diff options
author | Richard Guenther <rguenther@suse.de> | 2012-09-06 14:47:42 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-09-06 14:47:42 +0000 |
commit | 511c229c6caf013aaafca49535d4c82522d289e3 (patch) | |
tree | 115758a04c3bdab6ee264374fe7b3e672dd0650a /gcc/tree-ssa-alias.c | |
parent | 81a14f1e73f545848cdd03fc568390a419686044 (diff) | |
download | gcc-511c229c6caf013aaafca49535d4c82522d289e3.zip gcc-511c229c6caf013aaafca49535d4c82522d289e3.tar.gz gcc-511c229c6caf013aaafca49535d4c82522d289e3.tar.bz2 |
re PR tree-optimization/54498 (incorrect code generation from g++ -O)
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.
From-SVN: r191030
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 574f418..8d51570 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); } |