summaryrefslogtreecommitdiff
path: root/gcc/loop-unroll.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-05 22:05:18 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-05 22:05:18 +0000
commita5414ff59071320dd80a6541af5befab853ca6ff (patch)
tree8650ebaed410b4e61e93edf3cebafec476c895b8 /gcc/loop-unroll.c
parenta3e545123024adc8b8b52d235d15dbc37db1f119 (diff)
downloadgcc-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.c87
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);