diff options
author | Jan Hubicka <jh@suse.cz> | 2012-10-23 11:57:36 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2012-10-23 09:57:36 +0000 |
commit | 1a7de2015dfb81f40015a95be98abe50ad7382f0 (patch) | |
tree | dff1e819fae3b996fcd725e178165e8cf066a614 /gcc/tree-ssa-loop-ivcanon.c | |
parent | e8028ecdd02be651ec23cfdbc7e31c5b4b198ce1 (diff) | |
download | gcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.zip gcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.tar.gz gcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.tar.bz2 |
re PR tree-optimization/54967 (ICE in check_loop_closed_ssa_use, at tree-ssa-loop-manip.c:55)
PR middle-end/54967
* cfgloopmanip.c (fix_bb_placements): Add loop_closed_ssa_invalidated;
track basic blocks that moved out of their loops.
(unloop): Likewise.
(remove_path): Update.
(fix_loop_placements): Update.
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Add
loop_closed_ssa_invalidated parameter; pass it around.
(canonicalize_loop_induction_variables): Update loop closed
SSA form if needed.
(tree_unroll_loops_completely): Likewise; do irred update out of
the outer loop; verify that SSA form is closed.
* cfgloop.h (unrloop): Update.
* gfortran.dg/pr54967.f90: New testcase.
From-SVN: r192709
Diffstat (limited to 'gcc/tree-ssa-loop-ivcanon.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 81bf09e..323045f 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -390,13 +390,16 @@ loop_edge_to_cancel (struct loop *loop) EXIT is the exit of the loop that should be eliminated. IRRED_INVALIDATED is used to bookkeep if information about irreducible regions may become invalid as a result - of the transformation. */ + of the transformation. + LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case + when we need to go into loop closed SSA form. */ static bool try_unroll_loop_completely (struct loop *loop, edge exit, tree niter, enum unroll_level ul, - bool *irred_invalidated) + bool *irred_invalidated, + bitmap loop_closed_ssa_invalidated) { unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns; gimple cond; @@ -562,7 +565,7 @@ try_unroll_loop_completely (struct loop *loop, locus = latch_edge->goto_locus; /* Unloop destroys the latch edge. */ - unloop (loop, irred_invalidated); + unloop (loop, irred_invalidated, loop_closed_ssa_invalidated); /* Create new basic block for the latch edge destination and wire it in. */ @@ -615,7 +618,8 @@ static bool canonicalize_loop_induction_variables (struct loop *loop, bool create_iv, enum unroll_level ul, bool try_eval, - bool *irred_invalidated) + bool *irred_invalidated, + bitmap loop_closed_ssa_invalidated) { edge exit = NULL; tree niter; @@ -663,7 +667,8 @@ canonicalize_loop_induction_variables (struct loop *loop, (int)max_loop_iterations_int (loop)); } - if (try_unroll_loop_completely (loop, exit, niter, ul, irred_invalidated)) + if (try_unroll_loop_completely (loop, exit, niter, ul, irred_invalidated, + loop_closed_ssa_invalidated)) return true; if (create_iv @@ -683,13 +688,15 @@ canonicalize_induction_variables (void) struct loop *loop; bool changed = false; bool irred_invalidated = false; + bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL); FOR_EACH_LOOP (li, loop, 0) { changed |= canonicalize_loop_induction_variables (loop, true, UL_SINGLE_ITER, true, - &irred_invalidated); + &irred_invalidated, + loop_closed_ssa_invalidated); } gcc_assert (!need_ssa_update_p (cfun)); @@ -701,6 +708,13 @@ canonicalize_induction_variables (void) evaluation could reveal new information. */ scev_reset (); + if (!bitmap_empty_p (loop_closed_ssa_invalidated)) + { + gcc_checking_assert (loops_state_satisfies_p (LOOP_CLOSED_SSA)); + rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); + } + BITMAP_FREE (loop_closed_ssa_invalidated); + if (changed) return TODO_cleanup_cfg; return 0; @@ -794,11 +808,15 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) bool changed; enum unroll_level ul; int iteration = 0; + bool irred_invalidated = false; do { - bool irred_invalidated = false; changed = false; + bitmap loop_closed_ssa_invalidated = NULL; + + if (loops_state_satisfies_p (LOOP_CLOSED_SSA)) + loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL); FOR_EACH_LOOP (li, loop, 0) { @@ -812,9 +830,9 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) else ul = UL_NO_GROWTH; - if (canonicalize_loop_induction_variables (loop, false, ul, - !flag_tree_loop_ivcanon, - &irred_invalidated)) + if (canonicalize_loop_induction_variables + (loop, false, ul, !flag_tree_loop_ivcanon, + &irred_invalidated, loop_closed_ssa_invalidated)) { changed = true; /* If we'll continue unrolling, we need to propagate constants @@ -834,11 +852,14 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) struct loop **iter; unsigned i; - if (irred_invalidated - && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) - mark_irreducible_loops (); + /* We can not use TODO_update_ssa_no_phi because VOPS gets confused. */ - update_ssa (TODO_update_ssa); + if (loop_closed_ssa_invalidated + && !bitmap_empty_p (loop_closed_ssa_invalidated)) + rewrite_into_loop_closed_ssa (loop_closed_ssa_invalidated, + TODO_update_ssa); + else + update_ssa (TODO_update_ssa); /* Propagate the constants within the new basic blocks. */ FOR_EACH_VEC_ELT (loop_p, father_stack, i, iter) @@ -861,12 +882,22 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) /* Clean up the information about numbers of iterations, since complete unrolling might have invalidated it. */ scev_reset (); +#ifdef ENABLE_CHECKING + if (loops_state_satisfies_p (LOOP_CLOSED_SSA)) + verify_loop_closed_ssa (true); +#endif } + if (loop_closed_ssa_invalidated) + BITMAP_FREE (loop_closed_ssa_invalidated); } while (changed && ++iteration <= PARAM_VALUE (PARAM_MAX_UNROLL_ITERATIONS)); VEC_free (loop_p, stack, father_stack); + if (irred_invalidated + && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) + mark_irreducible_loops (); + return 0; } |