diff options
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/gcse.c | 22 | ||||
-rw-r--r-- | gcc/jump.c | 3 | ||||
-rw-r--r-- | gcc/reorg.c | 8 | ||||
-rw-r--r-- | gcc/rtlanal.c | 3 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 34 |
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 |