re PR fortran/48448 (Implement -f(no-)frontend-optimization)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 8 Apr 2011 21:46:08 +0000 (21:46 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 8 Apr 2011 21:46:08 +0000 (21:46 +0000)
2011-04-08  Thomas Koenig  <tkoenig@gcc.gnu.org>

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-08  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/48448
* gfortran.dg/function_optimize_5.f90:  New test.

From-SVN: r172215

gcc/fortran/ChangeLog
gcc/fortran/frontend-passes.c
gcc/fortran/gfortran.h
gcc/fortran/invoke.texi
gcc/fortran/lang.opt
gcc/fortran/options.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/function_optimize_5.f90 [new file with mode: 0644]

index c6cf7ff7208147e3cdd44f72ea975bc6caabe2de..0a4872c55c0f393841c2c0ea8a7d95290548204f 100644 (file)
@@ -1,3 +1,24 @@
+2011-04-08  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       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-06  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/18918
index b6f6b4cd02015fb3c76a3d321690617c0376b4df..cabfd28558650953e5a08dee9d1218a7afe6ed0f 100644 (file)
@@ -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 495923a2466aa804e3dffcf6ccddcc93e55f5bf5..73c39669c4ca3bc8e42c7a9e5193fde6130bbdf1 100644 (file)
@@ -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 5441dbcc121869c403df58010e84a62365e1d747..96beff58215bb9dfb5b434fb12d945d7d6403207 100644 (file)
@@ -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{<zero|inf|-inf|nan|snan>} @gol
 -finit-logical=@var{<true|false>} -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 occasion of variables being
 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 optimizations
+enabled by the @option{-ffrontend-optimize} option.
+
+
 @item -Werror
 @opindex @code{Werror}
 @cindex warnings, to errors
@@ -1482,8 +1491,19 @@ statements, regardless of whether these functions are marked
 @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 manipulating
+parts the Fortran parse tree.  Enabled by default by any @option{-O}
+option.  Optimizations enabled by this option include elimination of
+identical function calls within expressions, removing unnecessary
+calls to @code{TRIM} in comparisons and assignments and replacing
+@code{TRIM(a)} with @code{a(1:LEN_TRIM(a))}. 
+It can be deselected by specifying @option{-fno-frontend-optimize}.
 @end table
 
 @xref{Code Gen Options,,Options for Code Generation Conventions,
index 9de70aca04a5f184617cad2a114371a8d7eace04..adc6dce6d1e4e8f50ff900348f324500c5d5b251 100644 (file)
@@ -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-<n> 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 cb14c3ad2961408d41b28825ae6e97071f44a663..008346056a74aa9bf5a0adf7b3c6ea77d845f0eb 100644 (file)
@@ -99,6 +99,7 @@ gfc_init_options (unsigned int decoded_options_count,
   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_count,
   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, int value,
       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, int value,
       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;
index 23f95b16e40a907410fbaa978a716c491983f829..4ba7d150c6c589cca56f68c8b9ac39e313dab328 100644 (file)
@@ -1,3 +1,8 @@
+2011-04-08  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/48448
+       * gfortran.dg/function_optimize_5.f90:  New test.
+
 2011-04-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/aggr17.adb: New test.
diff --git a/gcc/testsuite/gfortran.dg/function_optimize_5.f90 b/gcc/testsuite/gfortran.dg/function_optimize_5.f90
new file mode 100644 (file)
index 0000000..427b126
--- /dev/null
@@ -0,0 +1,41 @@
+! { dg-do compile }
+! { dg-options "-ffrontend-optimize -Wfunction-elimination" }
+! 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