diff options
author | Richard Guenther <rguenther@suse.de> | 2011-10-11 11:57:23 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-10-11 11:57:23 +0000 |
commit | 45ce6084c2547d75f1cf5e1d8d12305aa85e02d8 (patch) | |
tree | edbad05931ac311508e282e377a4fb40d209d83b | |
parent | 12d31b36a87d5b49319bd32e218384ff2a6f0b28 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c | 26 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 111 |
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; |