diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 29 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 2 |
4 files changed, 32 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c3d87ad6a0..74c12b44709 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-09-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/54498 + * tree-ssa-alias.h (get_continuation_for_phi): Add flag to + abort when reaching an already visited region. + * tree-ssa-alias.c (maybe_skip_until): Likewise. And do it. + (get_continuation_for_phi_1): Likewise. + (walk_non_aliased_vuses): When we translated the reference, + abort when we re-visit a region. + * tree-ssa-pre.c (translate_vuse_through_block): Adjust. + 2012-09-06 David Edelsohn <dje.gcc@gmail.com> * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): Add TLS diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 574f418447d..8d515703a77 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1929,7 +1929,8 @@ stmt_kills_ref_p (gimple stmt, tree ref) static bool maybe_skip_until (gimple phi, tree target, ao_ref *ref, - tree vuse, unsigned int *cnt, bitmap *visited) + tree vuse, unsigned int *cnt, bitmap *visited, + bool abort_on_visited) { basic_block bb = gimple_bb (phi); @@ -1947,8 +1948,9 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref, { /* An already visited PHI node ends the walk successfully. */ if (bitmap_bit_p (*visited, SSA_NAME_VERSION (PHI_RESULT (def_stmt)))) - return true; - vuse = get_continuation_for_phi (def_stmt, ref, cnt, visited); + return !abort_on_visited; + vuse = get_continuation_for_phi (def_stmt, ref, cnt, + visited, abort_on_visited); if (!vuse) return false; continue; @@ -1967,7 +1969,7 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref, if (gimple_bb (def_stmt) != bb) { if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (vuse))) - return true; + return !abort_on_visited; bb = gimple_bb (def_stmt); } vuse = gimple_vuse (def_stmt); @@ -1981,7 +1983,8 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref, static tree get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1, - ao_ref *ref, unsigned int *cnt, bitmap *visited) + ao_ref *ref, unsigned int *cnt, + bitmap *visited, bool abort_on_visited) { gimple def0 = SSA_NAME_DEF_STMT (arg0); gimple def1 = SSA_NAME_DEF_STMT (arg1); @@ -1994,14 +1997,16 @@ get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1, && dominated_by_p (CDI_DOMINATORS, gimple_bb (def1), gimple_bb (def0)))) { - if (maybe_skip_until (phi, arg0, ref, arg1, cnt, visited)) + if (maybe_skip_until (phi, arg0, ref, arg1, cnt, + visited, abort_on_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, cnt, visited)) + if (maybe_skip_until (phi, arg1, ref, arg0, cnt, + visited, abort_on_visited)) return arg1; } /* Special case of a diamond: @@ -2038,7 +2043,8 @@ get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1, tree get_continuation_for_phi (gimple phi, ao_ref *ref, - unsigned int *cnt, bitmap *visited) + unsigned int *cnt, bitmap *visited, + bool abort_on_visited) { unsigned nargs = gimple_phi_num_args (phi); @@ -2076,7 +2082,7 @@ get_continuation_for_phi (gimple phi, ao_ref *ref, { arg1 = PHI_ARG_DEF (phi, i); arg0 = get_continuation_for_phi_1 (phi, arg0, arg1, ref, - cnt, visited); + cnt, visited, abort_on_visited); if (!arg0) return NULL_TREE; } @@ -2113,6 +2119,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, bitmap visited = NULL; void *res; unsigned int cnt = 0; + bool translated = false; timevar_push (TV_ALIAS_STMT_WALK); @@ -2136,7 +2143,8 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, if (gimple_nop_p (def_stmt)) break; else if (gimple_code (def_stmt) == GIMPLE_PHI) - vuse = get_continuation_for_phi (def_stmt, ref, &cnt, &visited); + vuse = get_continuation_for_phi (def_stmt, ref, &cnt, + &visited, translated); else { cnt++; @@ -2155,6 +2163,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, else if (res != NULL) break; /* Translation succeeded, continue walking. */ + translated = true; } vuse = gimple_vuse (def_stmt); } diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index cdff3812181..6f38f20bce5 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -108,7 +108,7 @@ extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *); extern bool call_may_clobber_ref_p (gimple, tree); extern bool stmt_kills_ref_p (gimple, tree); extern tree get_continuation_for_phi (gimple, ao_ref *, - unsigned int *, bitmap *); + unsigned int *, bitmap *, bool); extern void *walk_non_aliased_vuses (ao_ref *, tree, void *(*)(ao_ref *, tree, unsigned int, void *), diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index bb1a03dfe99..e64d4f75a9b 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1291,7 +1291,7 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands, unsigned int cnt; /* Try to find a vuse that dominates this phi node by skipping non-clobbering statements. */ - vuse = get_continuation_for_phi (phi, &ref, &cnt, &visited); + vuse = get_continuation_for_phi (phi, &ref, &cnt, &visited, false); if (visited) BITMAP_FREE (visited); } |