re PR middle-end/41453 (use INTENT(out) for optimization)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 22 Sep 2018 18:44:01 +0000 (18:44 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 22 Sep 2018 18:44:01 +0000 (18:44 +0000)
2018-09-22  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/41453
* trans.h (gfc_conv_expr_reference): Add optional argument
add_clobber to prototype.
(gfc_conv_procedure_call):  Set add_clobber argument to
gfc_conv_procedure_reference to true for scalar, INTENT(OUT),
non-pointer, non-allocatable, non-dummy variables whose type
is neither BT_CHARACTER, BT_DERIVED or BT_CLASS, but only if
the procedure is not elemental.
* trans-expr.c (gfc_conv_procedure_reference): Add clobber
statement before call if add_clobber is set.

2018-09-22  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/41453
* gfortran.dg/intent_optimize_2.f90: New test.

From-SVN: r264506

gcc/fortran/ChangeLog
gcc/fortran/trans-expr.c
gcc/fortran/trans.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/intent_optimize_2.f90 [new file with mode: 0644]

index 14a1de1da9384f74ed71f5d0924fb7d8c5ea5f88..6a7f7f26720ca69ae00405f397f955ab67674284 100644 (file)
@@ -1,3 +1,16 @@
+2018-09-22  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/41453
+       * trans.h (gfc_conv_expr_reference): Add optional argument
+       add_clobber to prototype.
+       (gfc_conv_procedure_call):  Set add_clobber argument to
+       gfc_conv_procedure_reference to true for scalar, INTENT(OUT),
+       non-pointer, non-allocatable, non-dummy variables whose type
+       is neither BT_CHARACTER, BT_DERIVED or BT_CLASS, but only if
+       the procedure is not elemental.
+       * trans-expr.c (gfc_conv_procedure_reference): Add clobber
+       statement before call if add_clobber is set.
+
 2018-09-22  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/85603
index 1453828684bfb5885d3fda51c5cbd5935fdd3d23..ae86d59272de16a4c8f26ed953aa10d26cbc031e 100644 (file)
@@ -5276,8 +5276,17 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                        }
                    }
                  else
-                   gfc_conv_expr_reference (&parmse, e);
-
+                   {
+                     bool add_clobber;
+                     add_clobber = fsym && fsym->attr.intent == INTENT_OUT
+                       && !fsym->attr.allocatable && !fsym->attr.pointer
+                       && !e->symtree->n.sym->attr.pointer
+                       && !e->symtree->n.sym->attr.dummy  /* See PR 41453.  */
+                       && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
+                       && e->ts.type != BT_CLASS && !sym->attr.elemental;
+
+                     gfc_conv_expr_reference (&parmse, e, add_clobber);
+                   }
                  /* Catch base objects that are not variables.  */
                  if (e->ts.type == BT_CLASS
                        && e->expr_type != EXPR_VARIABLE
@@ -8060,7 +8069,7 @@ gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
    values only.  */
 
 void
-gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
+gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
 {
   gfc_ss *ss;
   tree var;
@@ -8100,6 +8109,16 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
          gfc_add_block_to_block (&se->pre, &se->post);
          se->expr = var;
        }
+      else if (add_clobber)
+       {
+         tree clobber;
+         tree var;
+         /* FIXME: This fails if var is passed by reference, see PR
+            41453.  */
+         var = expr->symtree->n.sym->backend_decl;
+         clobber = build_clobber (TREE_TYPE (var));
+         gfc_add_modify (&se->pre, var, clobber);
+       }
       return;
     }
 
index 1813882fe366bbc02c917984b86f3b36d945abfc..4f33a89eddc55f70eb242fd4e5d61de113680289 100644 (file)
@@ -485,7 +485,8 @@ tree gfc_build_compare_string (tree, tree, tree, tree, int, enum tree_code);
 void gfc_conv_expr (gfc_se * se, gfc_expr * expr);
 void gfc_conv_expr_val (gfc_se * se, gfc_expr * expr);
 void gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr);
-void gfc_conv_expr_reference (gfc_se * se, gfc_expr *);
+void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr,
+                             bool add_clobber = false);
 void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);
 
 
index 7afec4f4fa35bd2a14211ba47861233de38353a8..d26e494c6dddd75df9e3e3bbf45a55e61f26fc0d 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-22  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/41453
+       * gfortran.dg/intent_optimize_2.f90: New test.
+
 2018-09-22  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/87318
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_2.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_2.f90
new file mode 100644 (file)
index 0000000..47632bb
--- /dev/null
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! { dg-options "-O -fno-inline -fdump-tree-optimized -fdump-tree-original" }
+! PR fortran/41453
+! Check that there is one clobber in the *.original tree, plus that
+! the constant 123456789 has been removed due to the INTENT(OUT).
+
+module x
+implicit none
+contains
+  subroutine foo(a)
+    integer, intent(out) :: a
+    a = 42
+  end subroutine foo
+end module x
+
+program main
+  use x
+  implicit none
+  integer :: a
+  a = 123456789
+  call foo(a)
+  print *,a
+end program main
+
+! { dg-final { scan-tree-dump-times "123456789" 0 "optimized" } }
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }