aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-10-24 07:45:26 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-10-24 07:45:26 +0000
commit4cce988e5b77892135180d6f1a486cfc3e1d5bac (patch)
tree28e69a6ab8a84a8bba7c04bb6a5015a69b04ea57 /gcc
parentbe8cf3b55e32b8bd1eb0672d90f91fc246586178 (diff)
downloadgcc-4cce988e5b77892135180d6f1a486cfc3e1d5bac.zip
gcc-4cce988e5b77892135180d6f1a486cfc3e1d5bac.tar.gz
gcc-4cce988e5b77892135180d6f1a486cfc3e1d5bac.tar.bz2
cfglayout.c (fixup_reorder_chain): When ensuring that there is at least one insn with a locus corresponding to an...
* cfglayout.c (fixup_reorder_chain): When ensuring that there is at least one insn with a locus corresponding to an edge's goto_locus, disregard non-fallthru edges to the exit block and merge the blocks created for the same goto_locus. From-SVN: r165897
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cfglayout.c29
2 files changed, 32 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 809f3be..189f349 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cfglayout.c (fixup_reorder_chain): When ensuring that there is at
+ least one insn with a locus corresponding to an edge's goto_locus,
+ disregard non-fallthru edges to the exit block and merge the blocks
+ created for the same goto_locus.
+
2010-10-23 Joseph Myers <joseph@codesourcery.com>
* gcc.c (n_switches_alloc_debug_check): New.
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 8a0d35c..d599b36 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -940,7 +940,9 @@ fixup_reorder_chain (void)
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
{
- basic_block nb;
+ edge e2;
+ edge_iterator ei2;
+ basic_block dest, nb;
rtx end;
insn = BB_END (e->src);
@@ -957,10 +959,17 @@ fixup_reorder_chain (void)
INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
continue;
}
- if (e->dest != EXIT_BLOCK_PTR)
+ dest = e->dest;
+ if (dest == EXIT_BLOCK_PTR)
{
- insn = BB_HEAD (e->dest);
- end = NEXT_INSN (BB_END (e->dest));
+ /* Non-fallthru edges to the exit block cannot be split. */
+ if (!(e->flags & EDGE_FALLTHRU))
+ continue;
+ }
+ else
+ {
+ insn = BB_HEAD (dest);
+ end = NEXT_INSN (BB_END (dest));
while (insn != end && !NONDEBUG_INSN_P (insn))
insn = NEXT_INSN (insn);
if (insn != end && INSN_LOCATOR (insn)
@@ -972,6 +981,18 @@ fixup_reorder_chain (void)
BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
nb);
INSN_LOCATOR (BB_END (nb)) = e->goto_locus;
+
+ /* If there are other incoming edges to the destination block
+ with the same goto locus, redirect them to the new block as
+ well, this can prevent other such blocks from being created
+ in subsequent iterations of the loop. */
+ for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
+ if (e2->goto_locus
+ && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
+ && locator_eq (e->goto_locus, e2->goto_locus))
+ redirect_edge_and_branch (e2, nb);
+ else
+ ei_next (&ei2);
}
}
}