diff options
author | Richard Biener <rguenther@suse.de> | 2013-02-08 11:00:26 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-02-08 11:00:26 +0000 |
commit | 0375167b6c15a60dc2b974b2654a8ff1dbe7160a (patch) | |
tree | 81c148d9e2f62306dffd098afe34e256d86ec31e /gcc/cfgloopmanip.c | |
parent | 85d768f349087f3766ff84054ec7b3403c52ac7a (diff) | |
download | gcc-0375167b6c15a60dc2b974b2654a8ff1dbe7160a.zip gcc-0375167b6c15a60dc2b974b2654a8ff1dbe7160a.tar.gz gcc-0375167b6c15a60dc2b974b2654a8ff1dbe7160a.tar.bz2 |
re PR rtl-optimization/56181 (ICE in verify_loop_structure, at cfgloop.c:1581 with -ftracer)
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.
From-SVN: r195879
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 156 |
1 files changed, 0 insertions, 156 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index c72ceda..3e53aa0 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 -} |