diff options
Diffstat (limited to 'gcc/cfgloop.c')
-rw-r--r-- | gcc/cfgloop.c | 204 |
1 files changed, 93 insertions, 111 deletions
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index a94cbfe..b4b8eb7 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -31,11 +31,13 @@ static int flow_loop_nested_p PARAMS ((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 void flow_loop_pre_header_scan PARAMS ((struct loop *)); +static int flow_loop_nodes_find PARAMS ((basic_block, basic_block, + sbitmap)); +static void flow_loop_pre_header_scan PARAMS ((struct loop *)); static basic_block flow_loop_pre_header_find PARAMS ((basic_block, const sbitmap *)); -static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *)); +static void flow_loop_tree_node_add PARAMS ((struct loop *, + struct loop *)); static void flow_loops_tree_build PARAMS ((struct loops *)); static int flow_loop_level_compute PARAMS ((struct loop *, int)); static int flow_loops_level_compute PARAMS ((struct loops *)); @@ -68,14 +70,17 @@ flow_loops_cfg_dump (loops, file) fputs (";; DFS order: ", file); for (i = 0; i < n_basic_blocks; i++) fprintf (file, "%d ", loops->cfg.dfs_order[i]); + fputs ("\n", file); } + /* Dump the reverse completion node order. */ if (loops->cfg.rc_order) { fputs (";; RC order: ", file); for (i = 0; i < n_basic_blocks; i++) fprintf (file, "%d ", loops->cfg.rc_order[i]); + fputs ("\n", file); } } @@ -107,12 +112,10 @@ flow_loop_dump (loop, file, loop_dump_aux, verbose) fprintf (file, ";;\n;; Loop %d (%d to %d):%s%s\n", loop->num, INSN_UID (loop->first->head), INSN_UID (loop->last->end), - loop->shared ? " shared" : "", - loop->invalid ? " invalid" : ""); + loop->shared ? " shared" : "", loop->invalid ? " invalid" : ""); else fprintf (file, ";;\n;; Loop %d:%s%s\n", loop->num, - loop->shared ? " shared" : "", - loop->invalid ? " invalid" : ""); + loop->shared ? " shared" : "", loop->invalid ? " invalid" : ""); fprintf (file, ";; header %d, latch %d, pre-header %d, first %d, last %d\n", loop->header->index, loop->latch->index, @@ -125,14 +128,17 @@ flow_loop_dump (loop, file, loop_dump_aux, verbose) if (loop->pre_header_edges) flow_edge_list_print (";; pre-header edges", loop->pre_header_edges, loop->num_pre_header_edges, file); + 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); flow_edge_list_print (";; exit edges", loop->exit_edges, loop->num_exits, file); + if (loop->exits_doms) flow_nodes_print (";; exit doms", loop->exits_doms, file); + if (loop_dump_aux) loop_dump_aux (loop, file, verbose); } @@ -147,49 +153,42 @@ flow_loops_dump (loops, file, loop_dump_aux, verbose) void (*loop_dump_aux) PARAMS((const struct loop *, FILE *, int)); int verbose; { - int i; + int i, j; int num_loops; num_loops = loops->num; if (! num_loops || ! file) return; - fprintf (file, ";; %d loops found, %d levels\n", - num_loops, loops->levels); - + fprintf (file, ";; %d loops found, %d levels\n", num_loops, loops->levels); for (i = 0; i < num_loops; i++) { struct loop *loop = &loops->array[i]; flow_loop_dump (loop, file, loop_dump_aux, verbose); - if (loop->shared) - { - int j; - - for (j = 0; j < i; j++) - { - struct loop *oloop = &loops->array[j]; - - if (loop->header == oloop->header) - { - int disjoint; - int smaller; - - smaller = loop->num_nodes < oloop->num_nodes; - - /* If the union of LOOP and OLOOP is different than - the larger of LOOP and OLOOP then LOOP and OLOOP - must be disjoint. */ - disjoint = ! flow_loop_nested_p (smaller ? loop : oloop, - smaller ? oloop : loop); - fprintf (file, - ";; loop header %d shared by loops %d, %d %s\n", - loop->header->index, i, j, - disjoint ? "disjoint" : "nested"); - } - } - } + for (j = 0; j < i; j++) + { + struct loop *oloop = &loops->array[j]; + + if (loop->header == oloop->header) + { + int disjoint; + int smaller; + + smaller = loop->num_nodes < oloop->num_nodes; + + /* If the union of LOOP and OLOOP is different than + the larger of LOOP and OLOOP then LOOP and OLOOP + must be disjoint. */ + disjoint = ! flow_loop_nested_p (smaller ? loop : oloop, + smaller ? oloop : loop); + fprintf (file, + ";; loop header %d shared by loops %d, %d %s\n", + loop->header->index, i, j, + disjoint ? "disjoint" : "nested"); + } + } } if (verbose) @@ -225,11 +224,13 @@ flow_loops_free (loops) if (loop->exits_doms) sbitmap_free (loop->exits_doms); } + free (loops->array); loops->array = NULL; if (loops->cfg.dom) sbitmap_vector_free (loops->cfg.dom); + if (loops->cfg.dfs_order) free (loops->cfg.dfs_order); @@ -394,42 +395,33 @@ static void flow_loop_pre_header_scan (loop) struct loop *loop; { - int num = 0; + int num; basic_block ebb; + edge e; loop->num_pre_header_edges = 0; - if (loop->num_entries != 1) - return; + return; ebb = loop->entry_edges[0]->src; + if (ebb == ENTRY_BLOCK_PTR) + return; - if (ebb != ENTRY_BLOCK_PTR) - { - edge e; - - /* 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. */ - num++; - while (ebb->pred->src != ENTRY_BLOCK_PTR && ! ebb->pred->pred_next) - { - ebb = ebb->pred->src; - num++; - } - - loop->pre_header_edges = (edge *) 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) - { - loop->pre_header_edges[--num] = e; - } - } + /* 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; + num++) + ebb = ebb->pred->src; + + loop->pre_header_edges = (edge *) 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) + loop->pre_header_edges[--num] = e; } /* Return the block for the pre-header of the loop with header @@ -465,6 +457,7 @@ flow_loop_pre_header_find (header, dom) } } } + return pre_header; } @@ -485,16 +478,13 @@ flow_loop_tree_node_add (prevloop, loop) return; } - while (prevloop->outer) - { - if (flow_loop_nested_p (prevloop->outer, loop)) - { - prevloop->next = loop; - loop->outer = prevloop->outer; - return; - } - prevloop = prevloop->outer; - } + for (; prevloop->outer; prevloop = prevloop->outer) + if (flow_loop_nested_p (prevloop->outer, loop)) + { + prevloop->next = loop; + loop->outer = prevloop->outer; + return; + } prevloop->next = loop; loop->outer = NULL; @@ -517,7 +507,8 @@ flow_loops_tree_build (loops) Since we used a depth first search this should be the outermost loop. */ loops->tree_root = &loops->array[0]; - loops->tree_root->outer = loops->tree_root->inner = loops->tree_root->next = NULL; + loops->tree_root->outer = loops->tree_root->inner + = loops->tree_root->next = NULL; /* Add the remaining loops to the tree. */ for (i = 1; i < num_loops; i++) @@ -546,13 +537,11 @@ flow_loop_level_compute (loop, depth) itself). */ for (inner = loop->inner; inner; inner = inner->next) { - int ilevel; - - ilevel = flow_loop_level_compute (inner, depth + 1) + 1; + int ilevel = flow_loop_level_compute (inner, depth + 1) + 1; - if (ilevel > level) - level = ilevel; + level = MAX (ilevel, level); } + loop->level = level; loop->depth = depth; return level; @@ -566,17 +555,17 @@ static int flow_loops_level_compute (loops) struct loops *loops; { + int levels = 0; struct loop *loop; int level; - int levels = 0; /* Traverse all the outer level loops. */ for (loop = loops->tree_root; loop; loop = loop->next) { level = flow_loop_level_compute (loop, 1); - if (level > levels) - levels = level; + levels = MAX (levels, level); } + return levels; } @@ -594,23 +583,15 @@ flow_loop_scan (loops, loop, flags) flags |= LOOP_EXIT_EDGES; if (flags & LOOP_ENTRY_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 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); if (flags & LOOP_EXIT_EDGES) - { - /* Find edges which exit the loop. */ - loop->num_exits - = flow_loop_exit_edges_find (loop->nodes, - &loop->exit_edges); - } + /* Find edges which exit the loop. */ + loop->num_exits + = flow_loop_exit_edges_find (loop->nodes, &loop->exit_edges); if (flags & LOOP_EXITS_DOMS) { @@ -640,13 +621,14 @@ flow_loop_scan (loops, loop, flags) the loop pre-header. */ flow_loop_pre_header_scan (loop); } + return 1; } -/* 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 loops found. */ +/* 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 + loops found. */ int flow_loops_find (loops, flags) @@ -668,7 +650,7 @@ flow_loops_find (loops, flags) if (! (flags & LOOP_TREE)) abort (); - memset (loops, 0, sizeof (*loops)); + memset (loops, 0, sizeof *loops); /* Taking care of this degenerate case makes the rest of this code simpler. */ @@ -684,7 +666,6 @@ flow_loops_find (loops, flags) /* Count the number of loop edges (back edges). This should be the same as the number of natural loops. */ - num_loops = 0; for (b = 0; b < n_basic_blocks; b++) { @@ -810,9 +791,7 @@ flow_loops_find (loops, flags) sbitmap_free (headers); } else - { - sbitmap_vector_free (dom); - } + sbitmap_vector_free (dom); loops->num = num_loops; @@ -828,6 +807,7 @@ flow_loops_find (loops, flags) /* Update the information regarding the loops in the CFG specified by LOOPS. */ + int flow_loops_update (loops, flags) struct loops *loops; @@ -850,5 +830,7 @@ flow_loop_outside_edge_p (loop, e) { if (e->dest != loop->header) abort (); - return (e->src == ENTRY_BLOCK_PTR) || ! TEST_BIT (loop->nodes, e->src->index); + + return (e->src == ENTRY_BLOCK_PTR) + || ! TEST_BIT (loop->nodes, e->src->index); } |