aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgbuild.c
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-10-11 15:02:32 +0200
committerYvan Roux <yvan.roux@linaro.org>2017-10-11 15:02:32 +0200
commita1b8ee536a7ab5c8d96ca98894009937a8c01608 (patch)
tree98e0c2b04cf3e352ea36c2290336f83f05b55b64 /gcc/cfgbuild.c
parentadbfebe68eb0f236026adb817435ee0a20906b04 (diff)
Merge branches/gcc-7-branch rev 253626.
Change-Id: If635aa7dbff0d433569bcb961bd02d8e16b894bf
Diffstat (limited to 'gcc/cfgbuild.c')
-rw-r--r--gcc/cfgbuild.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 69ca1282c37..238954a1cfa 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -442,9 +442,10 @@ find_bb_boundaries (basic_block bb)
rtx_insn *end = BB_END (bb), *x;
rtx_jump_table_data *table;
rtx_insn *flow_transfer_insn = NULL;
+ rtx_insn *debug_insn = NULL;
edge fallthru = NULL;
- if (insn == BB_END (bb))
+ if (insn == end)
return;
if (LABEL_P (insn))
@@ -455,27 +456,49 @@ find_bb_boundaries (basic_block bb)
{
enum rtx_code code = GET_CODE (insn);
+ if (code == DEBUG_INSN)
+ {
+ if (flow_transfer_insn && !debug_insn)
+ debug_insn = insn;
+ }
/* In case we've previously seen an insn that effects a control
flow transfer, split the block. */
- if ((flow_transfer_insn || code == CODE_LABEL)
- && inside_basic_block_p (insn))
+ else if ((flow_transfer_insn || code == CODE_LABEL)
+ && inside_basic_block_p (insn))
{
- fallthru = split_block (bb, PREV_INSN (insn));
+ rtx_insn *prev = PREV_INSN (insn);
+
+ /* If the first non-debug inside_basic_block_p insn after a control
+ flow transfer is not a label, split the block before the debug
+ insn instead of before the non-debug insn, so that the debug
+ insns are not lost. */
+ if (debug_insn && code != CODE_LABEL && code != BARRIER)
+ prev = PREV_INSN (debug_insn);
+ fallthru = split_block (bb, prev);
if (flow_transfer_insn)
{
BB_END (bb) = flow_transfer_insn;
+ rtx_insn *next;
/* Clean up the bb field for the insns between the blocks. */
for (x = NEXT_INSN (flow_transfer_insn);
x != BB_HEAD (fallthru->dest);
- x = NEXT_INSN (x))
- if (!BARRIER_P (x))
- set_block_for_insn (x, NULL);
+ x = next)
+ {
+ next = NEXT_INSN (x);
+ /* Debug insns should not be in between basic blocks,
+ drop them on the floor. */
+ if (DEBUG_INSN_P (x))
+ delete_insn (x);
+ else if (!BARRIER_P (x))
+ set_block_for_insn (x, NULL);
+ }
}
bb = fallthru->dest;
remove_edge (fallthru);
flow_transfer_insn = NULL;
+ debug_insn = NULL;
if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn))
make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, 0);
}
@@ -498,17 +521,23 @@ find_bb_boundaries (basic_block bb)
/* In case expander replaced normal insn by sequence terminating by
return and barrier, or possibly other sequence not behaving like
ordinary jump, we need to take care and move basic block boundary. */
- if (flow_transfer_insn)
+ if (flow_transfer_insn && flow_transfer_insn != end)
{
BB_END (bb) = flow_transfer_insn;
/* Clean up the bb field for the insns that do not belong to BB. */
- x = flow_transfer_insn;
- while (x != end)
+ rtx_insn *next;
+ for (x = NEXT_INSN (flow_transfer_insn); ; x = next)
{
- x = NEXT_INSN (x);
- if (!BARRIER_P (x))
+ next = NEXT_INSN (x);
+ /* Debug insns should not be in between basic blocks,
+ drop them on the floor. */
+ if (DEBUG_INSN_P (x))
+ delete_insn (x);
+ else if (!BARRIER_P (x))
set_block_for_insn (x, NULL);
+ if (x == end)
+ break;
}
}