Introduce -finline-arg-packing.
authorThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 20 Dec 2019 11:51:05 +0000 (11:51 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 20 Dec 2019 11:51:05 +0000 (11:51 +0000)
2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR middle-end/91512
    PR fortran/92738
    * invoke.texi: Document -finline-arg-packing.
    * lang.opt: Add -finline-arg-packing.
    * options.c (gfc_post_options): Handle -finline-arg-packing.
    * trans-array.c (gfc_conv_array_parameter): Use
    flag_inline_arg_packing instead of checking for optimize and
    optimize_size.

2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR middle-end/91512
    PR fortran/92738
    * gfortran.dg/inline_pack_25.f90: New test.

From-SVN: r279639

gcc/fortran/ChangeLog
gcc/fortran/invoke.texi
gcc/fortran/lang.opt
gcc/fortran/options.c
gcc/fortran/trans-array.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/internal_pack_25.f90 [new file with mode: 0644]

index 8d480c5..f1c71ba 100644 (file)
@@ -1,3 +1,9 @@
+2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR middle-end/91512
+       PR fortran/92738
+       * gfortran.dg/inline_pack_25.f90: New test.
+
 2019-12-20  Tobias Burnus  <tobias@codesourcery.com>
 
        PR fortran/92996
index 0bc054f..299fc9f 100644 (file)
@@ -192,8 +192,9 @@ and warnings}.
 -ffrontend-loop-interchange -ffrontend-optimize @gol
 -finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero @gol
 -finit-derived -finit-logical=@var{<true|false>} @gol
--finit-real=@var{<zero|inf|-inf|nan|snan>} @gol
--finline-matmul-limit=@var{n} -fmax-array-constructor=@var{n} @gol
+-finit-real=@var{<zero|inf|-inf|nan|snan>}
+-finline-matmul-limit=@var{n} @gol
+-finline-arg-packing -fmax-array-constructor=@var{n} @gol
 -fmax-stack-var-size=@var{n} -fno-align-commons -fno-automatic @gol
 -fno-protect-parens -fno-underscoring -fsecond-underscore @gol
 -fpack-derived -frealloc-lhs -frecursive -frepack-arrays @gol
@@ -1779,6 +1780,34 @@ compiled with the @option{-fshort-enums} option.  It will make
 GNU Fortran choose the smallest @code{INTEGER} kind a given
 enumerator set will fit in, and give all its enumerators this kind.
 
+@item -finline-arg-packing
+@opindex @code{finline-arg-packing}
+When passing an assumed-shape argument of a procedure as actual
+argument to an assumed-size or explicit size or as argument to a
+procedure that does not have an explicit interface, the argument may
+have to be packed, that is put into contiguous memory. An example is
+the call to @code{foo} in
+@smallexample
+  subroutine foo(a)
+     real, dimension(*) :: a
+  end subroutine foo
+  subroutine bar(b)
+     real, dimension(:) :: b
+     call foo(b)
+  end subroutine bar
+@end smallexample
+
+When @option{-finline-arg-packing} is in effect, this packing will be
+performed by inline code. This allows for more optimization while
+increasing code size.
+
+@option{-finline-arg-packing} is implied by any of the @option{-O} options
+except when optimizing for size via @option{-Os}.  If the code
+contains a very large number of argument that have to be packed, code
+size and also compilation time may become excessive.  If that is the
+case, it may be better to disable this option.  Instances of packing
+can be found by using by using @option{-Warray-temporaries}.
+
 @item -fexternal-blas
 @opindex @code{fexternal-blas}
 This option will make @command{gfortran} generate calls to BLAS functions
index 5fcd1ff..38c8891 100644 (file)
@@ -647,6 +647,10 @@ Enum(gfc_init_local_real) String(inf) Value(GFC_INIT_REAL_INF)
 EnumValue
 Enum(gfc_init_local_real) String(-inf) Value(GFC_INIT_REAL_NEG_INF)
 
+finline-arg-packing
+Fortran  Var(flag_inline_arg_packing) Init(-1)
+-finline-arg-packing   Perform argument packing inline
+
 finline-matmul-limit=
 Fortran RejectNegative Joined UInteger Var(flag_inline_matmul_limit) Init(-1)
 -finline-matmul-limit=<n>      Specify the size of the largest matrix for which matmul will be inlined.
index f7a5299..19e68d5 100644 (file)
@@ -467,6 +467,11 @@ gfc_post_options (const char **pfilename)
   if (flag_frontend_loop_interchange == -1)
     flag_frontend_loop_interchange = optimize;
 
+  /* Do inline packing by default if optimizing, but not if
+     optimizing for size.  */
+  if (flag_inline_arg_packing == -1)
+    flag_inline_arg_packing = optimize && !optimize_size;
+
   if (flag_max_array_constructor < 65535)
     flag_max_array_constructor = 65535;
 
index e879ea1..226fc3a 100644 (file)
@@ -8139,7 +8139,7 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77,
         making the packing and unpacking operation visible to the
         optimizers.  */
 
-      if (g77 && optimize && !optimize_size && expr->expr_type == EXPR_VARIABLE
+      if (g77 && flag_inline_arg_packing && expr->expr_type == EXPR_VARIABLE
          && !is_pointer (expr) && ! gfc_has_dimen_vector_ref (expr)
          && !(expr->symtree->n.sym->as
               && expr->symtree->n.sym->as->type == AS_ASSUMED_RANK)
index d5bd666..957f62a 100644 (file)
@@ -1,3 +1,14 @@
+2019-12-20  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR middle-end/91512
+       PR fortran/92738
+       * invoke.texi: Document -finline-arg-packing.
+       * lang.opt: Add -finline-arg-packing.
+       * options.c (gfc_post_options): Handle -finline-arg-packing.
+       * trans-array.c (gfc_conv_array_parameter): Use
+       flag_inline_arg_packing instead of checking for optimize and
+       optimize_size.
+
 2019-12-20  Tobias Burnus  <tobias@codesourcery.com>
 
        PR fortran/92996
diff --git a/gcc/testsuite/gfortran.dg/internal_pack_25.f90 b/gcc/testsuite/gfortran.dg/internal_pack_25.f90
new file mode 100644 (file)
index 0000000..ac9f7e9
--- /dev/null
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-fno-inline-arg-packing -O -fdump-tree-original" }
+! PR fortran/92738, middle-end/91512
+! Check that -fno-inline-pack does indeed suppress inline packing.
+module x
+  implicit none
+contains
+  subroutine foo(x)
+    real, dimension(:), intent(inout) :: x
+    call bar (x, size(x))
+  end subroutine foo
+  subroutine bar (x, n)
+    integer, intent(in) :: n
+    real, dimension(n) :: x
+    x = -x
+  end subroutine bar
+end module x
+! { dg-final { scan-tree-dump-times "_gfortran_internal_pack" 1 "original" } }
+! { dg-final { scan-tree-dump-times "_gfortran_internal_unpack" 1 "original" } }