diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-09-22 18:44:01 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-09-22 18:44:01 +0000 |
commit | 056e6860b3a3f915b499a9e7be48f49da2c04850 (patch) | |
tree | efba4c14d83c1c69cafcbf03c2c2db4ab500a286 | |
parent | 73a958c67e3c99e10724dc65c4cb738da6188e34 (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 25 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/intent_optimize_2.f90 | 26 |
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" } } |