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>
|
2011-07-22 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* dwarf2out.c (struct macinfo_struct): Change code to unsigned char.
|
* 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.
|
/* A subroutine of mark_all_labels. Trivially propagate a simple label
|
||||||
Combine consecutive labels, and count uses of labels. */
|
load into a jump_insn that uses it. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mark_all_labels (rtx f)
|
maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
|
||||||
{
|
{
|
||||||
rtx insn;
|
rtx label_note, pc, pc_src;
|
||||||
rtx prev_nonjump_insn = NULL;
|
|
||||||
|
|
||||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
pc = pc_set (jump_insn);
|
||||||
if (NONDEBUG_INSN_P (insn))
|
pc_src = pc != NULL ? SET_SRC (pc) : NULL;
|
||||||
{
|
label_note = find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL);
|
||||||
mark_jump_label (PATTERN (insn), insn, 0);
|
|
||||||
|
|
||||||
/* If the previous non-jump insn sets something to a label,
|
/* If the previous non-jump insn sets something to a label,
|
||||||
something that this jump insn uses, make that label the primary
|
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
|
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
|
may refer to the item being set only directly or as one of the
|
||||||
arms in an IF_THEN_ELSE. */
|
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)
|
if (label_note != NULL && pc_src != NULL)
|
||||||
{
|
{
|
||||||
rtx label_set = single_set (prev_nonjump_insn);
|
rtx label_set = single_set (prev_nonjump_insn);
|
||||||
rtx label_dest
|
rtx label_dest = label_set != NULL ? SET_DEST (label_set) : NULL;
|
||||||
= label_set != NULL ? SET_DEST (label_set) : NULL;
|
|
||||||
|
|
||||||
if (label_set != NULL
|
if (label_set != NULL
|
||||||
/* The source must be the direct LABEL_REF, not a
|
/* 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)
|
&& (rtx_equal_p (label_dest, pc_src)
|
||||||
|| (GET_CODE (pc_src) == IF_THEN_ELSE
|
|| (GET_CODE (pc_src) == IF_THEN_ELSE
|
||||||
&& (rtx_equal_p (label_dest, XEXP (pc_src, 1))
|
&& (rtx_equal_p (label_dest, XEXP (pc_src, 1))
|
||||||
|| rtx_equal_p (label_dest,
|
|| rtx_equal_p (label_dest, XEXP (pc_src, 2))))))
|
||||||
XEXP (pc_src, 2))))))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* The CODE_LABEL referred to in the note must be the
|
/* The CODE_LABEL referred to in the note must be the
|
||||||
CODE_LABEL in the LABEL_REF of the "set". We can
|
CODE_LABEL in the LABEL_REF of the "set". We can
|
||||||
conveniently use it for the marker function, which
|
conveniently use it for the marker function, which
|
||||||
requires a LABEL_REF wrapping. */
|
requires a LABEL_REF wrapping. */
|
||||||
gcc_assert (XEXP (label_note, 0)
|
gcc_assert (XEXP (label_note, 0) == XEXP (SET_SRC (label_set), 0));
|
||||||
== XEXP (SET_SRC (label_set), 0));
|
|
||||||
|
|
||||||
mark_jump_label_1 (label_set, insn, false, true);
|
mark_jump_label_1 (label_set, jump_insn, false, true);
|
||||||
gcc_assert (JUMP_LABEL (insn)
|
|
||||||
== XEXP (SET_SRC (label_set), 0));
|
gcc_assert (JUMP_LABEL (jump_insn) == XEXP (label_note, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (! INSN_DELETED_P (insn))
|
|
||||||
prev_nonjump_insn = insn;
|
/* Mark the label each jump jumps to.
|
||||||
}
|
Combine consecutive labels, and count uses of labels. */
|
||||||
else if (LABEL_P (insn))
|
|
||||||
prev_nonjump_insn = NULL;
|
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)
|
if (current_ir_type () == IR_RTL_CFGLAYOUT)
|
||||||
{
|
{
|
||||||
basic_block bb;
|
basic_block bb;
|
||||||
rtx insn;
|
|
||||||
FOR_EACH_BB (bb)
|
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))
|
for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
|
||||||
if (INSN_P (insn))
|
if (INSN_P (insn))
|
||||||
{
|
{
|
||||||
gcc_assert (JUMP_TABLE_DATA_P (insn));
|
gcc_assert (JUMP_TABLE_DATA_P (insn));
|
||||||
mark_jump_label (PATTERN (insn), insn, 0);
|
mark_jump_label (PATTERN (insn), insn, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
|
for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
|
||||||
if (INSN_P (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
|
/* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
|
||||||
|
|
Loading…
Reference in New Issue