aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-09-12 13:20:17 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-09-12 13:20:17 +0000
commite1fb4ad3325352d6820722ee2966b9bfd4a3f712 (patch)
treef71e1f5d4b41a5d90459e260266a7cec947e9d59
parent154c91887b3709c1a2c2407d1dcb2000d3e9b4a7 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr58404.C20
-rw-r--r--gcc/tree-ssa-forwprop.c46
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;