/* Loop manipulation code for GNU compiler.
- Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software
- Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
This file is part of GCC.
struct loop *father = current_loops->tree_root, *act;
bool ret = false;
- for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+ FOR_EACH_VEC_ELT (edge, exits, i, e)
{
act = find_common_loop (loop, e->dest->loop_father);
if (flow_loop_nested_p (father, act))
/* The exit edges of LOOP no longer exits its original immediate
superloops; remove them from the appropriate exit lists. */
- for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+ FOR_EACH_VEC_ELT (edge, exits, i, e)
rescan_loop_exit (e, false, false);
ret = true;
{
sbitmap in_queue;
basic_block *queue, *qtop, *qbeg, *qend;
- struct loop *base_loop;
+ struct loop *base_loop, *target_loop;
edge e;
/* We pass through blocks back-reachable from FROM, testing whether some
fix_loop_placement. */
base_loop = from->loop_father;
- if (base_loop == current_loops->tree_root)
+ /* If we are already in the outermost loop, the basic blocks cannot be moved
+ outside of it. If FROM is the header of the base loop, it cannot be moved
+ outside of it, either. In both cases, we can end now. */
+ if (base_loop == current_loops->tree_root
+ || from == base_loop->header)
return;
in_queue = sbitmap_alloc (last_basic_block);
/* Subloop header, maybe move the loop upward. */
if (!fix_loop_placement (from->loop_father))
continue;
+ target_loop = loop_outer (from->loop_father);
}
else
{
/* Ordinary basic block. */
if (!fix_bb_placement (from))
continue;
+ target_loop = from->loop_father;
}
FOR_EACH_EDGE (e, ei, from->succs)
&& (nca == base_loop
|| nca != pred->loop_father))
pred = pred->loop_father->header;
- else if (!flow_loop_nested_p (from->loop_father, pred->loop_father))
+ else if (!flow_loop_nested_p (target_loop, pred->loop_father))
{
- /* No point in processing it. */
+ /* If PRED is already higher in the loop hierarchy than the
+ TARGET_LOOP to that we moved FROM, the change of the position
+ of FROM does not affect the position of PRED, so there is no
+ point in processing it. */
continue;
}
int i, nrem, n_bord_bbs;
sbitmap seen;
bool irred_invalidated = false;
+ edge_iterator ei;
+ struct loop *l, *f;
if (!can_remove_branch_p (e))
return false;
we belong to. In this case first unloop the loops, then proceed
normally. We may assume that e->dest is not a header of any loop,
as it now has exactly one predecessor. */
- while (loop_outer (e->src->loop_father)
- && dominated_by_p (CDI_DOMINATORS,
- e->src->loop_father->latch, e->dest))
- unloop (e->src->loop_father, &irred_invalidated);
+ for (l = e->src->loop_father; loop_outer (l); l = f)
+ {
+ f = loop_outer (l);
+ if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
+ unloop (l, &irred_invalidated);
+ }
/* Identify the path. */
nrem = find_path (e, &rem_bbs);
/* Find "border" hexes -- i.e. those with predecessor in removed path. */
for (i = 0; i < nrem; i++)
SET_BIT (seen, rem_bbs[i]->index);
+ if (!irred_invalidated)
+ FOR_EACH_EDGE (ae, ei, e->src->succs)
+ if (ae != e && ae->dest != EXIT_BLOCK_PTR && !TEST_BIT (seen, ae->dest->index)
+ && ae->flags & EDGE_IRREDUCIBLE_LOOP)
+ irred_invalidated = true;
for (i = 0; i < nrem; i++)
{
- edge_iterator ei;
bb = rem_bbs[i];
FOR_EACH_EDGE (ae, ei, rem_bbs[i]->succs)
if (ae->dest != EXIT_BLOCK_PTR && !TEST_BIT (seen, ae->dest->index))
bb->aux = 0;
dom_bbs = get_dominated_by (CDI_DOMINATORS, bb);
- for (j = 0; VEC_iterate (basic_block, dom_bbs, j, dominated); j++)
+ FOR_EACH_VEC_ELT (basic_block, dom_bbs, j, dominated)
{
if (flow_bb_inside_loop_p (loop, dominated))
continue;
/* Duplicate loop. */
if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
NULL, NULL, NULL, 0))
- return NULL;
+ {
+ entry->flags |= irred_flag;
+ return NULL;
+ }
/* After duplication entry edge now points to new loop head block.
Note down new head as second_head. */