diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-18 14:39:49 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-18 14:39:49 +0000 |
commit | a44300123f81d68890d0dd98012c3d9e38c11e81 (patch) | |
tree | 965e63d5d06c276a59bece27337abea448f54c59 /gcc/cfgloopmanip.c | |
parent | d64d3175bf55a6776c4c7dabd623b7c4a62fdb3b (diff) | |
download | gcc-a44300123f81d68890d0dd98012c3d9e38c11e81.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194582 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 34f73016608..64f6f643738 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 (); |