Commit 176c9e6b by Jim Wilson

(try_combine): New variable i3_subst_into_i2.

Set it for special case of substituting i3 into i2.  Use it near
end to detect when special case succeeded.  Move i2notes to
i3notes for this special case.
(distribute_notes, REG_UNUSED case): Ignore all REG_UNUSED notes
except those from I3.

From-SVN: r5639
parent f8ece317
...@@ -1152,6 +1152,8 @@ try_combine (i3, i2, i1) ...@@ -1152,6 +1152,8 @@ try_combine (i3, i2, i1)
int i1_feeds_i3 = 0; int i1_feeds_i3 = 0;
/* Notes that must be added to REG_NOTES in I3 and I2. */ /* Notes that must be added to REG_NOTES in I3 and I2. */
rtx new_i3_notes, new_i2_notes; rtx new_i3_notes, new_i2_notes;
/* Notes that we substituted I3 into I2 instead of the normal case. */
int i3_subst_into_i2 = 0;
int maxreg; int maxreg;
rtx temp; rtx temp;
...@@ -1254,6 +1256,7 @@ try_combine (i3, i2, i1) ...@@ -1254,6 +1256,7 @@ try_combine (i3, i2, i1)
SET_DEST (PATTERN (i3))); SET_DEST (PATTERN (i3)));
newpat = p2; newpat = p2;
i3_subst_into_i2 = 1;
goto validate_replacement; goto validate_replacement;
} }
} }
...@@ -2040,22 +2043,39 @@ try_combine (i3, i2, i1) ...@@ -2040,22 +2043,39 @@ try_combine (i3, i2, i1)
/* We had one special case above where I2 had more than one set and /* We had one special case above where I2 had more than one set and
we replaced a destination of one of those sets with the destination we replaced a destination of one of those sets with the destination
of I3. In that case, we have to update LOG_LINKS of insns later of I3. In that case, we have to update LOG_LINKS of insns later
in this basic block. Note that this (expensive) case is rare. */ in this basic block. Note that this (expensive) case is rare.
if (GET_CODE (PATTERN (i2)) == PARALLEL) Also, in this case, we must pretend that all REG_NOTEs for I2
for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++) actually came from I3, so that REG_UNUSED notes from I2 will be
if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG properly handled. */
&& SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
&& ! find_reg_note (i2, REG_UNUSED, if (i3_subst_into_i2)
SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) {
for (temp = NEXT_INSN (i2); for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
temp && (this_basic_block == n_basic_blocks - 1 if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG
|| basic_block_head[this_basic_block] != temp); && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
temp = NEXT_INSN (temp)) && ! find_reg_note (i2, REG_UNUSED,
if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i') SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
for (link = LOG_LINKS (temp); link; link = XEXP (link, 1)) for (temp = NEXT_INSN (i2);
if (XEXP (link, 0) == i2) temp && (this_basic_block == n_basic_blocks - 1
XEXP (link, 0) = i3; || basic_block_head[this_basic_block] != temp);
temp = NEXT_INSN (temp))
if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i')
for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
if (XEXP (link, 0) == i2)
XEXP (link, 0) = i3;
if (i3notes)
{
rtx link = i3notes;
while (XEXP (link, 1))
link = XEXP (link, 1);
XEXP (link, 1) = i2notes;
}
else
i3notes = i2notes;
i2notes = 0;
}
LOG_LINKS (i3) = 0; LOG_LINKS (i3) = 0;
REG_NOTES (i3) = 0; REG_NOTES (i3) = 0;
...@@ -9857,9 +9877,26 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) ...@@ -9857,9 +9877,26 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
switch (REG_NOTE_KIND (note)) switch (REG_NOTE_KIND (note))
{ {
case REG_UNUSED: case REG_UNUSED:
/* If this note is from any insn other than i3, then we have no
use for it, and must ignore it.
Any clobbers for i3 may still exist, and so we must process
REG_UNUSED notes from that insn.
Any clobbers from i2 or i1 can only exist if they were added by
recog_for_combine. In that case, recog_for_combine created the
necessary REG_UNUSED notes. Trying to keep any original
REG_UNUSED notes from these insns can cause incorrect output
if it is for the same register as the original i3 dest.
In that case, we will notice that the register is set in i3,
and then add a REG_UNUSED note for the destination of i3, which
is wrong. */
if (from_insn != i3)
break;
/* If this register is set or clobbered in I3, put the note there /* If this register is set or clobbered in I3, put the note there
unless there is one already. */ unless there is one already. */
if (reg_set_p (XEXP (note, 0), PATTERN (i3))) else if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
{ {
if (! (GET_CODE (XEXP (note, 0)) == REG if (! (GET_CODE (XEXP (note, 0)) == REG
? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0))) ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
......
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