Commit eb8b3474 by Alexandre Oliva Committed by Alexandre Oliva

[SFN] stabilize find_bb_boundaries

If find_bb_boundaries is given a block with zero or one nondebug insn
beside debug insns, it shouldn't purge dead edges, because without
debug insns we wouldn't purge them at that point.  Doing so may change
the order in which edges are processed, and ultimately lead to
different transformations to the CFG and then to different
optimizations.

We shouldn't, however, retain debug insns after control flow insns, so
if we find debug insns after a single insn that happens to be a
control flow insn, do the debug insn cleanups, but still refrain from
purging dead edges at that point.


for  gcc/ChangeLog

	* cfgbuild.c (find_bb_boundaries): Don't purge dead edges if,
	without debug insns, we wouldn't, but clean up debug insns
	after a control flow insn nevertheless.

From-SVN: r255567
parent 65f4b875
2017-12-12 Alexandre Oliva <aoliva@redhat.com> 2017-12-12 Alexandre Oliva <aoliva@redhat.com>
* cfgbuild.c (find_bb_boundaries): Don't purge dead edges if,
without debug insns, we wouldn't, but clean up debug insns
after a control flow insn nevertheless.
* cfgcleanup.c (delete_unreachable_blocks): Use alternate * cfgcleanup.c (delete_unreachable_blocks): Use alternate
block removal order if MAY_HAVE_DEBUG_BIND_INSNS. block removal order if MAY_HAVE_DEBUG_BIND_INSNS.
* cfgexpand.c (label_rtx_for_bb): Skip debug insns. * cfgexpand.c (label_rtx_for_bb): Skip debug insns.
...@@ -444,10 +444,43 @@ find_bb_boundaries (basic_block bb) ...@@ -444,10 +444,43 @@ find_bb_boundaries (basic_block bb)
rtx_insn *flow_transfer_insn = NULL; rtx_insn *flow_transfer_insn = NULL;
rtx_insn *debug_insn = NULL; rtx_insn *debug_insn = NULL;
edge fallthru = NULL; edge fallthru = NULL;
bool skip_purge;
if (insn == end) if (insn == end)
return; return;
if (DEBUG_INSN_P (insn) || DEBUG_INSN_P (end))
{
/* Check whether, without debug insns, the insn==end test above
would have caused us to return immediately, and behave the
same way even with debug insns. If we don't do this, debug
insns could cause us to purge dead edges at different times,
which could in turn change the cfg and affect codegen
decisions in subtle but undesirable ways. */
while (insn != end && DEBUG_INSN_P (insn))
insn = NEXT_INSN (insn);
rtx_insn *e = end;
while (insn != e && DEBUG_INSN_P (e))
e = PREV_INSN (e);
if (insn == e)
{
/* If there are debug insns after a single insn that is a
control flow insn in the block, we'd have left right
away, but we should clean up the debug insns after the
control flow insn, because they can't remain in the same
block. So, do the debug insn cleaning up, but then bail
out without purging dead edges as we would if the debug
insns hadn't been there. */
if (e != end && !DEBUG_INSN_P (e) && control_flow_insn_p (e))
{
skip_purge = true;
flow_transfer_insn = e;
goto clean_up_debug_after_control_flow;
}
return;
}
}
if (LABEL_P (insn)) if (LABEL_P (insn))
insn = NEXT_INSN (insn); insn = NEXT_INSN (insn);
...@@ -475,7 +508,6 @@ find_bb_boundaries (basic_block bb) ...@@ -475,7 +508,6 @@ find_bb_boundaries (basic_block bb)
if (debug_insn && code != CODE_LABEL && code != BARRIER) if (debug_insn && code != CODE_LABEL && code != BARRIER)
prev = PREV_INSN (debug_insn); prev = PREV_INSN (debug_insn);
fallthru = split_block (bb, prev); fallthru = split_block (bb, prev);
if (flow_transfer_insn) if (flow_transfer_insn)
{ {
BB_END (bb) = flow_transfer_insn; BB_END (bb) = flow_transfer_insn;
...@@ -527,6 +559,9 @@ find_bb_boundaries (basic_block bb) ...@@ -527,6 +559,9 @@ find_bb_boundaries (basic_block bb)
ordinary jump, we need to take care and move basic block boundary. */ ordinary jump, we need to take care and move basic block boundary. */
if (flow_transfer_insn && flow_transfer_insn != end) if (flow_transfer_insn && flow_transfer_insn != end)
{ {
skip_purge = false;
clean_up_debug_after_control_flow:
BB_END (bb) = flow_transfer_insn; BB_END (bb) = flow_transfer_insn;
/* Clean up the bb field for the insns that do not belong to BB. */ /* Clean up the bb field for the insns that do not belong to BB. */
...@@ -543,6 +578,9 @@ find_bb_boundaries (basic_block bb) ...@@ -543,6 +578,9 @@ find_bb_boundaries (basic_block bb)
if (x == end) if (x == end)
break; break;
} }
if (skip_purge)
return;
} }
/* We've possibly replaced the conditional jump by conditional jump /* We've possibly replaced the conditional jump by conditional jump
......
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