aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2018-09-22 18:44:01 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2018-09-22 18:44:01 +0000
commit056e6860b3a3f915b499a9e7be48f49da2c04850 (patch)
treeefba4c14d83c1c69cafcbf03c2c2db4ab500a286
parent73a958c67e3c99e10724dc65c4cb738da6188e34 (diff)
downloadgcc-056e6860b3a3f915b499a9e7be48f49da2c04850.zip
gcc-056e6860b3a3f915b499a9e7be48f49da2c04850.tar.gz
gcc-056e6860b3a3f915b499a9e7be48f49da2c04850.tar.bz2
re PR middle-end/41453 (use INTENT(out) for optimization)
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
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/trans-expr.c25
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_2.f9026
5 files changed, 68 insertions, 4 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 14a1de1..6a7f7f2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 1453828..ae86d59 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -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;
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 1813882..4f33a89 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7afec4f..d26e494 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..47632bb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_2.f90
@@ -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" } }