diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-03-05 22:05:18 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-03-05 22:05:18 +0000 |
commit | a5414ff59071320dd80a6541af5befab853ca6ff (patch) | |
tree | 8650ebaed410b4e61e93edf3cebafec476c895b8 /gcc/loop-unroll.c | |
parent | a3e545123024adc8b8b52d235d15dbc37db1f119 (diff) | |
download | gcc-a5414ff59071320dd80a6541af5befab853ca6ff.tar.gz |
* basic-block.h (EDGE_IRREDUCIBLE_LOOP, EDGE_ALL_FLAGS): New.
* cfg.c (dump_edge_info): Add EDGE_IRREDUCIBLE_LOOP flag dump.
* cfgloop.c (flow_loop_free): Made global.
(establish_preds): New static function.
(flow_loop_tree_node_add): Handle subloops of added loop correctly.
(get_loop_exit_edges): New.
(verify_loop_structure): Verify EDGE_IRREDUCIBLE_LOOP flags.
* cfgloop.h (flow_loop_free, get_loop_exit_edges, unloop): Declare.
* cfgloopanal.c (mark_irreducible_loops): Mark edges in irreducible
loops.
* cfgloopmanip.c (loop_delete_branch_edge): Allow to test for
removability of an edge.
(fix_irreducible_loops): New static function.
(find_path, remove_path): Add ability to remove enclosing loops.
(unloop): New.
(copy_bbs, duplicate_loop_to_header_edge): Use EDGE_IRREDUCIBLE_LOOP
flags.
* cfgrtl.c (verify_flow_info): Handle EDGE_IRREDUCIBLE_LOOP flag.
* loop-unroll.c (peel_loops_completely): Do not duplicate loop if
not neccessary.
(decide_peel_completely, peel_loops_completely): Allow complete peeling
of non-duplicable once rolling loops.
* loop-unswitch.c (unswitch_loop): Update EDGE_IRREDUCIBLE_LOOP flags.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63864 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-unroll.c')
-rw-r--r-- | gcc/loop-unroll.c | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 67eb8da45b0..6f945a22a2d 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -180,25 +180,6 @@ peel_loops_completely (loops, flags) fprintf (rtl_dump_file, ";; Considering loop %d for complete peeling\n", loop->num); - /* Do not peel cold areas. */ - if (!maybe_hot_bb_p (loop->header)) - { - if (rtl_dump_file) - fprintf (rtl_dump_file, ";; Not considering loop, cold area\n"); - loop = next; - continue; - } - - /* Can the loop be manipulated? */ - if (!can_duplicate_loop_p (loop)) - { - if (rtl_dump_file) - fprintf (rtl_dump_file, - ";; Not considering loop, cannot duplicate\n"); - loop = next; - continue; - } - loop->ninsns = num_loop_insns (loop); decide_peel_once_rolling (loops, loop, flags); @@ -348,6 +329,23 @@ decide_peel_completely (loops, loop, flags) return; } + /* Do not peel cold areas. */ + if (!maybe_hot_bb_p (loop->header)) + { + if (rtl_dump_file) + fprintf (rtl_dump_file, ";; Not considering loop, cold area\n"); + return; + } + + /* Can the loop be manipulated? */ + if (!can_duplicate_loop_p (loop)) + { + if (rtl_dump_file) + fprintf (rtl_dump_file, + ";; Not considering loop, cannot duplicate\n"); + return; + } + /* npeel = number of iterations to peel. */ npeel = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS) / loop->ninsns; if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES)) @@ -411,45 +409,40 @@ peel_loop_completely (loops, loop) { sbitmap wont_exit; unsigned HOST_WIDE_INT npeel; - edge e; unsigned n_remove_edges, i; edge *remove_edges; struct loop_desc *desc = &loop->desc; npeel = desc->niter; - wont_exit = sbitmap_alloc (npeel + 2); - sbitmap_ones (wont_exit); - RESET_BIT (wont_exit, 0); - RESET_BIT (wont_exit, npeel + 1); - if (desc->may_be_zero) - RESET_BIT (wont_exit, 1); - - remove_edges = xcalloc (npeel, sizeof (edge)); - n_remove_edges = 0; - - if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop), - loops, npeel + 1, - wont_exit, desc->out_edge, remove_edges, &n_remove_edges, - DLTHE_FLAG_UPDATE_FREQ)) - abort (); + if (npeel) + { + wont_exit = sbitmap_alloc (npeel + 1); + sbitmap_ones (wont_exit); + RESET_BIT (wont_exit, 0); + if (desc->may_be_zero) + RESET_BIT (wont_exit, 1); - free (wont_exit); + remove_edges = xcalloc (npeel, sizeof (edge)); + n_remove_edges = 0; - /* Remove the exit edges. */ - for (i = 0; i < n_remove_edges; i++) - remove_path (loops, remove_edges[i]); - free (remove_edges); + if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop), + loops, npeel, + wont_exit, desc->out_edge, remove_edges, &n_remove_edges, + DLTHE_FLAG_UPDATE_FREQ)) + abort (); - /* Now remove the loop. */ - for (e = RBI (desc->in_edge->src)->copy->succ; - e && e->dest != RBI (desc->in_edge->dest)->copy; - e = e->succ_next); + free (wont_exit); - if (!e) - abort (); + /* Remove the exit edges. */ + for (i = 0; i < n_remove_edges; i++) + remove_path (loops, remove_edges[i]); + free (remove_edges); + } - remove_path (loops, e); + /* Now remove the unreachable part of the last iteration and cancel + the loop. */ + remove_path (loops, desc->in_edge); if (rtl_dump_file) fprintf (rtl_dump_file, ";; Peeled loop completely, %d times\n", (int) npeel); |