aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgloopmanip.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-02-08 11:00:26 +0000
committerRichard Biener <rguenther@suse.de>2013-02-08 11:00:26 +0000
commitf81fff2564f64d757bd767a4cb22071e62cb6269 (patch)
tree81c148d9e2f62306dffd098afe34e256d86ec31e /gcc/cfgloopmanip.c
parent5ae7512d97c129c1f9f1002b2e7a66bb2903e155 (diff)
2013-02-08 Richard Biener <rguenther@suse.de>
PR middle-end/56181 * cfgloop.h (flow_loops_find): Adjust. (bb_loop_header_p): Declare. * cfgloop.c (bb_loop_header_p): New function split out from ... (flow_loops_find): ... here. Adjust function signature, support incremental loop structure update. (verify_loop_structure): Cleanup. Verify a loop is a loop. * cfgloopmanip.c (fix_loop_structure): Move ... * loop-init.c (fix_loop_structure): ... here. (apply_loop_flags): Split out from ... (loop_optimizer_init): ... here. (fix_loop_structure): Use apply_loop_flags. Use flow_loops_find in incremental mode, only remove dead loops here. * gcc.dg/torture/pr56181.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@195879 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r--gcc/cfgloopmanip.c156
1 files changed, 0 insertions, 156 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index c72cedaf74e..3e53aa0dddf 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1760,159 +1760,3 @@ loop_version (struct loop *loop,
return nloop;
}
-
-/* The structure of loops might have changed. Some loops might get removed
- (and their headers and latches were set to NULL), loop exists might get
- removed (thus the loop nesting may be wrong), and some blocks and edges
- were changed (so the information about bb --> loop mapping does not have
- to be correct). But still for the remaining loops the header dominates
- the latch, and loops did not get new subloops (new loops might possibly
- get created, but we are not interested in them). Fix up the mess.
-
- If CHANGED_BBS is not NULL, basic blocks whose loop has changed are
- marked in it. */
-
-void
-fix_loop_structure (bitmap changed_bbs)
-{
- basic_block bb;
- struct loop *loop, *ploop;
- loop_iterator li;
- bool record_exits = false;
- struct loop **superloop = XNEWVEC (struct loop *, number_of_loops ());
-
- /* We need exact and fast dominance info to be available. */
- gcc_assert (dom_info_state (CDI_DOMINATORS) == DOM_OK);
-
- /* Remove the old bb -> loop mapping. Remember the depth of the blocks in
- the loop hierarchy, so that we can recognize blocks whose loop nesting
- relationship has changed. */
- FOR_EACH_BB (bb)
- {
- if (changed_bbs)
- bb->aux = (void *) (size_t) loop_depth (bb->loop_father);
- bb->loop_father = current_loops->tree_root;
- }
-
- if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
- {
- release_recorded_exits ();
- record_exits = true;
- }
-
- /* First re-compute loop latches. */
- FOR_EACH_LOOP (li, loop, 0)
- {
- edge_iterator ei;
- edge e, first_latch = NULL, latch = NULL;
-
- if (!loop->header)
- continue;
-
- FOR_EACH_EDGE (e, ei, loop->header->preds)
- if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header))
- {
- if (!first_latch)
- first_latch = latch = e;
- else
- {
- latch = NULL;
- break;
- }
- }
- /* If there was no latch, schedule the loop for removal. */
- if (!first_latch)
- loop->header = NULL;
- /* If there was a single latch, record it. */
- else if (latch)
- loop->latch = latch->src;
- /* Otherwise there are multiple latches which are eventually
- disambiguated below. */
- else
- loop->latch = NULL;
- }
-
- /* Remove the dead loops from structures. We start from the innermost
- loops, so that when we remove the loops, we know that the loops inside
- are preserved, and do not waste time relinking loops that will be
- removed later. */
- FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
- {
- if (loop->header)
- continue;
-
- while (loop->inner)
- {
- ploop = loop->inner;
- flow_loop_tree_node_remove (ploop);
- flow_loop_tree_node_add (loop_outer (loop), ploop);
- }
-
- /* Remove the loop and free its data. */
- delete_loop (loop);
- }
-
- /* Rescan the bodies of loops, starting from the outermost ones. We assume
- that no optimization interchanges the order of the loops, i.e., it cannot
- happen that L1 was superloop of L2 before and it is subloop of L2 now
- (without explicitly updating loop information). At the same time, we also
- determine the new loop structure. */
- current_loops->tree_root->num_nodes = n_basic_blocks;
- FOR_EACH_LOOP (li, loop, 0)
- {
- superloop[loop->num] = loop->header->loop_father;
- loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
- }
-
- /* Now fix the loop nesting. */
- FOR_EACH_LOOP (li, loop, 0)
- {
- ploop = superloop[loop->num];
- if (ploop != loop_outer (loop))
- {
- flow_loop_tree_node_remove (loop);
- flow_loop_tree_node_add (ploop, loop);
- }
- }
- free (superloop);
-
- /* Mark the blocks whose loop has changed. */
- if (changed_bbs)
- {
- FOR_EACH_BB (bb)
- {
- if ((void *) (size_t) loop_depth (bb->loop_father) != bb->aux)
- bitmap_set_bit (changed_bbs, bb->index);
-
- bb->aux = NULL;
- }
- }
-
- if (!loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
- disambiguate_loops_with_multiple_latches ();
-
- if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
- {
- int cp_flags = CP_SIMPLE_PREHEADERS;
-
- if (loops_state_satisfies_p (LOOPS_HAVE_FALLTHRU_PREHEADERS))
- cp_flags |= CP_FALLTHRU_PREHEADERS;
-
- create_preheaders (cp_flags);
- }
-
- if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
- force_single_succ_latches ();
-
- if (loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
- mark_irreducible_loops ();
-
- if (record_exits)
- record_loop_exits ();
-
- loops_state_clear (LOOPS_NEED_FIXUP);
-
-#ifdef ENABLE_CHECKING
- verify_loop_structure ();
-#endif
-}