aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1993-04-25 14:24:15 -0700
committerJim Wilson <wilson@gcc.gnu.org>1993-04-25 14:24:15 -0700
commit56b7c17e4966ca659a04153a62427eaf8895e3ad (patch)
treec3e074bef046c62bc6d26b8966e0ffb947006e77 /gcc
parent51f0e748faaeb6f31deb2a8c38dd2b235fbdb137 (diff)
downloadgcc-56b7c17e4966ca659a04153a62427eaf8895e3ad.zip
gcc-56b7c17e4966ca659a04153a62427eaf8895e3ad.tar.gz
gcc-56b7c17e4966ca659a04153a62427eaf8895e3ad.tar.bz2
(create_reg_dead_note): Rewrite so as to conserve registers killed not number of REG_DEAD notes.
(create_reg_dead_note): Rewrite so as to conserve registers killed not number of REG_DEAD notes. (schedule_block): Change comments about dead_notes variable. From-SVN: r4222
Diffstat (limited to 'gcc')
-rw-r--r--gcc/sched.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/gcc/sched.c b/gcc/sched.c
index 69fc5dd..434f768 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -2508,12 +2508,19 @@ static void
create_reg_dead_note (reg, insn)
rtx reg, insn;
{
- rtx link = dead_notes;
+ rtx link, backlink;
- if (link == 0)
- /* In theory, we should not end up with more REG_DEAD reg notes than we
- started with. In practice, this can occur as the result of bugs in
- flow, combine and/or sched. */
+ /* The number of registers killed after scheduling must be the same as the
+ number of registers killed before scheduling. The number of REG_DEAD
+ notes may not be conserved, i.e. two SImode hard register REG_DEAD notes
+ might become one DImode hard register REG_DEAD note, but the number of
+ registers killed will be conserved.
+
+ We carefully remove REG_DEAD notes from the dead_notes list, so that
+ there will be none left at the end. If we run out early, then there
+ is a bug somewhere in flow, combine and/or sched. */
+
+ if (dead_notes == 0)
{
#if 1
abort ();
@@ -2523,7 +2530,40 @@ create_reg_dead_note (reg, insn)
#endif
}
else
- dead_notes = XEXP (dead_notes, 1);
+ {
+ /* Number of regs killed by REG. */
+ int regs_killed = (REGNO (reg) >= FIRST_PSEUDO_REGISTER ? 1
+ : HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)));
+ /* Number of regs killed by REG_DEAD notes taken off the list. */
+ int reg_note_regs;
+
+ link = dead_notes;
+ reg_note_regs = (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
+ : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
+ GET_MODE (XEXP (link, 0))));
+ while (reg_note_regs < regs_killed)
+ {
+ link = XEXP (link, 1);
+ reg_note_regs += (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
+ : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
+ GET_MODE (XEXP (link, 0))));
+ }
+ dead_notes = XEXP (link, 1);
+
+ /* If we took too many regs kills off, put the extra ones back. */
+ while (reg_note_regs > regs_killed)
+ {
+ rtx temp_reg, temp_link;
+
+ temp_reg = gen_rtx (REG, word_mode, 0);
+ temp_link = rtx_alloc (EXPR_LIST);
+ PUT_REG_NOTE_KIND (temp_link, REG_DEAD);
+ XEXP (temp_link, 0) = temp_reg;
+ XEXP (temp_link, 1) = dead_notes;
+ dead_notes = temp_link;
+ reg_note_regs--;
+ }
+ }
XEXP (link, 0) = reg;
XEXP (link, 1) = REG_NOTES (insn);
@@ -3654,7 +3694,7 @@ schedule_block (b, file)
head = note_head;
}
- /* In theory, there should be no REG_DEAD notes leftover at the end.
+ /* There should be no REG_DEAD notes leftover at the end.
In practice, this can occur as the result of bugs in flow, combine.c,
and/or sched.c. The values of the REG_DEAD notes remaining are
meaningless, because dead_notes is just used as a free list. */