diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1993-01-03 19:00:20 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1993-01-03 19:00:20 -0500 |
commit | 7aba0f0be51554e0fbd8d93f22c0a90c59498c3b (patch) | |
tree | e7912d819891a73c74c38bc664f9e122f6df7e2e | |
parent | 2151a093e30b2d7b1122924810d0427b8a438ca9 (diff) | |
download | gcc-7aba0f0be51554e0fbd8d93f22c0a90c59498c3b.zip gcc-7aba0f0be51554e0fbd8d93f22c0a90c59498c3b.tar.gz gcc-7aba0f0be51554e0fbd8d93f22c0a90c59498c3b.tar.bz2 |
(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
-rw-r--r-- | gcc/local-alloc.c | 96 |
1 files changed, 56 insertions, 40 deletions
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 7cdd050..3b892c6 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -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,56 +1166,64 @@ block_alloc (b) #endif ) { - r0 = recog_operand[0]; - r1 = recog_operand[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. */ - if ( #ifdef REGISTER_CONSTRAINTS - insn_operand_constraint[insn_code_number][1][0] == 'p' -#else - insn_operand_address_p[insn_code_number][1] + int must_match_0 = -1; + + + 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 - ) - while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT) - r1 = XEXP (r1, 0); - if (GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG) + r0 = recog_operand[0]; + for (i = 1; i < insn_n_operands[insn_code_number]; i++) { - /* 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 - 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; + /* 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 - if (GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG) - win = combine_regs (r1, r0, may_save_copy, - insn_number, insn, 0); + r1 = recog_operand[i]; - if (win == 0 - && insn_n_operands[insn_code_number] > 2 + /* 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] == '%' + insn_operand_constraint[insn_code_number][i][0] == 'p' #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)) + insn_operand_address_p[insn_code_number][i] #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); + ) + while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT) + r1 = XEXP (r1, 0); + + 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 + priority to an equivalence found from that insn. */ + int may_save_copy + = ((SET_DEST (body) == r0 && SET_SRC (body) == r1) +#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); + } } } |