/* 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;
}
edge ae;
basic_block *rem_bbs, *bord_bbs, from, bb;
VEC (basic_block, heap) *dom_bbs;
- int i, nrem, n_bord_bbs, nreml;
+ int i, nrem, n_bord_bbs;
sbitmap seen;
bool irred_invalidated = false;
- struct loop **deleted_loop;
if (!can_remove_branch_p (e))
return false;
dom_bbs = NULL;
/* Cancel loops contained in the path. */
- deleted_loop = XNEWVEC (struct loop *, nrem);
- nreml = 0;
for (i = 0; i < nrem; i++)
if (rem_bbs[i]->loop_father->header == rem_bbs[i])
- deleted_loop[nreml++] = rem_bbs[i]->loop_father;
-
- for (i = 0; i < nreml; i++)
- cancel_loop_tree (deleted_loop[i]);
- free (deleted_loop);
+ cancel_loop_tree (rem_bbs[i]->loop_father);
remove_bbs (rem_bbs, nrem);
free (rem_bbs);
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. */