+2001-03-28 Bernd Schmidt <bernds@redhat.com>
+
+ * flow.c (propagate_block): When trying to delete a case vector, cope
+ if its label has LABEL_PRESERVE_P set.
+ * jump.c (jump_optimize_1): Move call to delete_barrier_successors to
+ a point where JUMP_LABELS and LABEL_NUSES are set up properly.
+ (delete_barrier_successors): If deleting a table jump, delete the case
+ vector as well.
+ * varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P
+ so it won't get deleted.
+
Tue Mar 20 18:31:48 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
1999-11-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
{
if (REG_NOTE_KIND (inote) == REG_LABEL)
{
+ int n_forced;
rtx label = XEXP (inote, 0);
rtx next;
LABEL_NUSES (label)--;
+ /* The label may be forced if it has been put in the
+ constant pool. We can't delete it in this case, but
+ we still must discard a jump table following it. */
+ n_forced = 0;
+ if (LABEL_PRESERVE_P (label))
+ n_forced++;
+
/* If this 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. */
- if (LABEL_NUSES (label) == 0
+ if (LABEL_NUSES (label) == n_forced
&& (next = next_nonnote_insn (label)) != NULL
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
if (flag_exceptions && cross_jump)
init_insn_eh_region (f, max_uid);
- delete_barrier_successors (f);
-
/* Leave some extra room for labels and duplicate exit test insns
we make. */
max_jump_chain = max_uid * 14 / 10;
for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
LABEL_NUSES (XEXP (insn, 0))++;
+ delete_barrier_successors (f);
+
/* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
notes and recompute LABEL_NUSES. */
if (mark_labels_only)
insn = NEXT_INSN (insn);
while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
{
- if (GET_CODE (insn) == NOTE
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ /* Detect when we're deleting a tablejump; get rid of
+ the jump table as well. */
+ rtx next1 = next_nonnote_insn (insn);
+ rtx next2 = next1 ? next_nonnote_insn (next1) : 0;
+ if (next2 && GET_CODE (next1) == CODE_LABEL
+ && (GET_CODE (PATTERN (next2)) == ADDR_VEC
+ || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC))
+ {
+ delete_insn (insn);
+ insn = next2;
+ }
+ else
+ insn = delete_insn (insn);
+ }
+ else if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
insn = NEXT_INSN (insn);
else
pop_obstacks ();
}
+ if (GET_CODE (x) == LABEL_REF)
+ LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
/* Allocate a pool constant descriptor, fill it in, and chain it in. */
pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));