[backport from gcc-4.7.2 r191031 ] gcc/ 2012-09-06 Richard Guenther 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. --- gcc-4.6.3/gcc/tree-ssa-alias.c.~1~ 2011-09-30 20:13:25.000000000 +0200 +++ gcc-4.6.3/gcc/tree-ssa-alias.c 2012-09-09 19:02:50.000000000 +0200 @@ -1713,7 +1713,7 @@ stmt_kills_ref_p (gimple stmt, tree ref) static bool maybe_skip_until (gimple phi, tree target, ao_ref *ref, - tree vuse, bitmap *visited) + tree vuse, bitmap *visited, bool abort_on_visited) { if (!*visited) *visited = BITMAP_ALLOC (NULL); @@ -1729,8 +1729,9 @@ maybe_skip_until (gimple phi, tree targe { /* 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, visited); + return !abort_on_visited; + vuse = get_continuation_for_phi (def_stmt, ref, + visited, abort_on_visited); if (!vuse) return false; continue; @@ -1751,7 +1752,8 @@ maybe_skip_until (gimple phi, tree targe be found. */ tree -get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited) +get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited, + bool abort_on_visited) { unsigned nargs = gimple_phi_num_args (phi); @@ -1776,14 +1778,14 @@ get_continuation_for_phi (gimple phi, ao && dominated_by_p (CDI_DOMINATORS, gimple_bb (def1), gimple_bb (def0)))) { - if (maybe_skip_until (phi, arg0, ref, arg1, visited)) + if (maybe_skip_until (phi, arg0, ref, arg1, 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, visited)) + if (maybe_skip_until (phi, arg1, ref, arg0, visited, abort_on_visited)) return arg1; } /* Special case of a diamond: @@ -1836,6 +1838,7 @@ walk_non_aliased_vuses (ao_ref *ref, tre { bitmap visited = NULL; void *res; + bool translated = false; timevar_push (TV_ALIAS_STMT_WALK); @@ -1852,7 +1855,7 @@ walk_non_aliased_vuses (ao_ref *ref, tre if (gimple_nop_p (def_stmt)) break; else if (gimple_code (def_stmt) == GIMPLE_PHI) - vuse = get_continuation_for_phi (def_stmt, ref, &visited); + vuse = get_continuation_for_phi (def_stmt, ref, &visited, translated); else { if (stmt_may_clobber_ref_p_1 (def_stmt, ref)) @@ -1870,6 +1873,7 @@ walk_non_aliased_vuses (ao_ref *ref, tre else if (res != NULL) break; /* Translation succeeded, continue walking. */ + translated = true; } vuse = gimple_vuse (def_stmt); } --- gcc-4.6.3/gcc/tree-ssa-alias.h.~1~ 2011-01-03 21:52:22.000000000 +0100 +++ gcc-4.6.3/gcc/tree-ssa-alias.h 2012-09-09 19:01:09.000000000 +0200 @@ -107,7 +107,7 @@ extern bool stmt_may_clobber_ref_p (gimp 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 *, bitmap *); +extern tree get_continuation_for_phi (gimple, ao_ref *, bitmap *, bool); extern void *walk_non_aliased_vuses (ao_ref *, tree, void *(*)(ao_ref *, tree, void *), void *(*)(ao_ref *, tree, void *), void *); --- gcc-4.6.3/gcc/tree-ssa-pre.c.~1~ 2012-01-03 15:46:03.000000000 +0100 +++ gcc-4.6.3/gcc/tree-ssa-pre.c 2012-09-09 19:01:09.000000000 +0200 @@ -1293,7 +1293,7 @@ translate_vuse_through_block (VEC (vn_re bitmap visited = NULL; /* Try to find a vuse that dominates this phi node by skipping non-clobbering statements. */ - vuse = get_continuation_for_phi (phi, &ref, &visited); + vuse = get_continuation_for_phi (phi, &ref, &visited, false); if (visited) BITMAP_FREE (visited); }