summaryrefslogtreecommitdiff
path: root/gcc/jump.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/jump.c')
-rw-r--r--gcc/jump.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/jump.c b/gcc/jump.c
index 28a9b0f43ea..a12d0404500 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
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 *);
@@ -1006,8 +1007,12 @@ sets_cc0_p (const_rtx x)
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
@@ -1145,6 +1150,22 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
}
}
+/* 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);
+}
/* Delete insn INSN from the chain of insns and update label ref counts
and delete insns now unreachable.
@@ -1386,9 +1407,17 @@ int
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);
@@ -1514,7 +1543,8 @@ invert_jump_1 (rtx jump, rtx nlabel)
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);