#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
+#include "obstack.h"
#include "basic-block.h"
#include "toplev.h"
#include "cfgloop.h"
static void flow_loop_pre_header_scan (struct loop *);
static basic_block flow_loop_pre_header_find (basic_block);
static int flow_loop_level_compute (struct loop *);
-static int flow_loops_level_compute (struct loops *);
+static void flow_loops_level_compute (struct loops *);
static void establish_preds (struct loop *);
static void canonicalize_loop_headers (void);
static bool glb_enum_p (basic_block, void *);
FOR_EACH_BB (bb)
{
edge succ;
+ edge_iterator ei;
fprintf (file, ";; %d succs { ", bb->index);
- for (succ = bb->succ; succ; succ = succ->succ_next)
+ FOR_EACH_EDGE (succ, ei, bb->succs)
fprintf (file, "%d ", succ->dest->index);
fprintf (file, "}\n");
}
struct loop *
superloop_at_depth (struct loop *loop, unsigned depth)
{
- if (depth > (unsigned) loop->depth)
- abort ();
+ gcc_assert (depth <= (unsigned) loop->depth);
if (depth == (unsigned) loop->depth)
return loop;
if (! num_loops || ! file)
return;
- fprintf (file, ";; %d loops found, %d levels\n",
- num_loops, loops->levels);
+ fprintf (file, ";; %d loops found\n", num_loops);
for (i = 0; i < num_loops; i++)
{
{
unsigned i;
- if (! loops->num)
- abort ();
+ gcc_assert (loops->num);
/* Free the loop descriptors. */
for (i = 0; i < loops->num; i++)
flow_loop_entry_edges_find (struct loop *loop)
{
edge e;
+ edge_iterator ei;
int num_entries;
num_entries = 0;
- for (e = loop->header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, loop->header->preds)
{
if (flow_loop_outside_edge_p (loop, e))
num_entries++;
}
- if (! num_entries)
- abort ();
+ gcc_assert (num_entries);
loop->entry_edges = xmalloc (num_entries * sizeof (edge *));
num_entries = 0;
- for (e = loop->header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, loop->header->preds)
{
if (flow_loop_outside_edge_p (loop, e))
loop->entry_edges[num_entries++] = e;
bbs = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
{
+ edge_iterator ei;
node = bbs[i];
- for (e = node->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, node->succs)
{
basic_block dest = e->dest;
num_exits = 0;
for (i = 0; i < loop->num_nodes; i++)
{
+ edge_iterator ei;
node = bbs[i];
- for (e = node->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, node->succs)
{
basic_block dest = e->dest;
{
basic_block node;
edge e;
+ edge_iterator ei;
node = stack[--sp];
- for (e = node->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, node->preds)
{
basic_block ancestor = e->src;
FOR_EACH_BB (bb)
{
+ edge_iterator ei;
if (bb->loop_father == loops->tree_root)
continue;
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->dest == EXIT_BLOCK_PTR)
continue;
/* If we have already seen an exit, mark this by the edge that
surely does not occur as any exit. */
if (loop->single_exit)
- loop->single_exit = ENTRY_BLOCK_PTR->succ;
+ loop->single_exit = EDGE_SUCC (ENTRY_BLOCK_PTR, 0);
else
loop->single_exit = e;
}
if (!loop)
continue;
- if (loop->single_exit == ENTRY_BLOCK_PTR->succ)
+ if (loop->single_exit == EDGE_SUCC (ENTRY_BLOCK_PTR, 0))
loop->single_exit = NULL;
}
/* Count number of edges along trace from loop header to
root of pre-header extended basic block. Usually this is
only one or two edges. */
- for (num = 1; ebb->pred->src != ENTRY_BLOCK_PTR && ! ebb->pred->pred_next;
+ for (num = 1;
+ EDGE_PRED (ebb, 0)->src != ENTRY_BLOCK_PTR && EDGE_COUNT (ebb->preds) == 1;
num++)
- ebb = ebb->pred->src;
+ ebb = EDGE_PRED (ebb, 0)->src;
loop->pre_header_edges = xmalloc (num * sizeof (edge));
loop->num_pre_header_edges = num;
/* Store edges in order that they are followed. The source of the first edge
is the root node of the pre-header extended basic block and the
destination of the last last edge is the loop header. */
- for (e = loop->entry_edges[0]; num; e = e->src->pred)
+ for (e = loop->entry_edges[0]; num; e = EDGE_PRED (e->src, 0))
loop->pre_header_edges[--num] = e;
}
{
basic_block pre_header;
edge e;
+ edge_iterator ei;
/* If block p is a predecessor of the header and is the only block
that the header does not dominate, then it is the pre-header. */
pre_header = NULL;
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
{
basic_block node = e->src;
hierarchy tree specified by LOOPS. Return the maximum enclosed loop
level. */
-static int
+static void
flow_loops_level_compute (struct loops *loops)
{
- return flow_loop_level_compute (loops->tree_root);
+ flow_loop_level_compute (loops->tree_root);
}
/* Scan a single natural loop specified by LOOP collecting information
{
alloc_aux_for_block (jump, sizeof (int));
HEADER_BLOCK (jump) = 0;
- alloc_aux_for_edge (jump->pred, sizeof (int));
- LATCH_EDGE (jump->pred) = 0;
- set_immediate_dominator (CDI_DOMINATORS, jump, jump->pred->src);
+ alloc_aux_for_edge (EDGE_PRED (jump, 0), sizeof (int));
+ LATCH_EDGE (EDGE_PRED (jump, 0)) = 0;
+ set_immediate_dominator (CDI_DOMINATORS, jump, EDGE_PRED (jump, 0)->src);
}
/* A callback for make_forwarder block, to redirect all edges except for
/* Split blocks so that each loop has only single latch. */
FOR_EACH_BB (header)
{
+ edge_iterator ei;
int num_latches = 0;
int have_abnormal_edge = 0;
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
{
basic_block latch = e->src;
HEADER_BLOCK (header) = num_latches;
}
- if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
+ if (HEADER_BLOCK (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest))
{
basic_block bb;
/* We could not redirect edges freely here. On the other hand,
we can simply split the edge from entry block. */
- bb = split_edge (ENTRY_BLOCK_PTR->succ);
+ bb = split_edge (EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
- alloc_aux_for_edge (bb->succ, sizeof (int));
- LATCH_EDGE (bb->succ) = 0;
+ alloc_aux_for_edge (EDGE_SUCC (bb, 0), sizeof (int));
+ LATCH_EDGE (EDGE_SUCC (bb, 0)) = 0;
alloc_aux_for_block (bb, sizeof (int));
HEADER_BLOCK (bb) = 0;
}
{
int max_freq, is_heavy;
edge heavy, tmp_edge;
+ edge_iterator ei;
if (HEADER_BLOCK (header) <= 1)
continue;
is_heavy = 1;
heavy = NULL;
max_freq = 0;
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
if (LATCH_EDGE (e) &&
EDGE_FREQUENCY (e) > max_freq)
max_freq = EDGE_FREQUENCY (e);
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
if (LATCH_EDGE (e) &&
EDGE_FREQUENCY (e) >= max_freq / HEAVY_EDGE_RATIO)
{
#endif
}
+/* Initialize all the parallel_p fields of the loops structure to true. */
+
+static void
+initialize_loops_parallel_p (struct loops *loops)
+{
+ unsigned int i;
+
+ for (i = 0; i < loops->num; i++)
+ {
+ struct loop *loop = loops->parray[i];
+ loop->parallel_p = true;
+ }
+}
+
/* Find all the natural loops in the function and save in LOOPS structure and
recalculate loop_depth information in basic block structures. FLAGS
controls which loop information is collected. Return the number of natural
/* This function cannot be repeatedly called with different
flags to build up the loop information. The loop tree
must always be built if this function is called. */
- if (! (flags & LOOP_TREE))
- abort ();
+ gcc_assert (flags & LOOP_TREE);
memset (loops, 0, sizeof *loops);
num_loops = 0;
FOR_EACH_BB (header)
{
+ edge_iterator ei;
int more_latches = 0;
header->loop_depth = 0;
/* If we have an abnormal predecessor, do not consider the
loop (not worth the problems). */
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
if (e->flags & EDGE_ABNORMAL)
break;
if (e)
continue;
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
{
basic_block latch = e->src;
- if (e->flags & EDGE_ABNORMAL)
- abort ();
+ gcc_assert (!(e->flags & EDGE_ABNORMAL));
/* Look for back edges where a predecessor is dominated
by this block. A natural loop has a single entry
&& dominated_by_p (CDI_DOMINATORS, latch, header))
{
/* Shared headers should be eliminated by now. */
- if (more_latches)
- abort ();
+ gcc_assert (!more_latches);
more_latches = 1;
SET_BIT (headers, header->index);
num_loops++;
for (b = 0; b < n_basic_blocks; b++)
{
struct loop *loop;
+ edge_iterator ei;
/* Search the nodes of the CFG in reverse completion order
so that we can find outer loops first. */
num_loops++;
/* Look for the latch for this header block. */
- for (e = header->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, header->preds)
{
basic_block latch = e->src;
/* Assign the loop nesting depth and enclosed loop level for each
loop. */
- loops->levels = flow_loops_level_compute (loops);
+ flow_loops_level_compute (loops);
/* Scan the loops. */
for (i = 1; i < num_loops; i++)
flow_loop_scan (loops->parray[i], flags);
loops->num = num_loops;
+ initialize_loops_parallel_p (loops);
}
sbitmap_free (headers);
return loops->num;
}
-/* Update the information regarding the loops in the CFG
- specified by LOOPS. */
-
-int
-flow_loops_update (struct loops *loops, int flags)
-{
- /* One day we may want to update the current loop data. For now
- throw away the old stuff and rebuild what we need. */
- if (loops->parray)
- flow_loops_free (loops);
-
- return flow_loops_find (loops, flags);
-}
-
/* Return nonzero if basic block BB belongs to LOOP. */
bool
flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
bool
flow_loop_outside_edge_p (const struct loop *loop, edge e)
{
- if (e->dest != loop->header)
- abort ();
+ gcc_assert (e->dest == loop->header);
return !flow_bb_inside_loop_p (loop, e->src);
}
basic_block *tovisit, bb;
unsigned tv = 0;
- if (!loop->num_nodes)
- abort ();
+ gcc_assert (loop->num_nodes);
tovisit = xcalloc (loop->num_nodes, sizeof (basic_block));
tovisit[tv++] = loop->header;
if (loop->latch == EXIT_BLOCK_PTR)
{
/* There may be blocks unreachable from EXIT_BLOCK. */
- if (loop->num_nodes != (unsigned) n_basic_blocks + 2)
- abort ();
+ gcc_assert (loop->num_nodes == (unsigned) n_basic_blocks + 2);
FOR_EACH_BB (bb)
tovisit[tv++] = bb;
tovisit[tv++] = EXIT_BLOCK_PTR;
loop->header) + 1;
}
- if (tv != loop->num_nodes)
- abort ();
+ gcc_assert (tv == loop->num_nodes);
return tovisit;
}
basic_block *tovisit;
int tv;
- if (!loop->num_nodes)
- abort ();
+ gcc_assert (loop->num_nodes);
tovisit = xcalloc (loop->num_nodes, sizeof (basic_block));
- if (loop->latch == EXIT_BLOCK_PTR)
- abort ();
+ gcc_assert (loop->latch != EXIT_BLOCK_PTR);
tv = 0;
fill_sons_in_loop (loop, loop->header, tovisit, &tv);
- if (tv != (int) loop->num_nodes)
- abort ();
+ gcc_assert (tv == (int) loop->num_nodes);
return tovisit;
}
unsigned int i = 0;
unsigned int vc = 1;
- if (!loop->num_nodes)
- abort ();
-
- if (loop->latch == EXIT_BLOCK_PTR)
- abort ();
+ gcc_assert (loop->num_nodes);
+ gcc_assert (loop->latch != EXIT_BLOCK_PTR);
blocks = xcalloc (loop->num_nodes, sizeof (basic_block));
visited = BITMAP_XMALLOC ();
while (i < loop->num_nodes)
{
edge e;
+ edge_iterator ei;
if (!bitmap_bit_p (visited, bb->index))
{
blocks[i++] = bb;
}
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
if (flow_bb_inside_loop_p (loop, e->dest))
{
}
}
- if (i < vc)
- abort ();
+ gcc_assert (i >= vc);
bb = blocks[vc++];
}
edge *edges, e;
unsigned i, n;
basic_block * body;
+ edge_iterator ei;
- if (loop->latch == EXIT_BLOCK_PTR)
- abort ();
+ gcc_assert (loop->latch != EXIT_BLOCK_PTR);
body = get_loop_body (loop);
n = 0;
for (i = 0; i < loop->num_nodes; i++)
- for (e = body[i]->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, body[i]->succs)
if (!flow_bb_inside_loop_p (loop, e->dest))
n++;
edges = xmalloc (n * sizeof (edge));
*n_edges = n;
n = 0;
for (i = 0; i < loop->num_nodes; i++)
- for (e = body[i]->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, body[i]->succs)
if (!flow_bb_inside_loop_p (loop, e->dest))
edges[n++] = e;
free (body);
unsigned i, n;
basic_block * body;
- if (loop->latch == EXIT_BLOCK_PTR)
- abort ();
+ gcc_assert (loop->latch != EXIT_BLOCK_PTR);
body = get_loop_body (loop);
n = 0;
for (i = 0; i < loop->num_nodes; i++)
- if (body[i]->succ && body[i]->succ->succ_next)
+ if (EDGE_COUNT (body[i]->succs) >= 2)
n++;
free (body);
basic_block *bbs;
unsigned i;
- if (loop->inner)
- abort ();
+ gcc_assert (!loop->inner);
/* Move blocks up one level (they should be removed as soon as possible). */
bbs = get_loop_body (loop);
continue;
if ((loops->state & LOOPS_HAVE_PREHEADERS)
- && (!loop->header->pred->pred_next
- || loop->header->pred->pred_next->pred_next))
+ && EDGE_COUNT (loop->header->preds) != 2)
{
error ("Loop %d's header does not have exactly 2 entries.", i);
err = 1;
}
if (loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
{
- if (!loop->latch->succ
- || loop->latch->succ->succ_next)
+ if (EDGE_COUNT (loop->latch->succs) != 1)
{
error ("Loop %d's latch does not have exactly 1 successor.", i);
err = 1;
}
- if (loop->latch->succ->dest != loop->header)
+ if (EDGE_SUCC (loop->latch, 0)->dest != loop->header)
{
error ("Loop %d's latch does not have header as successor.", i);
err = 1;
irreds = sbitmap_alloc (last_basic_block);
FOR_EACH_BB (bb)
{
+ edge_iterator ei;
if (bb->flags & BB_IRREDUCIBLE_LOOP)
SET_BIT (irreds, bb->index);
else
RESET_BIT (irreds, bb->index);
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
e->flags |= EDGE_ALL_FLAGS + 1;
}
/* Compare. */
FOR_EACH_BB (bb)
{
+ edge_iterator ei;
+
if ((bb->flags & BB_IRREDUCIBLE_LOOP)
&& !TEST_BIT (irreds, bb->index))
{
error ("Basic block %d should not be marked irreducible.", bb->index);
err = 1;
}
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
if ((e->flags & EDGE_IRREDUCIBLE_LOOP)
&& !(e->flags & (EDGE_ALL_FLAGS + 1)))
memset (sizes, 0, sizeof (unsigned) * loops->num);
FOR_EACH_BB (bb)
{
+ edge_iterator ei;
if (bb->loop_father == loops->tree_root)
continue;
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->dest == EXIT_BLOCK_PTR)
continue;
}
}
- if (err)
- abort ();
+ gcc_assert (!err);
free (sizes);
}
edge
loop_latch_edge (const struct loop *loop)
{
- edge e;
-
- for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next)
- continue;
-
- return e;
+ return find_edge (loop->latch, loop->header);
}
/* Returns preheader edge of LOOP. */
loop_preheader_edge (const struct loop *loop)
{
edge e;
+ edge_iterator ei;
- for (e = loop->header->pred; e->src == loop->latch; e = e->pred_next)
- continue;
+ FOR_EACH_EDGE (e, ei, loop->header->preds)
+ if (e->src != loop->latch)
+ break;
return e;
}