aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-11-23 09:05:11 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-11-23 09:05:11 +0000
commitd7a160a45ea7ed09247788c708721c2813cf0007 (patch)
treed8b5404eccbb222d1e6e5d2a067adec60e607835 /gcc/tree-ssa-sccvn.c
parentbb9ec14d414a51c3461510f3cddfcafe11b35ee1 (diff)
downloadgcc-d7a160a45ea7ed09247788c708721c2813cf0007.zip
gcc-d7a160a45ea7ed09247788c708721c2813cf0007.tar.gz
gcc-d7a160a45ea7ed09247788c708721c2813cf0007.tar.bz2
re PR tree-optimization/23094 (store ccp, or store copy prop misses an optimization)
2017-11-23 Richard Biener <rguenther@suse.de> PR tree-optimization/23094 * tree-ssa-sccvn.c (vuse_ssa_val): Handle VN_TOP when we come here from walking over backedges in the first iteration. (vn_reference_lookup_3): Skip clobbers that store the same value. * gcc.dg/tree-ssa/ssa-fre-61.c: New testcase. From-SVN: r255093
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index f5bc28e..d0ff301 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -345,7 +345,12 @@ vuse_ssa_val (tree x)
do
{
- x = SSA_VAL (x);
+ tree tem = SSA_VAL (x);
+ /* stmt walking can walk over a backedge and reach code we didn't
+ value-number yet. */
+ if (tem == VN_TOP)
+ return x;
+ x = tem;
}
while (SSA_NAME_IN_FREE_LIST (x));
@@ -1868,6 +1873,39 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
ao_ref_init (&lhs_ref, lhs);
lhs_ref_ok = true;
}
+
+ /* If we reach a clobbering statement try to skip it and see if
+ we find a VN result with exactly the same value as the
+ possible clobber. In this case we can ignore the clobber
+ and return the found value.
+ Note that we don't need to worry about partial overlapping
+ accesses as we then can use TBAA to disambiguate against the
+ clobbering statement when looking up a load (thus the
+ VN_WALKREWRITE guard). */
+ if (vn_walk_kind == VN_WALKREWRITE
+ && is_gimple_reg_type (TREE_TYPE (lhs))
+ && types_compatible_p (TREE_TYPE (lhs), vr->type))
+ {
+ tree *saved_last_vuse_ptr = last_vuse_ptr;
+ /* Do not update last_vuse_ptr in vn_reference_lookup_2. */
+ last_vuse_ptr = NULL;
+ tree saved_vuse = vr->vuse;
+ hashval_t saved_hashcode = vr->hashcode;
+ void *res = vn_reference_lookup_2 (ref,
+ gimple_vuse (def_stmt), 0, vr);
+ /* Need to restore vr->vuse and vr->hashcode. */
+ vr->vuse = saved_vuse;
+ vr->hashcode = saved_hashcode;
+ last_vuse_ptr = saved_last_vuse_ptr;
+ if (res && res != (void *)-1)
+ {
+ vn_reference_t vnresult = (vn_reference_t) res;
+ if (vnresult->result
+ && operand_equal_p (vnresult->result,
+ gimple_assign_rhs1 (def_stmt), 0))
+ return res;
+ }
+ }
}
else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
&& gimple_call_num_args (def_stmt) <= 4)