summaryrefslogtreecommitdiff
path: root/gcc/cfgloopmanip.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-12-16 21:01:25 +0100
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-12-16 20:01:25 +0000
commitc15bc84b7b6fad8567c9fd02f51e9436c5d3f861 (patch)
treecf52adea28f2fae4e6fc75375765ddb131f51b85 /gcc/cfgloopmanip.c
parent59b1a766fb697329a64202089365375c042f9c40 (diff)
downloadgcc-c15bc84b7b6fad8567c9fd02f51e9436c5d3f861.tar.gz
re PR tree-optimization/18707 (Performance regression at -O2 with gzip)
PR tree-optimization/18707 * cfgloopmanip.c (create_preheader): Move the preheader only if the latch was falling through to the header. Co-Authored-By: Roger Sayle <roger@eyesopen.com> From-SVN: r92282
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r--gcc/cfgloopmanip.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 77988c20c2f..c07571014af 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1142,6 +1142,8 @@ create_preheader (struct loop *loop, int flags)
struct loop *cloop, *ploop;
int nentry = 0;
bool irred = false;
+ bool latch_edge_was_fallthru;
+ edge one_succ_pred = 0;
edge_iterator ei;
cloop = loop->outer;
@@ -1152,6 +1154,8 @@ create_preheader (struct loop *loop, int flags)
continue;
irred |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
nentry++;
+ if (EDGE_COUNT (e->src->succs) == 1)
+ one_succ_pred = e;
}
gcc_assert (nentry);
if (nentry == 1)
@@ -1166,6 +1170,7 @@ create_preheader (struct loop *loop, int flags)
}
mfb_kj_edge = loop_latch_edge (loop);
+ latch_edge_was_fallthru = (mfb_kj_edge->flags & EDGE_FALLTHRU) != 0;
fallthru = make_forwarder_block (loop->header, mfb_keep_just,
mfb_update_loops);
dummy = fallthru->src;
@@ -1177,13 +1182,23 @@ create_preheader (struct loop *loop, int flags)
if (ploop->latch == dummy)
ploop->latch = fallthru->dest;
- /* Reorganize blocks so that the preheader is not stuck in the middle of the
- loop. */
-
- /* Get an edge that is different from the one from loop->latch to
- dummy. */
- e = EDGE_PRED (dummy, EDGE_PRED (dummy, 0)->src == loop->latch);
- move_block_after (dummy, e->src);
+ /* Try to be clever in placing the newly created preheader. The idea is to
+ avoid breaking any "fallthruness" relationship between blocks.
+
+ The preheader was created just before the header and all incoming edges
+ to the header were redirected to the preheader, except the latch edge.
+ So the only problematic case is when this latch edge was a fallthru
+ edge: it is not anymore after the preheader creation so we have broken
+ the fallthruness. We're therefore going to look for a better place. */
+ if (latch_edge_was_fallthru)
+ {
+ if (one_succ_pred)
+ e = one_succ_pred;
+ else
+ e = EDGE_PRED (dummy, 0);
+
+ move_block_after (dummy, e->src);
+ }
loop->header->loop_father = loop;
add_bb_to_loop (dummy, cloop);