mirror of
https://git.FreeBSD.org/ports.git
synced 2024-11-01 22:05:08 +00:00
155 lines
5.2 KiB
C
155 lines
5.2 KiB
C
--- combine.c.orig Sun Nov 26 11:32:07 1995
|
||
+++ combine.c Mon Mar 20 13:29:10 2000
|
||
@@ -440,7 +440,7 @@
|
||
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));
|
||
@@ -2077,8 +2077,38 @@
|
||
undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
|
||
}
|
||
|
||
- /* We now know that we can do this combination. Merge the insns and
|
||
- update the status of registers and LOG_LINKS. */
|
||
+ /* We now know that we can do this combination. */
|
||
+
|
||
+ /* Earlier we did all the checks required to determine if we could
|
||
+ logically combine three insns into one. Then we determined that
|
||
+ the machine description would not let us do it in one, but would
|
||
+ let us do it in two. Thus when generating two insns, they must,
|
||
+ in general, be adjacent -- one logical instruction if you will.
|
||
+
|
||
+ We could be complicated and figure out some rules that would allow
|
||
+ us to not move the insn, but it seems likely that the scheduler will
|
||
+ do as good with no muss. */
|
||
+
|
||
+ if (newi2pat && NEXT_INSN (i2) != i3)
|
||
+ {
|
||
+ rtx n = NEXT_INSN(i2);
|
||
+ int c = INSN_CUID(i2);
|
||
+
|
||
+ /* Move the instruction */
|
||
+ reorder_insns(i2, i2, PREV_INSN (i3));
|
||
+
|
||
+ /* Update the CUID map */
|
||
+ while (1)
|
||
+ {
|
||
+ uid_cuid[INSN_UID (n)] = c;
|
||
+ if (n == i2)
|
||
+ break;
|
||
+ n = NEXT_INSN(n);
|
||
+ ++c;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /* Merge the insns and update the status of registers and LOG_LINKS. */
|
||
|
||
{
|
||
rtx i3notes, i2notes, i1notes = 0;
|
||
@@ -2186,11 +2216,18 @@
|
||
}
|
||
|
||
/* 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)
|
||
@@ -10372,12 +10409,15 @@
|
||
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;
|
||
@@ -10392,6 +10432,11 @@
|
||
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;
|
||
@@ -10449,7 +10494,7 @@
|
||
|
||
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))
|
||
@@ -10470,7 +10515,7 @@
|
||
{
|
||
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
|
||
@@ -10485,7 +10530,7 @@
|
||
== ((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;
|
||
}
|
||
|
||
@@ -10499,7 +10544,8 @@
|
||
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;
|
||
}
|
||
|
||
@@ -10515,10 +10561,11 @@
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|