Commit 9be94227 by Eric Botcazou Committed by Eric Botcazou

cfgcleanup.c (try_optimize_cfg): Do not delete forwarder blocks if CLEANUP_NO_INSN_DEL.

	* cfgcleanup.c (try_optimize_cfg): Do not delete forwarder blocks
	if CLEANUP_NO_INSN_DEL.
	* cfgrtl.c (unique_locus_on_edge_between_p): New function extracted
	from cfg_layout_merge_blocks.
	(emit_nop_for_unique_locus_between): New function.
	(rtl_merge_blocks): Invoke emit_nop_for_unique_locus_between.
	(cfg_layout_merge_blocks): Likewise.

From-SVN: r187913
parent 60ba49d0
2012-05-26 Eric Botcazou <ebotcazou@adacore.com>
* cfgcleanup.c (try_optimize_cfg): Do not delete forwarder blocks
if CLEANUP_NO_INSN_DEL.
* cfgrtl.c (unique_locus_on_edge_between_p): New function extracted
from cfg_layout_merge_blocks.
(emit_nop_for_unique_locus_between): New function.
(rtl_merge_blocks): Invoke emit_nop_for_unique_locus_between.
(cfg_layout_merge_blocks): Likewise.
2012-05-26 Dimitrios Apostolou <jimis@gmx.net> 2012-05-26 Dimitrios Apostolou <jimis@gmx.net>
Paolo Bonzini <bonzini@gnu.org> Paolo Bonzini <bonzini@gnu.org>
......
...@@ -2644,7 +2644,7 @@ try_optimize_cfg (int mode) ...@@ -2644,7 +2644,7 @@ try_optimize_cfg (int mode)
} }
/* If we fall through an empty block, we can remove it. */ /* If we fall through an empty block, we can remove it. */
if (!(mode & CLEANUP_CFGLAYOUT) if (!(mode & (CLEANUP_CFGLAYOUT | CLEANUP_NO_INSN_DEL))
&& single_pred_p (b) && single_pred_p (b)
&& (single_pred_edge (b)->flags & EDGE_FALLTHRU) && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
&& !LABEL_P (BB_HEAD (b)) && !LABEL_P (BB_HEAD (b))
......
...@@ -603,6 +603,56 @@ rtl_split_block (basic_block bb, void *insnp) ...@@ -603,6 +603,56 @@ rtl_split_block (basic_block bb, void *insnp)
return new_bb; return new_bb;
} }
/* Return true if the single edge between blocks A and B is the only place
in RTL which holds some unique locus. */
static bool
unique_locus_on_edge_between_p (basic_block a, basic_block b)
{
const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
rtx insn, end;
if (!goto_locus)
return false;
/* First scan block A backward. */
insn = BB_END (a);
end = PREV_INSN (BB_HEAD (a));
while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
insn = PREV_INSN (insn);
if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
return false;
/* Then scan block B forward. */
insn = BB_HEAD (b);
if (insn)
{
end = NEXT_INSN (BB_END (b));
while (insn != end && !NONDEBUG_INSN_P (insn))
insn = NEXT_INSN (insn);
if (insn != end && INSN_LOCATOR (insn) != 0
&& locator_eq (INSN_LOCATOR (insn), goto_locus))
return false;
}
return true;
}
/* If the single edge between blocks A and B is the only place in RTL which
holds some unique locus, emit a nop with that locus between the blocks. */
static void
emit_nop_for_unique_locus_between (basic_block a, basic_block b)
{
if (!unique_locus_on_edge_between_p (a, b))
return;
BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
}
/* Blocks A and B are to be merged into a single block A. The insns /* Blocks A and B are to be merged into a single block A. The insns
are already contiguous. */ are already contiguous. */
...@@ -681,15 +731,25 @@ rtl_merge_blocks (basic_block a, basic_block b) ...@@ -681,15 +731,25 @@ rtl_merge_blocks (basic_block a, basic_block b)
/* Delete everything marked above as well as crap that might be /* Delete everything marked above as well as crap that might be
hanging out between the two blocks. */ hanging out between the two blocks. */
BB_HEAD (b) = NULL; BB_END (a) = a_end;
BB_HEAD (b) = b_empty ? NULL_RTX : b_head;
delete_insn_chain (del_first, del_last, true); delete_insn_chain (del_first, del_last, true);
/* When not optimizing CFG and the edge is the only place in RTL which holds
some unique locus, emit a nop with that locus in between. */
if (!optimize)
{
emit_nop_for_unique_locus_between (a, b);
a_end = BB_END (a);
}
/* Reassociate the insns of B with A. */ /* Reassociate the insns of B with A. */
if (!b_empty) if (!b_empty)
{ {
update_bb_for_insn_chain (a_end, b_debug_end, a); update_bb_for_insn_chain (a_end, b_debug_end, a);
a_end = b_debug_end; BB_END (a) = b_debug_end;
BB_HEAD (b) = NULL_RTX;
} }
else if (b_end != b_debug_end) else if (b_end != b_debug_end)
{ {
...@@ -701,11 +761,10 @@ rtl_merge_blocks (basic_block a, basic_block b) ...@@ -701,11 +761,10 @@ rtl_merge_blocks (basic_block a, basic_block b)
reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start), reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start),
b_debug_end); b_debug_end);
update_bb_for_insn_chain (b_debug_start, b_debug_end, a); update_bb_for_insn_chain (b_debug_start, b_debug_end, a);
a_end = b_debug_end; BB_END (a) = b_debug_end;
} }
df_bb_delete (b->index); df_bb_delete (b->index);
BB_END (a) = a_end;
/* If B was a forwarder block, propagate the locus on the edge. */ /* If B was a forwarder block, propagate the locus on the edge. */
if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus) if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
...@@ -2853,33 +2912,10 @@ cfg_layout_merge_blocks (basic_block a, basic_block b) ...@@ -2853,33 +2912,10 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true); try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true);
gcc_assert (!JUMP_P (BB_END (a))); gcc_assert (!JUMP_P (BB_END (a)));
/* When not optimizing and the edge is the only place in RTL which holds /* When not optimizing CFG and the edge is the only place in RTL which holds
some unique locus, emit a nop with that locus in between. */ some unique locus, emit a nop with that locus in between. */
if (!optimize && EDGE_SUCC (a, 0)->goto_locus) if (!optimize)
{ emit_nop_for_unique_locus_between (a, b);
rtx insn = BB_END (a), end = PREV_INSN (BB_HEAD (a));
int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
while (insn != end && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0))
insn = PREV_INSN (insn);
if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
goto_locus = 0;
else
{
insn = BB_HEAD (b);
end = NEXT_INSN (BB_END (b));
while (insn != end && !INSN_P (insn))
insn = NEXT_INSN (insn);
if (insn != end && INSN_LOCATOR (insn) != 0
&& locator_eq (INSN_LOCATOR (insn), goto_locus))
goto_locus = 0;
}
if (goto_locus)
{
BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
INSN_LOCATOR (BB_END (a)) = goto_locus;
}
}
/* Possible line number notes should appear in between. */ /* Possible line number notes should appear in between. */
if (BB_HEADER (b)) if (BB_HEADER (b))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment