aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-10-11 11:57:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-10-11 11:57:23 +0000
commit45ce6084c2547d75f1cf5e1d8d12305aa85e02d8 (patch)
treeedbad05931ac311508e282e377a4fb40d209d83b
parent12d31b36a87d5b49319bd32e218384ff2a6f0b28 (diff)
downloadgcc-45ce6084c2547d75f1cf5e1d8d12305aa85e02d8.zip
gcc-45ce6084c2547d75f1cf5e1d8d12305aa85e02d8.tar.gz
gcc-45ce6084c2547d75f1cf5e1d8d12305aa85e02d8.tar.bz2
re PR tree-optimization/50204 (Missed fully redundant load found in crafty (SPEC 2k))
2011-10-11 Richard Guenther <rguenther@suse.de> PR tree-optimization/50204 * tree-ssa-alias.c (get_continuation_for_phi_1): Split out two argument handling from ... (get_continuation_for_phi): ... here. Handle arbitrary number of PHI args. * gcc.dg/tree-ssa/ssa-fre-36.c: New testcase. From-SVN: r179799
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c26
-rw-r--r--gcc/tree-ssa-alias.c111
4 files changed, 107 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e83c515..8e42253 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-10-11 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/50204
+ * tree-ssa-alias.c (get_continuation_for_phi_1): Split out
+ two argument handling from ...
+ (get_continuation_for_phi): ... here. Handle arbitrary number
+ of PHI args.
+
2011-10-11 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/33067
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 48dcf8f..06a16b0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-10-11 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/50204
+ * gcc.dg/tree-ssa/ssa-fre-36.c: New testcase.
+
2011-10-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc.target/s390/20090223-1.c: Add -Wno-attributes.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c
new file mode 100644
index 0000000..a8a2dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+extern int opening;
+extern int middle_game;
+int s;
+extern int d[1];
+void PreEvaluate(int wtm)
+{
+ int i, j;
+ if (opening) {
+ d[0]=1;
+ }
+ else if (middle_game) {
+ d[0]=-1;
+ }
+ if (4 != opening) {
+ return;
+ }
+ s = 1;
+}
+
+/* We should be able to CSE the second load of opening. */
+
+/* { dg-final { scan-tree-dump "Replaced opening" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 506e778..c63b5a8 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1875,6 +1875,60 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref,
return true;
}
+/* For two PHI arguments ARG0 and ARG1 try to skip non-aliasing code
+ until we hit the phi argument definition that dominates the other one.
+ Return that, or NULL_TREE if there is no such definition. */
+
+static tree
+get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1,
+ ao_ref *ref, bitmap *visited)
+{
+ gimple def0 = SSA_NAME_DEF_STMT (arg0);
+ gimple def1 = SSA_NAME_DEF_STMT (arg1);
+ tree common_vuse;
+
+ if (arg0 == arg1)
+ return arg0;
+ else if (gimple_nop_p (def0)
+ || (!gimple_nop_p (def1)
+ && dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (def1), gimple_bb (def0))))
+ {
+ if (maybe_skip_until (phi, arg0, ref, arg1, visited))
+ return arg0;
+ }
+ else if (gimple_nop_p (def1)
+ || dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (def0), gimple_bb (def1)))
+ {
+ if (maybe_skip_until (phi, arg1, ref, arg0, visited))
+ return arg1;
+ }
+ /* Special case of a diamond:
+ MEM_1 = ...
+ goto (cond) ? L1 : L2
+ L1: store1 = ... #MEM_2 = vuse(MEM_1)
+ goto L3
+ L2: store2 = ... #MEM_3 = vuse(MEM_1)
+ L3: MEM_4 = PHI<MEM_2, MEM_3>
+ We were called with the PHI at L3, MEM_2 and MEM_3 don't
+ dominate each other, but still we can easily skip this PHI node
+ if we recognize that the vuse MEM operand is the same for both,
+ and that we can skip both statements (they don't clobber us).
+ This is still linear. Don't use maybe_skip_until, that might
+ potentially be slow. */
+ else if ((common_vuse = gimple_vuse (def0))
+ && common_vuse == gimple_vuse (def1))
+ {
+ if (!stmt_may_clobber_ref_p_1 (def0, ref)
+ && !stmt_may_clobber_ref_p_1 (def1, ref))
+ return common_vuse;
+ }
+
+ return NULL_TREE;
+}
+
+
/* Starting from a PHI node for the virtual operand of the memory reference
REF find a continuation virtual operand that allows to continue walking
statements dominating PHI skipping only statements that cannot possibly
@@ -1890,53 +1944,24 @@ get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited)
if (nargs == 1)
return PHI_ARG_DEF (phi, 0);
- /* For two arguments try to skip non-aliasing code until we hit
- the phi argument definition that dominates the other one. */
- if (nargs == 2)
+ /* For two or more arguments try to pairwise skip non-aliasing code
+ until we hit the phi argument definition that dominates the other one. */
+ else if (nargs >= 2)
{
tree arg0 = PHI_ARG_DEF (phi, 0);
- tree arg1 = PHI_ARG_DEF (phi, 1);
- gimple def0 = SSA_NAME_DEF_STMT (arg0);
- gimple def1 = SSA_NAME_DEF_STMT (arg1);
- tree common_vuse;
-
- if (arg0 == arg1)
- return arg0;
- else if (gimple_nop_p (def0)
- || (!gimple_nop_p (def1)
- && dominated_by_p (CDI_DOMINATORS,
- gimple_bb (def1), gimple_bb (def0))))
- {
- if (maybe_skip_until (phi, arg0, ref, arg1, visited))
- return arg0;
- }
- else if (gimple_nop_p (def1)
- || dominated_by_p (CDI_DOMINATORS,
- gimple_bb (def0), gimple_bb (def1)))
- {
- if (maybe_skip_until (phi, arg1, ref, arg0, visited))
- return arg1;
- }
- /* Special case of a diamond:
- MEM_1 = ...
- goto (cond) ? L1 : L2
- L1: store1 = ... #MEM_2 = vuse(MEM_1)
- goto L3
- L2: store2 = ... #MEM_3 = vuse(MEM_1)
- L3: MEM_4 = PHI<MEM_2, MEM_3>
- We were called with the PHI at L3, MEM_2 and MEM_3 don't
- dominate each other, but still we can easily skip this PHI node
- if we recognize that the vuse MEM operand is the same for both,
- and that we can skip both statements (they don't clobber us).
- This is still linear. Don't use maybe_skip_until, that might
- potentially be slow. */
- else if ((common_vuse = gimple_vuse (def0))
- && common_vuse == gimple_vuse (def1))
+ tree arg1;
+ unsigned i = 1;
+ do
{
- if (!stmt_may_clobber_ref_p_1 (def0, ref)
- && !stmt_may_clobber_ref_p_1 (def1, ref))
- return common_vuse;
+ arg1 = PHI_ARG_DEF (phi, i);
+ arg0 = get_continuation_for_phi_1 (phi, arg0, arg1, ref, visited);
+ if (!arg0)
+ return NULL_TREE;
+
}
+ while (++i < nargs);
+
+ return arg0;
}
return NULL_TREE;