aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgloopmanip.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2012-12-18 14:39:49 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-12-18 14:39:49 +0000
commit867fdd05e4de59b21ea5fec6182127404cc94712 (patch)
tree965e63d5d06c276a59bece27337abea448f54c59 /gcc/cfgloopmanip.c
parent0b8ca8fefec7479e91654819be9b77362406b1b5 (diff)
downloadgcc-867fdd05e4de59b21ea5fec6182127404cc94712.zip
gcc-867fdd05e4de59b21ea5fec6182127404cc94712.tar.gz
gcc-867fdd05e4de59b21ea5fec6182127404cc94712.tar.bz2
re PR middle-end/54838 (ICE: in merge_latch_edges, at cfgloop.c:678 with -ftracer)
2012-12-18 Richard Biener <rguenther@suse.de> PR middle-end/54838 * cfgloopmanip.c (fix_loop_structure): Re-discover latch edges first and mark loops for removal if no latch edges remain. Properly re-create LOOPS_HAVE_FALLTHRU_PREHEADERS. * loop-init.c (loop_optimizer_finalize): Set LOOPS_MAY_HAVE_MULTIPLE_LATCHES. * g++.dg/torture/pr54838.C: New testcase. From-SVN: r194582
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r--gcc/cfgloopmanip.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 34f7301..64f6f64 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1793,6 +1793,40 @@ fix_loop_structure (bitmap changed_bbs)
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 and it belongs to the loop of the
+ header, record it. */
+ else if (latch
+ && latch->src->loop_father == loop)
+ 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
@@ -1849,34 +1883,18 @@ fix_loop_structure (bitmap changed_bbs)
}
}
- /* Then re-compute the single latch if there is one. */
- FOR_EACH_LOOP (li, loop, 0)
- {
- edge_iterator ei;
- edge e, latch = NULL;
- FOR_EACH_EDGE (e, ei, loop->header->preds)
- if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header))
- {
- if (!latch)
- latch = e;
- else
- {
- latch = NULL;
- break;
- }
- }
- if (latch
- && latch->src->loop_father == loop)
- loop->latch = latch->src;
- else
- loop->latch = NULL;
- }
-
if (!loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
disambiguate_loops_with_multiple_latches ();
if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
- create_preheaders (CP_SIMPLE_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 ();