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
This commit is contained in:
Steven Bosscher 2013-04-16 06:26:18 +00:00
parent 96fba5210e
commit 4c8af8586d
2 changed files with 37 additions and 28 deletions

View File

@ -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.

View File

@ -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;
if (!BB_FOOTER (a))
BB_FOOTER (a) = BB_FOOTER (b);
else
{
rtx last = BB_FOOTER (a);
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);
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)