(block_alloc): Generalize tying so we can tie any operand with the output unless some operand must be in the same register as the output...

(block_alloc): Generalize tying so we can tie any operand with the
output unless some operand must be in the same register as the output,
in which case only try tying that operand.

From-SVN: r3075
This commit is contained in:
Richard Kenner 1993-01-03 19:00:20 -05:00
parent 2151a093e3
commit 7aba0f0be5

View File

@ -1142,7 +1142,15 @@ block_alloc (b)
Suitable insns are those with at least two operands and where
operand 0 is an output that is a register that is not
earlyclobber.
For a commutative operation, try (set reg0 (arithop ... reg1)).
We can tie operand 0 with some operand that dies in this insn.
First look for operands that are required to be in the same
register as operand 0. If we find such, only try tying that
operand or one that can be put into that operand if the
operation is commutative. If we don't find an operand
that is required to be in the same register as operand 0,
we can tie with any operand.
Subregs in place of regs are also ok.
If tying is done, WIN is set nonzero. */
@ -1158,17 +1166,42 @@ block_alloc (b)
#endif
)
{
r0 = recog_operand[0];
r1 = recog_operand[1];
#ifdef REGISTER_CONSTRAINTS
int must_match_0 = -1;
/* If the first operand is an address, find a register in it.
There may be more than one register, but we only try one of
them. */
for (i = 1; i < insn_n_operands[insn_code_number]; i++)
if (requires_inout_p
(insn_operand_constraint[insn_code_number][i]))
must_match_0 = i;
#endif
r0 = recog_operand[0];
for (i = 1; i < insn_n_operands[insn_code_number]; i++)
{
#ifdef REGISTER_CONSTRAINTS
/* Skip this operand if we found an operand that
must match operand 0 and this operand isn't it
and can't be made to be it by commutativity. */
if (must_match_0 >= 0 && i != must_match_0
&& ! (i == must_match_0 + 1
&& insn_operand_constraint[insn_code_number][i-1][0] == '%')
&& ! (i == must_match_0 - 1
&& insn_operand_constraint[insn_code_number][i][0] == '%'))
continue;
#endif
r1 = recog_operand[i];
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
if (
#ifdef REGISTER_CONSTRAINTS
insn_operand_constraint[insn_code_number][1][0] == 'p'
insn_operand_constraint[insn_code_number][i][0] == 'p'
#else
insn_operand_address_p[insn_code_number][1]
insn_operand_address_p[insn_code_number][i]
#endif
)
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
@ -1177,37 +1210,20 @@ block_alloc (b)
if (GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG)
{
/* We have two priorities for hard register preferences.
If we have a move insn or an insn whose first input can
only be in the same register as the output, give
If we have a move insn or an insn whose first input
can only be in the same register as the output, give
priority to an equivalence found from that insn. */
#ifdef REGISTER_CONSTRAINTS
int may_save_copy
= ((SET_DEST (body) == r0 && SET_SRC (body) == r1)
|| (r1 == recog_operand[1]
&& (requires_inout_p (insn_operand_constraint[insn_code_number][1]))));
#else
int may_save_copy = 0;
#ifdef REGISTER_CONSTRAINTS
|| (r1 == recog_operand[i] && must_match_0 >= 0)
#endif
);
if (GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG)
win = combine_regs (r1, r0, may_save_copy,
insn_number, insn, 0);
if (win == 0
&& insn_n_operands[insn_code_number] > 2
#ifdef REGISTER_CONSTRAINTS
&& insn_operand_constraint[insn_code_number][1][0] == '%'
#else
&& GET_CODE (PATTERN (insn)) == SET
&& (GET_RTX_CLASS (GET_CODE (SET_SRC (PATTERN (insn))))
== 'c')
&& rtx_equal_p (recog_operand[2],
XEXP (SET_SRC (PATTERN (insn)), 0))
#endif
&& (r1 = recog_operand[2],
GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG))
win = combine_regs (r1, r0, may_save_copy,
insn_number, insn, 0);
}
}
}