extern class loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
tree *, tree *, class loop *);
extern void unloop (class loop *, bool *, bitmap);
+extern void unloop_loops (vec<class loop *> &loops_to_unloop,
+ vec<int> &loops_to_unloop_nunroll,
+ bitmap loop_closed_ssa_invalidated,
+ bool *irred_invalidated);
extern void copy_loop_info (class loop *loop, class loop *target);
extern class loop * duplicate_loop (class loop *, class loop *,
class loop * = NULL);
auto_vec<loop_p> candidates;
auto_vec<std::pair<edge, loop_p> > copied;
+ auto_vec<class loop *> loops_to_unloop;
+ auto_vec<int> loops_to_unloop_nunroll;
mark_dfs_back_edges ();
gimple_ranger *ranger = new gimple_ranger;
"Analyzing loop %i\n", loop->num);
header = loop->header;
+ if (!get_max_loop_iterations_int (loop))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Loop %d never loops.\n", loop->num);
+ loops_to_unloop.safe_push (loop);
+ loops_to_unloop_nunroll.safe_push (0);
+ continue;
+ }
/* If the loop is already a do-while style one (either because it was
written as such, or because jump threading transformed it into one),
/* We possibly decreased number of itrations by 1. */
auto_vec<edge> exits = get_loop_exit_edges (loop);
bool precise = (nexits == (int) exits.length ());
- if (!get_max_loop_iterations_int (loop))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Loop %d no longer loops.\n", loop->num);
- /* TODO: We can unloop like in tree-ssa-loop-ivcanon. */
- precise = false;
- }
/* Check that loop may not terminate in other way than via
basic blocks we duplicated. */
if (precise)
precise = false;
}
}
- if (precise)
+ if (precise
+ && get_max_loop_iterations_int (loop) == 1)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Loop %d no longer loops.\n", loop->num);
+ loops_to_unloop.safe_push (loop);
+ loops_to_unloop_nunroll.safe_push (0);
+ }
+ else if (precise)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
BITMAP_FREE (exit_bbs);
}
}
+ if (!loops_to_unloop.is_empty ())
+ {
+ bool irred_invalidated;
+ unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, NULL, &irred_invalidated);
+ changed = true;
+ }
free (bbs);
free (copied_bbs);
LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
when we need to go into loop closed SSA form. */
-static void
-unloop_loops (bitmap loop_closed_ssa_invalidated,
+void
+unloop_loops (vec<class loop *> &loops_to_unloop,
+ vec<int> &loops_to_unloop_nunroll,
+ bitmap loop_closed_ssa_invalidated,
bool *irred_invalidated)
{
while (loops_to_unloop.length ())
gsi = gsi_start_bb (latch_edge->dest);
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
}
- loops_to_unloop.release ();
- loops_to_unloop_nunroll.release ();
/* Remove edges in peeled copies. Given remove_path removes dominated
regions we need to cope with removal of already removed paths. */
}
gcc_assert (!need_ssa_update_p (cfun));
- unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
+ unloop_loops (loops_to_unloop, loops_to_unloop_nunroll,
+ loop_closed_ssa_invalidated, &irred_invalidated);
+ loops_to_unloop.release ();
+ loops_to_unloop_nunroll.release ();
if (irred_invalidated
&& loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
mark_irreducible_loops ();
{
unsigned i;
- unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
+ unloop_loops (loops_to_unloop,
+ loops_to_unloop_nunroll,
+ loop_closed_ssa_invalidated,
+ &irred_invalidated);
+ loops_to_unloop.release ();
+ loops_to_unloop_nunroll.release ();
/* We cannot use TODO_update_ssa_no_phi because VOPS gets confused. */
if (loop_closed_ssa_invalidated