summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/gcse.c22
-rw-r--r--gcc/jump.c3
-rw-r--r--gcc/reorg.c8
-rw-r--r--gcc/rtlanal.c3
-rw-r--r--gcc/sched-rgn.c34
6 files changed, 64 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c34686d782..670c0ac04e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2007-11-24 Hans-Peter Nilsson <hp@axis.com>
+
+ * rtlanal.c (label_is_jump_target_p): Return true for a matching
+ REG_LABEL_TARGET.
+ * reorg.c (fill_slots_from_thread): Correct last change to use
+ NULL_RTX, not NULL. Outside of REG_NOTES loop, increase and
+ decrease LABEL_NUSES for JUMP_LABEL (trial), not XEXP (note, 0).
+ * jump.c (mark_jump_label_1): Add comment for last change
+ regarding JUMP_LABEL setting.
+ * gcse.c (add_label_notes): Remove conditional that the label is
+ mentioned in insn before adding regnote.
+ * sched-rgn.c (is_cfg_nonregular): Don't return 1 for a
+ single_set insn only feeding a label to a jump through a
+ register that dies there.
+
2007-11-23 Dirk Mueller <dmueller@suse.de>
Richard Guenther <rguenther@suse.de>
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 84c0994753d..db7e03c03d9 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -4614,18 +4614,16 @@ add_label_notes (rtx x, rtx insn)
We no longer ignore such label references (see LABEL_REF handling in
mark_jump_label for additional information). */
- if (reg_mentioned_p (XEXP (x, 0), insn))
- {
- /* There's no reason for current users to emit jump-insns
- with such a LABEL_REF, so we don't have to handle
- REG_LABEL_TARGET notes. */
- gcc_assert (!JUMP_P (insn));
- REG_NOTES (insn)
- = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, XEXP (x, 0),
- REG_NOTES (insn));
- if (LABEL_P (XEXP (x, 0)))
- LABEL_NUSES (XEXP (x, 0))++;
- }
+ /* There's no reason for current users to emit jump-insns with
+ such a LABEL_REF, so we don't have to handle REG_LABEL_TARGET
+ notes. */
+ gcc_assert (!JUMP_P (insn));
+ REG_NOTES (insn)
+ = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, XEXP (x, 0),
+ REG_NOTES (insn));
+ if (LABEL_P (XEXP (x, 0)))
+ LABEL_NUSES (XEXP (x, 0))++;
+
return;
}
diff --git a/gcc/jump.c b/gcc/jump.c
index e17f1488620..4564cd105ce 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -1051,6 +1051,9 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
if (insn)
{
if (is_target
+ /* Do not change a previous setting of JUMP_LABEL. If the
+ JUMP_LABEL slot is occupied by a different label,
+ create a note for this label. */
&& (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
JUMP_LABEL (insn) = label;
else
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 51acaa3d2af..985c118bc8c 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -2740,7 +2740,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
temporarily increment the use count on any referenced
label lest it be deleted by delete_related_insns. */
for (note = REG_NOTES (trial);
- note != NULL;
+ note != NULL_RTX;
note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
|| REG_NOTE_KIND (note) == REG_LABEL_TARGET)
@@ -2754,12 +2754,12 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
== REG_LABEL_OPERAND);
}
if (JUMP_P (trial) && JUMP_LABEL (trial))
- LABEL_NUSES (XEXP (note, 0))++;
+ LABEL_NUSES (JUMP_LABEL (trial))++;
delete_related_insns (trial);
for (note = REG_NOTES (trial);
- note != NULL;
+ note != NULL_RTX;
note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
|| REG_NOTE_KIND (note) == REG_LABEL_TARGET)
@@ -2773,7 +2773,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
== REG_LABEL_OPERAND);
}
if (JUMP_P (trial) && JUMP_LABEL (trial))
- LABEL_NUSES (XEXP (note, 0))--;
+ LABEL_NUSES (JUMP_LABEL (trial))--;
}
else
new_thread = next_active_insn (trial);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 0e0f7e3dfbb..d9e60d3b1ab 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3434,6 +3434,9 @@ label_is_jump_target_p (const_rtx label, const_rtx jump_insn)
return true;
}
+ if (find_reg_note (jump_insn, REG_LABEL_TARGET, label))
+ return true;
+
return false;
}
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 12f2e66832b..b340bd532e4 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -320,16 +320,40 @@ is_cfg_nonregular (void)
FOR_EACH_BB (b)
FOR_BB_INSNS (b, insn)
{
- /* Check for labels referred to but (at least not directly) as
- jump targets. */
- if (INSN_P (insn)
- && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
- return 1;
+ rtx note, next, set, dest;
/* If this function has a computed jump, then we consider the cfg
not well structured. */
if (JUMP_P (insn) && computed_jump_p (insn))
return 1;
+
+ if (!INSN_P (insn))
+ continue;
+
+ note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX);
+ if (note == NULL_RTX)
+ continue;
+
+ /* For that label not to be seen as a referred-to label, this
+ must be a single-set which is feeding a jump *only*. This
+ could be a conditional jump with the label split off for
+ machine-specific reasons or a casesi/tablejump. */
+ next = next_nonnote_insn (insn);
+ if (next == NULL_RTX
+ || !JUMP_P (next)
+ || (JUMP_LABEL (next) != XEXP (note, 0)
+ && find_reg_note (next, REG_LABEL_TARGET,
+ XEXP (note, 0)) == NULL_RTX)
+ || BLOCK_FOR_INSN (insn) != BLOCK_FOR_INSN (next))
+ return 1;
+
+ set = single_set (insn);
+ if (set == NULL_RTX)
+ return 1;
+
+ dest = SET_DEST (set);
+ if (!REG_P (dest) || !dead_or_set_p (next, dest))
+ return 1;
}
/* Unreachable loops with more than one basic block are detected