From e1fb4ad3325352d6820722ee2966b9bfd4a3f712 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 12 Sep 2013 13:20:17 +0000 Subject: [PATCH] re PR tree-optimization/58404 (&noninvariant_address not forwproped into ->handled_component) 2013-09-12 Richard Biener PR tree-optimization/58404 * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also propagate non-invariant addresses into dereferences wrapped in component references. * g++.dg/tree-ssa/pr58404.C: New testcase. From-SVN: r202525 --- gcc/ChangeLog | 7 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/tree-ssa/pr58404.C | 20 +++++++++++ gcc/tree-ssa-forwprop.c | 46 ++++++++++++++----------- 4 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr58404.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec525e50ea7..7a0d375fc33 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-09-12 Richard Biener + + PR tree-optimization/58404 + * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also + propagate non-invariant addresses into dereferences wrapped + in component references. + 2013-09-12 Richard Biener PR tree-optimization/58402 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 576d56d0873..75110d9021d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-09-12 Richard Biener + + PR tree-optimization/58404 + * g++.dg/tree-ssa/pr58404.C: New testcase. + 2013-09-12 Martin Jambor PR ipa/58371 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr58404.C b/gcc/testsuite/g++.dg/tree-ssa/pr58404.C new file mode 100644 index 00000000000..aa8fb796c6f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr58404.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-O -fdump-tree-cddce1" } + +struct S { int s; }; +S a[1024]; + +void +foo () +{ + for (int i = 0; i < 1024; i++) + { + S &r = a[i]; + r.s++; + } +} + +// We should propagate the reference into both memory accesses +// during the first forwprop pass +// { dg-final { scan-tree-dump-times "= &a" 0 "cddce1" } } +// { dg-final { cleanup-tree-dump "cddce1" } } diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 977aebdff51..f1a407774fb 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -786,9 +786,10 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. ADDR_EXPR will not appear on the LHS. */ - lhs = gimple_assign_lhs (use_stmt); - while (handled_component_p (lhs)) - lhs = TREE_OPERAND (lhs, 0); + tree *lhsp = gimple_assign_lhs_ptr (use_stmt); + while (handled_component_p (*lhsp)) + lhsp = &TREE_OPERAND (*lhsp, 0); + lhs = *lhsp; /* Now see if the LHS node is a MEM_REF using NAME. If so, propagate the ADDR_EXPR into the use of NAME and fold the result. */ @@ -822,11 +823,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* If the LHS is a plain dereference and the value type is the same as that of the pointed-to type of the address we can put the dereferenced address on the LHS preserving the original alias-type. */ - else if (gimple_assign_lhs (use_stmt) == lhs - && integer_zerop (TREE_OPERAND (lhs, 1)) - && useless_type_conversion_p - (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), - TREE_TYPE (gimple_assign_rhs1 (use_stmt))) + else if (integer_zerop (TREE_OPERAND (lhs, 1)) + && ((gimple_assign_lhs (use_stmt) == lhs + && useless_type_conversion_p + (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), + TREE_TYPE (gimple_assign_rhs1 (use_stmt)))) + || types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) /* Don't forward anything into clobber stmts if it would result in the lhs no longer being a MEM_REF. */ && (!gimple_clobber_p (use_stmt) @@ -854,7 +857,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs); TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs); new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0)); - gimple_assign_set_lhs (use_stmt, new_lhs); + *lhsp = new_lhs; TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs); TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs); *def_rhs_basep = saved; @@ -873,11 +876,12 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR nodes from the RHS. */ - rhs = gimple_assign_rhs1 (use_stmt); - if (TREE_CODE (rhs) == ADDR_EXPR) - rhs = TREE_OPERAND (rhs, 0); - while (handled_component_p (rhs)) - rhs = TREE_OPERAND (rhs, 0); + tree *rhsp = gimple_assign_rhs1_ptr (use_stmt); + if (TREE_CODE (*rhsp) == ADDR_EXPR) + rhsp = &TREE_OPERAND (*rhsp, 0); + while (handled_component_p (*rhsp)) + rhsp = &TREE_OPERAND (*rhsp, 0); + rhs = *rhsp; /* Now see if the RHS node is a MEM_REF using NAME. If so, propagate the ADDR_EXPR into the use of NAME and fold the result. */ @@ -909,11 +913,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* If the RHS is a plain dereference and the value type is the same as that of the pointed-to type of the address we can put the dereferenced address on the RHS preserving the original alias-type. */ - else if (gimple_assign_rhs1 (use_stmt) == rhs - && integer_zerop (TREE_OPERAND (rhs, 1)) - && useless_type_conversion_p - (TREE_TYPE (gimple_assign_lhs (use_stmt)), - TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) + else if (integer_zerop (TREE_OPERAND (rhs, 1)) + && ((gimple_assign_rhs1 (use_stmt) == rhs + && useless_type_conversion_p + (TREE_TYPE (gimple_assign_lhs (use_stmt)), + TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) + || types_compatible_p (TREE_TYPE (rhs), + TREE_TYPE (TREE_OPERAND (def_rhs, 0))))) { tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0); tree new_offset, new_base, saved, new_rhs; @@ -937,7 +943,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs); TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs); new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0)); - gimple_assign_set_rhs1 (use_stmt, new_rhs); + *rhsp = new_rhs; TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs); TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs); *def_rhs_basep = saved;