aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2013-04-16 06:26:18 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2013-04-16 06:26:18 +0000
commit4c8af8586d16a6d63fef6956a583d323c467d3de (patch)
treee59dfcb18955037dc4447fba23bccfc4ee7c2ec0
parent96fba5210e819b3354e8ca8d99c1b13e417277d8 (diff)
downloadgcc-4c8af8586d16a6d63fef6956a583d323c467d3de.zip
gcc-4c8af8586d16a6d63fef6956a583d323c467d3de.tar.gz
gcc-4c8af8586d16a6d63fef6956a583d323c467d3de.tar.bz2
cfgrtl.c (cfg_layout_merge_blocks): Revert r184005...
* cfgrtl.c (cfg_layout_merge_blocks): Revert r184005, implement correct fix by moving header and footer insn to the footer of the merged basic block. Clear BB_END of the merged-away block. From-SVN: r197995
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/cfgrtl.c63
2 files changed, 38 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 31c21e03..3d7e60b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2013-04-16 Steven Bosscher <steven@gcc.gnu.org>
+ * cfgrtl.c (cfg_layout_merge_blocks): Revert r184005, implement
+ correct fix by moving header and footer insn to the footer of
+ the merged basic block. Clear BB_END of the merged-away block.
+
PR middle-end/43631
* emit-rtl.c (make_note_raw): New function.
(link_insn_into_chain): New static inline function.
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index f59051d..9b12d28 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -4083,18 +4083,40 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
if (!optimize)
emit_nop_for_unique_locus_between (a, b);
- /* Possible line number notes should appear in between. */
- if (BB_HEADER (b))
+ /* Move things from b->footer after a->footer. */
+ if (BB_FOOTER (b))
{
- rtx first = BB_END (a), last;
-
- last = emit_insn_after_noloc (BB_HEADER (b), BB_END (a), a);
- /* The above might add a BARRIER as BB_END, but as barriers
- aren't valid parts of a bb, remove_insn doesn't update
- BB_END if it is a barrier. So adjust BB_END here. */
- while (BB_END (a) != first && BARRIER_P (BB_END (a)))
- BB_END (a) = PREV_INSN (BB_END (a));
- delete_insn_chain (NEXT_INSN (first), last, false);
+ if (!BB_FOOTER (a))
+ BB_FOOTER (a) = BB_FOOTER (b);
+ else
+ {
+ rtx last = BB_FOOTER (a);
+
+ while (NEXT_INSN (last))
+ last = NEXT_INSN (last);
+ NEXT_INSN (last) = BB_FOOTER (b);
+ PREV_INSN (BB_FOOTER (b)) = last;
+ }
+ BB_FOOTER (b) = NULL;
+ }
+
+ /* Move things from b->header before a->footer.
+ Note that this may include dead tablejump data, but we don't clean
+ those up until we go out of cfglayout mode. */
+ if (BB_HEADER (b))
+ {
+ if (! BB_FOOTER (a))
+ BB_FOOTER (a) = BB_HEADER (b);
+ else
+ {
+ rtx last = BB_HEADER (b);
+
+ while (NEXT_INSN (last))
+ last = NEXT_INSN (last);
+ NEXT_INSN (last) = BB_FOOTER (a);
+ PREV_INSN (BB_FOOTER (a)) = last;
+ BB_FOOTER (a) = BB_HEADER (b);
+ }
BB_HEADER (b) = NULL;
}
@@ -4120,28 +4142,11 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
if (!NOTE_INSN_BASIC_BLOCK_P (insn))
insn = NEXT_INSN (insn);
gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
- BB_HEAD (b) = NULL;
+ BB_HEAD (b) = BB_END (b) = NULL;
delete_insn (insn);
df_bb_delete (b->index);
- /* Possible tablejumps and barriers should appear after the block. */
- if (BB_FOOTER (b))
- {
- if (!BB_FOOTER (a))
- BB_FOOTER (a) = BB_FOOTER (b);
- else
- {
- rtx last = BB_FOOTER (a);
-
- while (NEXT_INSN (last))
- last = NEXT_INSN (last);
- NEXT_INSN (last) = BB_FOOTER (b);
- PREV_INSN (BB_FOOTER (b)) = last;
- }
- BB_FOOTER (b) = NULL;
- }
-
/* If B was a forwarder block, propagate the locus on the edge. */
if (forwarder_p
&& LOCATION_LOCUS (EDGE_SUCC (b, 0)->goto_locus) == UNKNOWN_LOCATION)