diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1996-06-19 17:50:05 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1996-06-19 17:50:05 -0400 |
commit | 6eb12cef1d7793f3e598841a7b38067fa74b621e (patch) | |
tree | fde46b4cf5e0b0aa32aa6eb2510cc09148814520 /gcc/combine.c | |
parent | fbe912dd099f284e1db21de74ea40ad81e72c84e (diff) | |
download | gcc-6eb12cef1d7793f3e598841a7b38067fa74b621e.tar.gz |
(move_deaths): New parameter maybe_kill_insn.
Don't move note if reg killed by maybe_kill_insn.
(try_combine): Pass new arg to move_deaths.
From-SVN: r12311
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 3dbdb183e5d..25e87292861 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -440,7 +440,7 @@ static rtx get_last_value PROTO((rtx)); static int use_crosses_set_p PROTO((rtx, int)); static void reg_dead_at_p_1 PROTO((rtx, rtx)); static int reg_dead_at_p PROTO((rtx, rtx)); -static void move_deaths PROTO((rtx, int, rtx, rtx *)); +static void move_deaths PROTO((rtx, rtx, int, rtx, rtx *)); static int reg_bitfield_target_p PROTO((rtx, rtx)); static void distribute_notes PROTO((rtx, rtx, rtx, rtx, rtx, rtx)); static void distribute_links PROTO((rtx)); @@ -2204,11 +2204,18 @@ try_combine (i3, i2, i1) } /* Get death notes for everything that is now used in either I3 or - I2 and used to die in a previous insn. */ + I2 and used to die in a previous insn. If we built two new + patterns, move from I1 to I2 then I2 to I3 so that we get the + proper movement on registers that I2 modifies. */ - move_deaths (newpat, i1 ? INSN_CUID (i1) : INSN_CUID (i2), i3, &midnotes); if (newi2pat) - move_deaths (newi2pat, INSN_CUID (i1), i2, &midnotes); + { + move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes); + move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes); + } + else + move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2), + i3, &midnotes); /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ if (i3notes) @@ -10489,12 +10496,15 @@ remove_death (regno, insn) TO_INSN (exclusive), put a REG_DEAD note for that register in the list headed by PNOTES. + That said, don't move registers killed by maybe_kill_insn. + This is done when X is being merged by combination into TO_INSN. These notes will then be distributed as needed. */ static void -move_deaths (x, from_cuid, to_insn, pnotes) +move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes) rtx x; + rtx maybe_kill_insn; int from_cuid; rtx to_insn; rtx *pnotes; @@ -10509,6 +10519,11 @@ move_deaths (x, from_cuid, to_insn, pnotes) register rtx where_dead = reg_last_death[regno]; register rtx before_dead, after_dead; + /* Don't move the register if it gets killed in between from and to */ + if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn) + && !reg_referenced_p (x, maybe_kill_insn)) + return; + /* WHERE_DEAD could be a USE insn made by combine, so first we make sure that we have insns with valid INSN_CUID values. */ before_dead = where_dead; @@ -10566,7 +10581,7 @@ move_deaths (x, from_cuid, to_insn, pnotes) for (i = regno + 1; i < ourend; i++) move_deaths (gen_rtx (REG, reg_raw_mode[i], i), - from_cuid, to_insn, &oldnotes); + maybe_kill_insn, from_cuid, to_insn, &oldnotes); } if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x)) @@ -10587,7 +10602,7 @@ move_deaths (x, from_cuid, to_insn, pnotes) { rtx dest = SET_DEST (x); - move_deaths (SET_SRC (x), from_cuid, to_insn, pnotes); + move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes); /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG that accesses one word of a multi-word item, some @@ -10602,7 +10617,7 @@ move_deaths (x, from_cuid, to_insn, pnotes) == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))) { - move_deaths (dest, from_cuid, to_insn, pnotes); + move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes); return; } @@ -10616,7 +10631,8 @@ move_deaths (x, from_cuid, to_insn, pnotes) being replaced so the old value is not used in this insn. */ if (GET_CODE (dest) == MEM) - move_deaths (XEXP (dest, 0), from_cuid, to_insn, pnotes); + move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid, + to_insn, pnotes); return; } @@ -10632,10 +10648,11 @@ move_deaths (x, from_cuid, to_insn, pnotes) { register int j; for (j = XVECLEN (x, i) - 1; j >= 0; j--) - move_deaths (XVECEXP (x, i, j), from_cuid, to_insn, pnotes); + move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid, + to_insn, pnotes); } else if (fmt[i] == 'e') - move_deaths (XEXP (x, i), from_cuid, to_insn, pnotes); + move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes); } } |