static void invalidate_mems_from_autoinc PARAMS ((struct propagate_block_info *,
rtx));
static void remove_fake_successors PARAMS ((basic_block));
-static void flow_nodes_print PARAMS ((const char *, const sbitmap, FILE *));
-static void flow_exits_print PARAMS ((const char *, const edge *, int, FILE *));
-static void flow_loops_cfg_dump PARAMS ((const struct loops *, FILE *));
-static int flow_loop_nested_p PARAMS ((struct loop *, struct loop *));
-static int flow_loop_exits_find PARAMS ((const sbitmap, edge **));
+static void flow_nodes_print PARAMS ((const char *, const sbitmap,
+ FILE *));
+static void flow_edge_list_print PARAMS ((const char *, const edge *,
+ int, FILE *));
+static void flow_loops_cfg_dump PARAMS ((const struct loops *,
+ FILE *));
+static int flow_loop_nested_p PARAMS ((struct loop *,
+ struct loop *));
+static int flow_loop_entry_edges_find PARAMS ((basic_block, const sbitmap,
+ edge **));
+static int flow_loop_exit_edges_find PARAMS ((const sbitmap, edge **));
static int flow_loop_nodes_find PARAMS ((basic_block, basic_block, sbitmap));
static int flow_depth_first_order_compute PARAMS ((int *, int *));
static void flow_dfs_compute_reverse_init
\f
/* Dump the list of basic blocks in the bitmap NODES. */
-static void
+static void
flow_nodes_print (str, nodes, file)
const char *str;
const sbitmap nodes;
{
int node;
+ if (! nodes)
+ return;
+
fprintf (file, "%s { ", str);
EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, node, {fprintf (file, "%d ", node);});
fputs ("}\n", file);
}
-/* Dump the list of exiting edges in the array EDGES. */
-static void
-flow_exits_print (str, edges, num_edges, file)
+/* Dump the list of edges in the array EDGE_LIST. */
+
+static void
+flow_edge_list_print (str, edge_list, num_edges, file)
const char *str;
- const edge *edges;
+ const edge *edge_list;
int num_edges;
FILE *file;
{
int i;
+ if (! edge_list)
+ return;
+
fprintf (file, "%s { ", str);
for (i = 0; i < num_edges; i++)
- fprintf (file, "%d->%d ", edges[i]->src->index, edges[i]->dest->index);
+ fprintf (file, "%d->%d ", edge_list[i]->src->index,
+ edge_list[i]->dest->index);
fputs ("}\n", file);
}
+
/* Dump loop related CFG information. */
static void
loop->depth, loop->level,
(long) (loop->outer ? loop->outer->num : -1));
+ flow_edge_list_print (";; entry edges", loop->entry_edges,
+ loop->num_entries, file);
fprintf (file, ";; %d", loop->num_nodes);
flow_nodes_print (" nodes", loop->nodes, file);
- fprintf (file, ";; %d", loop->num_exits);
- flow_exits_print (" exits", loop->exits, loop->num_exits, file);
+ flow_edge_list_print (";; exit edges", loop->exit_edges,
+ loop->num_exits, file);
if (loop_dump_aux)
loop_dump_aux (loop, file, verbose);
if (loop->nodes)
sbitmap_free (loop->nodes);
- if (loop->exits)
- free (loop->exits);
+ if (loop->entry_edges)
+ free (loop->entry_edges);
+ if (loop->exit_edges)
+ free (loop->exit_edges);
}
free (loops->array);
loops->array = NULL;
}
-/* Find the exits from the loop using the bitmap of loop nodes NODES
- and store in EXITS array. Return the number of exits from the
- loop. */
+/* Find the entry edges into the loop with header HEADER and nodes
+ NODES and store in ENTRY_EDGES array. Return the number of entry
+ edges from the loop. */
+
+static int
+flow_loop_entry_edges_find (header, nodes, entry_edges)
+ basic_block header;
+ const sbitmap nodes;
+ edge **entry_edges;
+{
+ edge e;
+ int num_entries;
+
+ *entry_edges = NULL;
+
+ num_entries = 0;
+ for (e = header->pred; e; e = e->pred_next)
+ {
+ basic_block src = e->src;
+
+ if (src == ENTRY_BLOCK_PTR || ! TEST_BIT (nodes, src->index))
+ num_entries++;
+ }
+
+ if (! num_entries)
+ abort ();
+
+ *entry_edges = (edge *) xmalloc (num_entries * sizeof (edge *));
+
+ num_entries = 0;
+ for (e = header->pred; e; e = e->pred_next)
+ {
+ basic_block src = e->src;
+
+ if (src == ENTRY_BLOCK_PTR || ! TEST_BIT (nodes, src->index))
+ (*entry_edges)[num_entries++] = e;
+ }
+
+ return num_entries;
+}
+
+
+/* Find the exit edges from the loop using the bitmap of loop nodes
+ NODES and store in EXIT_EDGES array. Return the number of
+ exit edges from the loop. */
static int
-flow_loop_exits_find (nodes, exits)
+flow_loop_exit_edges_find (nodes, exit_edges)
const sbitmap nodes;
- edge **exits;
+ edge **exit_edges;
{
edge e;
int node;
int num_exits;
- *exits = NULL;
+ *exit_edges = NULL;
/* Check all nodes within the loop to see if there are any
successors not in the loop. Note that a node may have multiple
- exiting edges. */
+ exiting edges ????? A node can have one jumping edge and one fallthru
+ edge so only one of these can exit the loop. */
num_exits = 0;
EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, node, {
for (e = BASIC_BLOCK (node)->succ; e; e = e->succ_next)
{
- basic_block dest = e->dest;
+ basic_block dest = e->dest;
if (dest == EXIT_BLOCK_PTR || ! TEST_BIT (nodes, dest->index))
num_exits++;
if (! num_exits)
return 0;
- *exits = (edge *) xmalloc (num_exits * sizeof (edge *));
+ *exit_edges = (edge *) xmalloc (num_exits * sizeof (edge *));
/* Store all exiting edges into an array. */
num_exits = 0;
EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, node, {
for (e = BASIC_BLOCK (node)->succ; e; e = e->succ_next)
{
- basic_block dest = e->dest;
+ basic_block dest = e->dest;
if (dest == EXIT_BLOCK_PTR || ! TEST_BIT (nodes, dest->index))
- (*exits)[num_exits++] = e;
+ (*exit_edges)[num_exits++] = e;
}
});
return num_exits;
}
+
/* Find the nodes contained within the loop with header HEADER and
latch LATCH and store in NODES. Return the number of nodes within
the loop. */
loop->last
= BASIC_BLOCK (sbitmap_last_set_bit (loop->nodes));
- /* Find edges which exit the loop. Note that a node
- may have several exit edges. */
+ /* Find edges which enter the loop header.
+ Note that the entry edges should only
+ enter the header of a natural loop. */
+ loop->num_entries
+ = flow_loop_entry_edges_find (loop->header, loop->nodes,
+ &loop->entry_edges);
+
+ /* Find edges which exit the loop. */
loop->num_exits
- = flow_loop_exits_find (loop->nodes, &loop->exits);
+ = flow_loop_exit_edges_find (loop->nodes,
+ &loop->exit_edges);
/* Look to see if the loop has a pre-header node. */
loop->pre_header = flow_loop_pre_header_find (header, dom);