Commit 56b7c17e by Jim Wilson

(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
parent 51f0e748
...@@ -2508,12 +2508,19 @@ static void ...@@ -2508,12 +2508,19 @@ static void
create_reg_dead_note (reg, insn) create_reg_dead_note (reg, insn)
rtx reg, insn; rtx reg, insn;
{ {
rtx link = dead_notes; rtx link, backlink;
if (link == 0) /* The number of registers killed after scheduling must be the same as the
/* In theory, we should not end up with more REG_DEAD reg notes than we number of registers killed before scheduling. The number of REG_DEAD
started with. In practice, this can occur as the result of bugs in notes may not be conserved, i.e. two SImode hard register REG_DEAD notes
flow, combine and/or sched. */ 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 #if 1
abort (); abort ();
...@@ -2523,7 +2530,40 @@ create_reg_dead_note (reg, insn) ...@@ -2523,7 +2530,40 @@ create_reg_dead_note (reg, insn)
#endif #endif
} }
else 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, 0) = reg;
XEXP (link, 1) = REG_NOTES (insn); XEXP (link, 1) = REG_NOTES (insn);
...@@ -3654,7 +3694,7 @@ schedule_block (b, file) ...@@ -3654,7 +3694,7 @@ schedule_block (b, file)
head = note_head; 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, 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 and/or sched.c. The values of the REG_DEAD notes remaining are
meaningless, because dead_notes is just used as a free list. */ meaningless, because dead_notes is just used as a free list. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment