diff options
author | Richard Biener <rguenther@suse.de> | 2013-09-12 13:20:17 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-09-12 13:20:17 +0000 |
commit | e1fb4ad3325352d6820722ee2966b9bfd4a3f712 (patch) | |
tree | f71e1f5d4b41a5d90459e260266a7cec947e9d59 /gcc | |
parent | 154c91887b3709c1a2c2407d1dcb2000d3e9b4a7 (diff) | |
download | gcc-e1fb4ad3325352d6820722ee2966b9bfd4a3f712.zip gcc-e1fb4ad3325352d6820722ee2966b9bfd4a3f712.tar.gz gcc-e1fb4ad3325352d6820722ee2966b9bfd4a3f712.tar.bz2 |
re PR tree-optimization/58404 (&noninvariant_address not forwproped into ->handled_component)
2013-09-12 Richard Biener <rguenther@suse.de>
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr58404.C | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 46 |
4 files changed, 58 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec525e5..7a0d375 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2013-09-12 Richard Biener <rguenther@suse.de> + 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 <rguenther@suse.de> + PR tree-optimization/58402 * passes.def: Move pass_late_warn_uninitialized later. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 576d56d..75110d9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-09-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58404 + * g++.dg/tree-ssa/pr58404.C: New testcase. + 2013-09-12 Martin Jambor <mjambor@suse.cz> 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 0000000..aa8fb79 --- /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 977aebd..f1a4077 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; |