dump_flow_info (file);
free_basic_block_vars (1);
+
+#ifdef ENABLE_CHECKING
+ {
+ rtx insn;
+
+ /* Search for any REG_LABEL notes whih reference deleted labels. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
+
+ if (inote && GET_CODE (inote) == NOTE_INSN_DELETED_LABEL)
+ abort ();
+ }
+ }
+#endif
}
/* A subroutine of verify_wide_reg, called through for_each_rtx.
/* If the insn referred to a label, and that label was attached to
an ADDR_VEC, it's safe to delete the ADDR_VEC. In fact, it's
pretty much mandatory to delete it, because the ADDR_VEC may be
- referencing labels that no longer exist. */
+ referencing labels that no longer exist.
+
+ INSN may reference a deleted label, particularly when a jump
+ table has been optimized into a direct jump. There's no
+ real good way to fix up the reference to the deleted label
+ when the label is deleted, so we just allow it here.
- if (inote)
+ After dead code elimination is complete, we do search for
+ any REG_LABEL notes which reference deleted labels as a
+ sanity check. */
+
+ if (inote && GET_CODE (inote) == CODE_LABEL)
{
rtx label = XEXP (inote, 0);
rtx next;
- if (LABEL_NUSES (label) == 1
+ /* The label may be forced if it has been put in the constant
+ pool. If that is the only use we must discard the table
+ jump following it, but not the label itself. */
+ if (LABEL_NUSES (label) == 1 + LABEL_PRESERVE_P (label)
&& (next = next_nonnote_insn (label)) != NULL
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
pbi->cc0_live = 0;
if (libcall_is_dead)
- {
- prev = propagate_block_delete_libcall (pbi->bb, insn, note);
- insn = NEXT_INSN (prev);
- }
+ prev = propagate_block_delete_libcall (pbi->bb, insn, note);
else
propagate_block_delete_insn (pbi->bb, insn);