Commit 4f4b3679 by Richard Henderson Committed by Richard Henderson

combine.c (subst): Process the inputs to a parallel asm_operands only once.

        * combine.c (subst): Process the inputs to a parallel asm_operands
        only once.

From-SVN: r23357
parent 3fbd5c2c
Mon Oct 26 13:35:02 1998 Richard Henderson <rth@cygnus.com>
* combine.c (subst): Process the inputs to a parallel asm_operands
only once.
Mon Oct 26 13:32:31 1998 Richard Henderson <rth@cygnus.com>
* stmt.c (expand_asm_operands): Accept `=' or `+' at any position.
......
......@@ -3048,13 +3048,56 @@ subst (x, from, to, in_dest, unique_copy)
if (COMBINE_RTX_EQUAL_P (x, to))
return to;
/* Parallel asm_operands need special attention because all of the
inputs are shared across the arms. Furthermore, unsharing the
rtl results in recognition failures. Failure to handle this case
specially can result in circular rtl.
Solve this by doing a normal pass across the first entry of the
parallel, and only processing the SET_DESTs of the subsequent
entries. Ug. */
if (code == PARALLEL
&& GET_CODE (XVECEXP (x, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
{
new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
/* If this substitution failed, this whole thing fails. */
if (GET_CODE (new) == CLOBBER
&& XEXP (new, 0) == const0_rtx)
return new;
SUBST (XVECEXP (x, 0, 0), new);
for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
{
rtx dest = SET_DEST (XVECEXP (x, 0, i));
if (GET_CODE (dest) != REG
&& GET_CODE (dest) != CC0
&& GET_CODE (dest) != PC)
{
new = subst (dest, from, to, 0, unique_copy);
/* If this substitution failed, this whole thing fails. */
if (GET_CODE (new) == CLOBBER
&& XEXP (new, 0) == const0_rtx)
return new;
SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
}
}
}
else
{
len = GET_RTX_LENGTH (code);
fmt = GET_RTX_FORMAT (code);
/* We don't need to process a SET_DEST that is a register, CC0, or PC, so
set up to skip this common case. All other cases where we want to
suppress replacing something inside a SET_SRC are handled via the
IN_DEST operand. */
/* We don't need to process a SET_DEST that is a register, CC0,
or PC, so set up to skip this common case. All other cases
where we want to suppress replacing something inside a
SET_SRC are handled via the IN_DEST operand. */
if (code == SET
&& (GET_CODE (SET_DEST (x)) == REG
|| GET_CODE (SET_DEST (x)) == CC0
......@@ -3075,15 +3118,19 @@ subst (x, from, to, in_dest, unique_copy)
{
if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
{
new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
new = (unique_copy && n_occurrences
? copy_rtx (to) : to);
n_occurrences++;
}
else
{
new = subst (XVECEXP (x, i, j), from, to, 0, unique_copy);
new = subst (XVECEXP (x, i, j), from, to, 0,
unique_copy);
/* If this substitution failed, this whole thing fails. */
if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
/* If this substitution failed, this whole thing
fails. */
if (GET_CODE (new) == CLOBBER
&& XEXP (new, 0) == const0_rtx)
return new;
}
......@@ -3094,16 +3141,19 @@ subst (x, from, to, in_dest, unique_copy)
{
if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
{
/* In general, don't install a subreg involving two modes not
tieable. It can worsen register allocation, and can even
make invalid reload insns, since the reg inside may need to
be copied from in the outside mode, and that may be invalid
/* In general, don't install a subreg involving two
modes not tieable. It can worsen register
allocation, and can even make invalid reload
insns, since the reg inside may need to be copied
from in the outside mode, and that may be invalid
if it is an fp reg copied in integer mode.
We allow two exceptions to this: It is valid if it is inside
another SUBREG and the mode of that SUBREG and the mode of
the inside of TO is tieable and it is valid if X is a SET
that copies FROM to CC0. */
We allow two exceptions to this: It is valid if
it is inside another SUBREG and the mode of that
SUBREG and the mode of the inside of TO is
tieable and it is valid if X is a SET that copies
FROM to CC0. */
if (GET_CODE (to) == SUBREG
&& ! MODES_TIEABLE_P (GET_MODE (to),
GET_MODE (SUBREG_REG (to)))
......@@ -3147,6 +3197,7 @@ subst (x, from, to, in_dest, unique_copy)
SUBST (XEXP (x, i), new);
}
}
}
/* Try to simplify X. If the simplification changed the code, it is likely
that further simplification will help, so loop, but limit the number
......
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