aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-03-30 15:37:29 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1993-03-30 15:37:29 -0500
commitdbc131f3ccb06fb898a095ef11289cb56ddc62e4 (patch)
tree2af6a2f6e28835fec0aaf60d278e356d12d9ae5f /gcc
parent99309f3bcbb8cd7d7504a89b32588d301609bf9e (diff)
downloadgcc-dbc131f3ccb06fb898a095ef11289cb56ddc62e4.zip
gcc-dbc131f3ccb06fb898a095ef11289cb56ddc62e4.tar.gz
gcc-dbc131f3ccb06fb898a095ef11289cb56ddc62e4.tar.bz2
(record_dead_and_set_regs): Record death of all hard regs when a multi-reg object in hard regs dies.
(record_dead_and_set_regs): Record death of all hard regs when a multi-reg object in hard regs dies. (move_deaths): Handle the case when we only have to move part of a multi-register death note. From-SVN: r3930
Diffstat (limited to 'gcc')
-rw-r--r--gcc/combine.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 631158d..92fa365 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8875,8 +8875,19 @@ record_dead_and_set_regs (insn)
register rtx link;
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
- if (REG_NOTE_KIND (link) == REG_DEAD)
- reg_last_death[REGNO (XEXP (link, 0))] = insn;
+ if (REG_NOTE_KIND (link) == REG_DEAD
+ && GET_CODE (XEXP (link, 0)) == REG)
+ {
+ int regno = REGNO (XEXP (link, 0));
+ int endregno
+ = regno + (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
+ : 1);
+ int i;
+
+ for (i = regno; i < endregno; i++)
+ reg_last_death[i] = insn;
+ }
else if (REG_NOTE_KIND (link) == REG_INC)
record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
}
@@ -9204,13 +9215,37 @@ move_deaths (x, from_cuid, to_insn, pnotes)
if (where_dead && INSN_CUID (where_dead) >= from_cuid
&& INSN_CUID (where_dead) < INSN_CUID (to_insn))
{
- rtx note = remove_death (regno, reg_last_death[regno]);
+ rtx note = remove_death (regno, where_dead);
/* It is possible for the call above to return 0. This can occur
when reg_last_death points to I2 or I1 that we combined with.
- In that case make a new note. */
+ In that case make a new note.
+
+ We must also check for the case where X is a hard register
+ and NOTE is a death note for a range of hard registers
+ including X. In that case, we must put REG_DEAD notes for
+ the remaining registers in place of NOTE. */
+
+ if (note != 0 && regno < FIRST_PSEUDO_REGISTER
+ && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
+ != GET_MODE_SIZE (GET_MODE (x))))
+ {
+ int deadregno = REGNO (XEXP (note, 0));
+ int deadend
+ = (deadregno + HARD_REGNO_NREGS (deadregno,
+ GET_MODE (XEXP (note, 0))));
+ int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ int i;
+
+ for (i = deadregno; i < deadend; i++)
+ if (i < regno || i >= ourend)
+ REG_NOTES (where_dead)
+ = gen_rtx (EXPR_LIST, REG_DEAD,
+ gen_rtx (REG, word_mode, i),
+ REG_NOTES (where_dead));
+ }
- if (note)
+ if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
{
XEXP (note, 1) = *pnotes;
*pnotes = note;