Fix mark_all_labels vs cfglayout mode.
* jump.c (maybe_propagate_label_ref): Split out of... (mark_all_labels): ... here. Do not attempt label_ref propagation while in cfglayout mode. From-SVN: r176663
This commit is contained in:
parent
a0a22423b0
commit
5f93b30abd
|
@ -1,3 +1,9 @@
|
|||
2011-07-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* jump.c (maybe_propagate_label_ref): Split out of...
|
||||
(mark_all_labels): ... here. Do not attempt label_ref
|
||||
propagation while in cfglayout mode.
|
||||
|
||||
2011-07-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf2out.c (struct macinfo_struct): Change code to unsigned char.
|
||||
|
|
102
gcc/jump.c
102
gcc/jump.c
|
@ -200,19 +200,17 @@ init_label_info (rtx f)
|
|||
}
|
||||
}
|
||||
|
||||
/* Mark the label each jump jumps to.
|
||||
Combine consecutive labels, and count uses of labels. */
|
||||
/* A subroutine of mark_all_labels. Trivially propagate a simple label
|
||||
load into a jump_insn that uses it. */
|
||||
|
||||
static void
|
||||
mark_all_labels (rtx f)
|
||||
maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
|
||||
{
|
||||
rtx insn;
|
||||
rtx prev_nonjump_insn = NULL;
|
||||
rtx label_note, pc, pc_src;
|
||||
|
||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
||||
if (NONDEBUG_INSN_P (insn))
|
||||
{
|
||||
mark_jump_label (PATTERN (insn), insn, 0);
|
||||
pc = pc_set (jump_insn);
|
||||
pc_src = pc != NULL ? SET_SRC (pc) : NULL;
|
||||
label_note = find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL);
|
||||
|
||||
/* If the previous non-jump insn sets something to a label,
|
||||
something that this jump insn uses, make that label the primary
|
||||
|
@ -222,23 +220,11 @@ mark_all_labels (rtx f)
|
|||
and must be a plain (set (pc) ...), maybe in a parallel, and
|
||||
may refer to the item being set only directly or as one of the
|
||||
arms in an IF_THEN_ELSE. */
|
||||
if (! INSN_DELETED_P (insn)
|
||||
&& JUMP_P (insn)
|
||||
&& JUMP_LABEL (insn) == NULL)
|
||||
{
|
||||
rtx label_note = NULL;
|
||||
rtx pc = pc_set (insn);
|
||||
rtx pc_src = pc != NULL ? SET_SRC (pc) : NULL;
|
||||
|
||||
if (prev_nonjump_insn != NULL)
|
||||
label_note
|
||||
= find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL);
|
||||
|
||||
if (label_note != NULL && pc_src != NULL)
|
||||
{
|
||||
rtx label_set = single_set (prev_nonjump_insn);
|
||||
rtx label_dest
|
||||
= label_set != NULL ? SET_DEST (label_set) : NULL;
|
||||
rtx label_dest = label_set != NULL ? SET_DEST (label_set) : NULL;
|
||||
|
||||
if (label_set != NULL
|
||||
/* The source must be the direct LABEL_REF, not a
|
||||
|
@ -247,45 +233,53 @@ mark_all_labels (rtx f)
|
|||
&& (rtx_equal_p (label_dest, pc_src)
|
||||
|| (GET_CODE (pc_src) == IF_THEN_ELSE
|
||||
&& (rtx_equal_p (label_dest, XEXP (pc_src, 1))
|
||||
|| rtx_equal_p (label_dest,
|
||||
XEXP (pc_src, 2))))))
|
||||
|
||||
|| 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
|
||||
conveniently use it for the marker function, which
|
||||
requires a LABEL_REF wrapping. */
|
||||
gcc_assert (XEXP (label_note, 0)
|
||||
== XEXP (SET_SRC (label_set), 0));
|
||||
gcc_assert (XEXP (label_note, 0) == XEXP (SET_SRC (label_set), 0));
|
||||
|
||||
mark_jump_label_1 (label_set, insn, false, true);
|
||||
gcc_assert (JUMP_LABEL (insn)
|
||||
== XEXP (SET_SRC (label_set), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (! INSN_DELETED_P (insn))
|
||||
prev_nonjump_insn = insn;
|
||||
}
|
||||
else if (LABEL_P (insn))
|
||||
prev_nonjump_insn = NULL;
|
||||
mark_jump_label_1 (label_set, jump_insn, false, true);
|
||||
|
||||
gcc_assert (JUMP_LABEL (jump_insn) == XEXP (label_note, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the label each jump jumps to.
|
||||
Combine consecutive labels, and count uses of labels. */
|
||||
|
||||
static void
|
||||
mark_all_labels (rtx f)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
/* If we are in cfglayout mode, there may be non-insns between the
|
||||
basic blocks. If those non-insns represent tablejump data, they
|
||||
contain label references that we must record. */
|
||||
if (current_ir_type () == IR_RTL_CFGLAYOUT)
|
||||
{
|
||||
basic_block bb;
|
||||
rtx insn;
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
/* In cfglayout mode, we don't bother with trivial next-insn
|
||||
propagation of LABEL_REFs into JUMP_LABEL. This will be
|
||||
handled by other optimizers using better algorithms. */
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
gcc_assert (! INSN_DELETED_P (insn));
|
||||
if (NONDEBUG_INSN_P (insn))
|
||||
mark_jump_label (PATTERN (insn), insn, 0);
|
||||
}
|
||||
|
||||
/* In cfglayout mode, there may be non-insns between the
|
||||
basic blocks. If those non-insns represent tablejump data,
|
||||
they contain label references that we must record. */
|
||||
for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
gcc_assert (JUMP_TABLE_DATA_P (insn));
|
||||
mark_jump_label (PATTERN (insn), insn, 0);
|
||||
}
|
||||
|
||||
for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
|
@ -294,6 +288,28 @@ mark_all_labels (rtx f)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx prev_nonjump_insn = NULL;
|
||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (INSN_DELETED_P (insn))
|
||||
;
|
||||
else if (LABEL_P (insn))
|
||||
prev_nonjump_insn = NULL;
|
||||
else if (NONDEBUG_INSN_P (insn))
|
||||
{
|
||||
mark_jump_label (PATTERN (insn), insn, 0);
|
||||
if (JUMP_P (insn))
|
||||
{
|
||||
if (JUMP_LABEL (insn) == NULL && prev_nonjump_insn != NULL)
|
||||
maybe_propagate_label_ref (insn, prev_nonjump_insn);
|
||||
}
|
||||
else
|
||||
prev_nonjump_insn = insn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
|
||||
|
|
Loading…
Reference in New Issue