static void init_label_info (rtx);
static void mark_all_labels (rtx);
static void mark_jump_label_1 (rtx, rtx, bool, bool);
+static void mark_jump_label_asm (rtx, rtx);
static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
static int invert_exp_1 (rtx, rtx);
static int returnjump_p_1 (rtx *, void *);
&& (rtx_equal_p (label_dest, XEXP (pc_src, 1))
|| rtx_equal_p (label_dest,
XEXP (pc_src, 2))))))
-
+
{
/* The CODE_LABEL referred to in the note must be the
CODE_LABEL in the LABEL_REF of the "set". We can
/* Test for an integer condition, or a floating-point comparison
in which NaNs can be ignored. */
- if (GET_CODE (arg0) == CONST_INT
+ if (CONST_INT_P (arg0)
|| (GET_MODE (arg0) != VOIDmode
&& GET_MODE_CLASS (mode) != MODE_CC
&& !HONOR_NANS (mode)))
int
returnjump_p (rtx insn)
{
- /* Handle delayed branches. */
- if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
-
if (!JUMP_P (insn))
return 0;
-
return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
}
void
mark_jump_label (rtx x, rtx insn, int in_mem)
{
- mark_jump_label_1 (x, insn, in_mem != 0,
- (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
+ rtx asmop = extract_asm_operands (x);
+ if (asmop)
+ mark_jump_label_asm (asmop, insn);
+ else
+ mark_jump_label_1 (x, insn, in_mem != 0,
+ (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
}
/* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
}
}
+/* Worker function for mark_jump_label. Handle asm insns specially.
+ In particular, output operands need not be considered so we can
+ avoid re-scanning the replicated asm_operand. Also, the asm_labels
+ need to be considered targets. */
+
+static void
+mark_jump_label_asm (rtx asmop, rtx insn)
+{
+ int i;
+
+ for (i = ASM_OPERANDS_INPUT_LENGTH (asmop) - 1; i >= 0; --i)
+ mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop, i), insn, false, false);
+
+ for (i = ASM_OPERANDS_LABEL_LENGTH (asmop) - 1; i >= 0; --i)
+ mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop, i), insn, false, true);
+}
\f
/* Delete insn INSN from the chain of insns and update label ref counts
and delete insns now unreachable.
/* Likewise if we're deleting a dispatch table. */
- if (JUMP_P (insn)
- && (GET_CODE (PATTERN (insn)) == ADDR_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
+ if (JUMP_TABLE_DATA_P (insn))
{
rtx pat = PATTERN (insn);
int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
if (was_code_label
&& NEXT_INSN (insn) != 0
- && JUMP_P (NEXT_INSN (insn))
- && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
- || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
+ && JUMP_TABLE_DATA_P (NEXT_INSN (insn)))
next = delete_related_insns (NEXT_INSN (insn));
/* If INSN was a label, delete insns following it if now unreachable. */
redirect_jump_1 (rtx jump, rtx nlabel)
{
int ochanges = num_validated_changes ();
- rtx *loc;
+ rtx *loc, asmop;
- if (GET_CODE (PATTERN (jump)) == PARALLEL)
+ asmop = extract_asm_operands (PATTERN (jump));
+ if (asmop)
+ {
+ if (nlabel == NULL)
+ return 0;
+ gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop) == 1);
+ loc = &ASM_OPERANDS_LABEL (asmop, 0);
+ }
+ else if (GET_CODE (PATTERN (jump)) == PARALLEL)
loc = &XVECEXP (PATTERN (jump), 0, 0);
else
loc = &PATTERN (jump);
}
/* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
- NLABEL in JUMP.
+ NLABEL in JUMP.
If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
count has dropped to zero. */
void
int ok;
ochanges = num_validated_changes ();
- gcc_assert (x);
+ if (x == NULL)
+ return 0;
ok = invert_exp_1 (SET_SRC (x), jump);
gcc_assert (ok);
-
+
if (num_validated_changes () == ochanges)
return 0;
if (GET_MODE (x) != GET_MODE (y))
return 0;
+ /* MEMs refering to different address space are not equivalent. */
+ if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
+ return 0;
+
/* For commutative operations, the RTX match if the operand match in any
order. Also handle the simple binary and unary cases without a loop. */
if (targetm.commutative_p (x, UNKNOWN))