From patchwork Thu Apr 7 19:32:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 90226 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 03C8DB6F87 for ; Fri, 8 Apr 2011 05:33:11 +1000 (EST) Received: (qmail 21225 invoked by alias); 7 Apr 2011 19:33:09 -0000 Received: (qmail 21208 invoked by uid 22791); 7 Apr 2011 19:33:07 -0000 X-SWARE-Spam-Status: No, hits=-0.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, T_FRT_FREE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cc-smtpout1.netcologne.de (HELO cc-smtpout1.netcologne.de) (89.1.8.211) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 07 Apr 2011 19:33:00 +0000 Received: from cc-smtpin3.netcologne.de (cc-smtpin3.netcologne.de [89.1.8.203]) by cc-smtpout1.netcologne.de (Postfix) with ESMTP id 0F8DB1220B; Thu, 7 Apr 2011 21:32:58 +0200 (CEST) Received: from [192.168.0.197] (xdsl-78-35-129-22.netcologne.de [78.35.129.22]) by cc-smtpin3.netcologne.de (Postfix) with ESMTPSA id C5D8411E84; Thu, 7 Apr 2011 21:32:56 +0200 (CEST) Message-ID: <4D9E1168.50908@netcologne.de> Date: Thu, 07 Apr 2011 21:32:56 +0200 From: Thomas Koenig User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.14) Gecko/20110221 SUSE/3.1.8 Thunderbird/3.1.8 MIME-Version: 1.0 To: "fortran@gcc.gnu.org" , gcc-patches Subject: [patch, fortran] More control over front end optimization Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello world, following Joost's request, the attached patch gives the user more control over front end optimization - it can now be selected or deselected independent of normal optimization. I have also implemented a warning for eliminated functions. Regression-tested. Once this is in, I will also mention the new options in the changes file. OK for trunk? 2011-04-07 Thomas Koenig PR fortran/48448 * gfortran.h (gfc_option_t): Add warn_function_elimination and flag_frontend_optimize. * lang.opt (Wfunction-elimination): Add. (ffrontend-optimize): Add. * invoke.texi: Add documentation for -Wfunction-elimination and -ffrontend-optimize. Add -faggressive-function-elimination to list of code generation options. * frontend-passes.c (gfc_run_passes): Run optimizations if flag_frontend_optimize is set. (warn_function_elimination): New function. (cfe_expr_0): Call it if requested to do so. * options.c (gfc_init_options): Initiate warn_function_elimination and flag_frontend_optimize. (gfc_post_options): Set flag_frontend_optimize if not specified by user, depending on the optimization level. (gfc_handle_option): Handle -Wfunction-elimination and -ffrontend-optimize. 2011-04-07 Thomas Koenig PR fortran/48448 * gfortran.dg/function_optimize_5.f90: New test. ! { dg-do compile } ! { dg-options "-ffrontend-optimize -Wfunction-elimination" } ! PR 48448 ! Check the -ffrontend-optimize (in the absence of -O) and ! -Wfunction-elimination options. program main implicit none real, dimension(2,2) :: a, b, c, d integer :: i real :: x, z character(60) :: line real, external :: ext_func interface elemental function element(x) real, intent(in) :: x real :: elem end function element pure function mypure(x) real, intent(in) :: x integer :: mypure end function mypure elemental impure function elem_impure(x) real, intent(in) :: x real :: elem_impure end function elem_impure end interface data a /2., 3., 5., 7./ data b /11., 13., 17., 23./ write (unit=line, fmt='(4F7.2)') matmul(a,b) & ! { dg-warning "Removing call to function 'matmul'" } & + matmul(a,b) z = sin(x) + 2.0 + sin(x) ! { dg-warning "Removing call to function 'sin'" } print *,z x = ext_func(a) + 23 + ext_func(a) print *,d,x z = element(x) + element(x) ! { dg-warning "Removing call to function 'element'" } print *,z i = mypure(x) - mypure(x) ! { dg-warning "Removing call to function 'mypure'" } print *,i z = elem_impure(x) - elem_impure(x) print *,z end program main Index: gfortran.h =================================================================== --- gfortran.h (Revision 172058) +++ gfortran.h (Arbeitskopie) @@ -2180,6 +2180,7 @@ typedef struct int warn_ampersand; int gfc_warn_conversion; int warn_conversion_extra; + int warn_function_elimination; int warn_implicit_interface; int warn_implicit_procedure; int warn_line_truncation; @@ -2234,6 +2235,7 @@ typedef struct int flag_protect_parens; int flag_realloc_lhs; int flag_aggressive_function_elimination; + int flag_frontend_optimize; int fpe; int rtcheck; Index: lang.opt =================================================================== --- lang.opt (Revision 172058) +++ lang.opt (Arbeitskopie) @@ -222,6 +222,10 @@ Wconversion-extra Fortran Warning Warn about most implicit conversions +Wfunction-elimination +Fortran Warning +Warn about function call elimination + Wimplicit-interface Fortran Warning Warn about calls with implicit interface @@ -414,6 +418,10 @@ ffree-line-length- Fortran RejectNegative Joined UInteger -ffree-line-length- Use n as character line width in free mode +ffrontend-optimize +Fortran +Enable front end optimization + fimplicit-none Fortran Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements Index: invoke.texi =================================================================== --- invoke.texi (Revision 172058) +++ invoke.texi (Arbeitskopie) @@ -139,7 +139,7 @@ and warnings}. -Wall -Waliasing -Wampersand -Warray-bounds -Wcharacter-truncation @gol -Wconversion -Wimplicit-interface -Wimplicit-procedure -Wline-truncation @gol -Wintrinsics-std -Wsurprising -Wno-tabs -Wunderflow -Wunused-parameter @gol --Wintrinsic-shadow -Wno-align-commons} +-Wintrinsic-shadow -Wno-align-commons -Wfunction-elimination} @item Debugging Options @xref{Debugging Options,,Options for debugging your program or GNU Fortran}. @@ -171,7 +171,8 @@ and warnings}. -fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol -finit-integer=@var{n} -finit-real=@var{} @gol -finit-logical=@var{} -finit-character=@var{n} @gol --fno-align-commons -fno-protect-parens -frealloc-lhs} +-fno-align-commons -fno-protect-parens -frealloc-lhs @gol +-faggressive-function-elimination -ffrontend-optimize} @end table @menu @@ -859,6 +860,14 @@ By default, @command{gfortran} warns about any occ padded for proper alignment inside a @code{COMMON} block. This warning can be turned off via @option{-Wno-align-commons}. See also @option{-falign-commons}. +@item -Wfunction-elimination +@opindex @code{Wfunction-elimination} +@cindex function elimination +@cindex warnings, function elimination +Warn if any calls to functions are eliminated by the +@option{-ffrontend-optimize} option. + + @item -Werror @opindex @code{Werror} @cindex warnings, to errors @@ -1482,8 +1491,15 @@ statements, regardless of whether these functions @smallexample a = f(b,c) + f(b,c) @end smallexample -there will only be a single call to @code{f}. +there will only be a single call to @code{f}. This option only works +if @option{-ffrontend-optimize} is in effect. +@item -ffrontend-optimize +@opindex @code{frontend-optimize} +@cindex Front-end optimization +This option performs front-end optimization, based on the Fortran parse +tree. Enabled by default by any @option{-O} option. It can +be deselcted by specifying @option{-fno-frontend-optimize}. @end table @xref{Code Gen Options,,Options for Code Generation Conventions, Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 172058) +++ frontend-passes.c (Arbeitskopie) @@ -62,7 +62,7 @@ gfc_namespace *current_ns; void gfc_run_passes (gfc_namespace *ns) { - if (optimize) + if (gfc_option.flag_frontend_optimize) { expr_size = 20; expr_array = XNEWVEC(gfc_expr **, expr_size); @@ -283,6 +283,20 @@ create_var (gfc_expr * e) return result; } +/* Warn about function elimination. */ + +static void +warn_function_elimination (gfc_expr *e) +{ + if (e->expr_type != EXPR_FUNCTION) + return; + if (e->value.function.esym) + gfc_warning ("Removing call to function '%s' at %L", + e->value.function.esym->name, &(e->where)); + else if (e->value.function.isym) + gfc_warning ("Removing call to function '%s' at %L", + e->value.function.isym->name, &(e->where)); +} /* Callback function for the code walker for doing common function elimination. This builds up the list of functions in the expression and goes through them to detect duplicates, which it then replaces @@ -315,6 +329,10 @@ cfe_expr_0 (gfc_expr **e, int *walk_subtrees, { if (newvar == NULL) newvar = create_var (*(expr_array[i])); + + if (gfc_option.warn_function_elimination) + warn_function_elimination (*(expr_array[j])); + gfc_free (*(expr_array[j])); *(expr_array[j]) = gfc_copy_expr (newvar); } Index: options.c =================================================================== --- options.c (Revision 172058) +++ options.c (Arbeitskopie) @@ -99,6 +99,7 @@ gfc_init_options (unsigned int decoded_options_cou gfc_option.warn_array_temp = 0; gfc_option.gfc_warn_conversion = 0; gfc_option.warn_conversion_extra = 0; + gfc_option.warn_function_elimination = 0; gfc_option.warn_implicit_interface = 0; gfc_option.warn_line_truncation = 0; gfc_option.warn_surprising = 0; @@ -151,6 +152,7 @@ gfc_init_options (unsigned int decoded_options_cou gfc_option.flag_protect_parens = 1; gfc_option.flag_realloc_lhs = -1; gfc_option.flag_aggressive_function_elimination = 0; + gfc_option.flag_frontend_optimize = -1; gfc_option.fpe = 0; gfc_option.rtcheck = 0; @@ -418,6 +420,12 @@ gfc_post_options (const char **pfilename) if (pedantic && gfc_option.flag_whole_file) gfc_option.flag_whole_file = 2; + /* Optimization implies front end optimization, unless the user + specified it directly. */ + + if (gfc_option.flag_frontend_optimize == -1) + gfc_option.flag_frontend_optimize = optimize; + gfc_cpp_post_options (); /* FIXME: return gfc_cpp_preprocess_only (); @@ -610,6 +618,10 @@ gfc_handle_option (size_t scode, const char *arg, gfc_option.warn_conversion_extra = value; break; + case OPT_Wfunction_elimination: + gfc_option.warn_function_elimination = value; + break; + case OPT_Wimplicit_interface: gfc_option.warn_implicit_interface = value; break; @@ -979,6 +991,10 @@ gfc_handle_option (size_t scode, const char *arg, gfc_option.flag_aggressive_function_elimination = value; break; + case OPT_ffrontend_optimize: + gfc_option.flag_frontend_optimize = value; + break; + case OPT_fprotect_parens: gfc_option.flag_protect_parens = value; break;