aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cfgrtl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/cfgrtl.c')
-rw-r--r--gcc-4.9/gcc/cfgrtl.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/gcc-4.9/gcc/cfgrtl.c b/gcc-4.9/gcc/cfgrtl.c
index 2c5ca2ac1..ed1c37cd4 100644
--- a/gcc-4.9/gcc/cfgrtl.c
+++ b/gcc-4.9/gcc/cfgrtl.c
@@ -1453,7 +1453,24 @@ emit_barrier_after_bb (basic_block bb)
gcc_assert (current_ir_type () == IR_RTL_CFGRTL
|| current_ir_type () == IR_RTL_CFGLAYOUT);
if (current_ir_type () == IR_RTL_CFGLAYOUT)
- BB_FOOTER (bb) = unlink_insn_chain (barrier, barrier);
+ {
+ rtx insn = unlink_insn_chain (barrier, barrier);
+
+ if (BB_FOOTER (bb))
+ {
+ rtx footer_tail = BB_FOOTER (bb);
+
+ while (NEXT_INSN (footer_tail))
+ footer_tail = NEXT_INSN (footer_tail);
+ if (!BARRIER_P (footer_tail))
+ {
+ NEXT_INSN (footer_tail) = insn;
+ PREV_INSN (insn) = footer_tail;
+ }
+ }
+ else
+ BB_FOOTER (bb) = insn;
+ }
}
/* Like force_nonfallthru below, but additionally performs redirection
@@ -1761,6 +1778,22 @@ rtl_tidy_fallthru_edge (edge e)
&& (any_uncondjump_p (q)
|| single_succ_p (b)))
{
+ rtx label, table;
+
+ if (tablejump_p (q, &label, &table))
+ {
+ /* The label is likely mentioned in some instruction before
+ the tablejump and might not be DCEd, so turn it into
+ a note instead and move before the tablejump that is going to
+ be deleted. */
+ const char *name = LABEL_NAME (label);
+ PUT_CODE (label, NOTE);
+ NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
+ NOTE_DELETED_LABEL_NAME (label) = name;
+ reorder_insns (label, label, PREV_INSN (q));
+ delete_insn (table);
+ }
+
#ifdef HAVE_cc0
/* If this was a conditional jump, we need to also delete
the insn that set cc0. */
@@ -2481,7 +2514,6 @@ rtl_verify_edges (void)
| EDGE_LOOP_EXIT
| EDGE_CROSSING
| EDGE_PRESERVE
- | EDGE_ANNOTATED
| EDGE_PREDICTED_BY_EXPECT)) == 0)
n_branch++;