From: Richard Kenner Date: Tue, 14 Jun 1994 21:37:25 +0000 (-0400) Subject: (reload): Process and accumulate needs for RELOAD_FOR_OPADDR_ADDR reloads. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=893bc853685bc2cb3c3b3394c0abf78c695c8df1;p=gcc.git (reload): Process and accumulate needs for RELOAD_FOR_OPADDR_ADDR reloads. When determining if needs are nongroup needs, ignore inactive or optional reloads. (reload_reg_used_in_op_addr_reload): New variable to indicate when reloads of class RELOAD_FOR_OPADDR_ADDR are in use. (mark_reload_reg_in_use, clear_reload_reg_in_use): Process reloads of class RELOAD_FOR_OPADDR_ADDR. (reload_reg_free_p, reload_reg_free_before_p, reloads_conflict): Likewise. (choose_reload_regs): Support RELOAD_FOR_OPADDR_ADDR reloads. (emit_reload_insns): Output RELOAD_FOR_OPADDR_ADDR reloads. From-SVN: r7462 --- diff --git a/gcc/reload1.c b/gcc/reload1.c index 10afe98bb56..d32e91fc313 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -945,6 +945,7 @@ reload (first, global, dumpfile) struct needs insn; struct needs other_addr; struct needs op_addr; + struct needs op_addr_reload; struct needs in_addr[MAX_RECOG_OPERANDS]; struct needs out_addr[MAX_RECOG_OPERANDS]; } insn_needs; @@ -1073,6 +1074,9 @@ reload (first, global, dumpfile) ? reload_outmode[j] : reload_inmode[j]) > 1) + && (!reload_optional[j]) + && (reload_in[j] != 0 || reload_out[j] != 0 + || reload_secondary_p[j]) && reloads_conflict (i, j) && reg_classes_intersect_p (class, reload_reg_class[j])) @@ -1108,6 +1112,9 @@ reload (first, global, dumpfile) case RELOAD_FOR_OPERAND_ADDRESS: this_needs = &insn_needs.op_addr; break; + case RELOAD_FOR_OPADDR_ADDR: + this_needs = &insn_needs.op_addr_reload; + break; } if (size > 1) @@ -1184,7 +1191,10 @@ reload (first, global, dumpfile) don't conflict with things needed to reload inputs or outputs. */ - in_max = MAX (in_max, insn_needs.op_addr.regs[j][i]); + in_max = MAX (MAX (insn_needs.op_addr.regs[j][i], + insn_needs.op_addr_reload.regs[j][i]), + in_max); + out_max = MAX (out_max, insn_needs.insn.regs[j][i]); insn_needs.input.regs[j][i] @@ -1210,7 +1220,9 @@ reload (first, global, dumpfile) = MAX (out_max, insn_needs.out_addr[j].groups[i]); } - in_max = MAX (in_max, insn_needs.op_addr.groups[i]); + in_max = MAX (MAX (insn_needs.op_addr.groups[i], + insn_needs.op_addr_reload.groups[i]), + in_max); out_max = MAX (out_max, insn_needs.insn.groups[i]); insn_needs.input.groups[i] @@ -3106,6 +3118,8 @@ eliminate_regs_in_insn (insn, replace) { rtx old_body = PATTERN (insn); rtx new_body; + rtx old_set; + rtx new_set; int val = 0; struct elim_table *ep; @@ -3176,6 +3190,12 @@ eliminate_regs_in_insn (insn, replace) new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX); if (new_body != old_body) { + old_set = (GET_CODE (old_body) == PARALLEL) ? single_set (insn) : + old_body; + + new_set = (GET_CODE (new_body) == PARALLEL) ? XVECEXP(new_body,0,0) : + new_body; + /* If we aren't replacing things permanently and we changed something, make another copy to ensure that all the RTL is new. Otherwise things can go wrong if find_reload swaps commutative operands @@ -3187,22 +3207,25 @@ eliminate_regs_in_insn (insn, replace) new_body = copy_rtx (new_body); /* If we had a move insn but now we don't, rerecognize it. */ - if ((GET_CODE (old_body) == SET && GET_CODE (SET_SRC (old_body)) == REG - && (GET_CODE (new_body) != SET - || GET_CODE (SET_SRC (new_body)) != REG)) + if ((GET_CODE (old_set) == SET && GET_CODE (SET_SRC (old_set)) == REG + && (GET_CODE (new_set) != SET + || GET_CODE (SET_SRC (new_set)) != REG)) /* If this was a load from or store to memory, compare the MEM in recog_operand to the one in the insn. If they are not equal, then rerecognize the insn. */ - || (GET_CODE (old_body) == SET - && ((GET_CODE (SET_SRC (old_body)) == MEM - && SET_SRC (old_body) != recog_operand[1]) - || (GET_CODE (SET_DEST (old_body)) == MEM - && SET_DEST (old_body) != recog_operand[0]))) + || (GET_CODE (old_set) == SET + && ((GET_CODE (SET_SRC (old_set)) == MEM + && SET_SRC (old_set) != recog_operand[1]) + || (GET_CODE (SET_DEST (old_set)) == MEM + && SET_DEST (old_set) != recog_operand[0]))) /* If this was an add insn before, rerecognize. */ || - (GET_CODE (old_body) == SET - && GET_CODE (SET_SRC (old_body)) == PLUS)) + (GET_CODE (old_set) == SET + && GET_CODE (SET_SRC (old_set)) == PLUS)) { + if (!replace) + PATTERN (insn) = copy_rtx (PATTERN (insn)); + if (! validate_change (insn, &PATTERN (insn), new_body, 0)) /* If recognition fails, store the new body anyway. It's normal to have recognition failures here @@ -3993,6 +4016,8 @@ static HARD_REG_SET reload_reg_used_in_input[MAX_RECOG_OPERANDS]; static HARD_REG_SET reload_reg_used_in_output[MAX_RECOG_OPERANDS]; /* If reg is in use for a RELOAD_FOR_OPERAND_ADDRESS reload. */ static HARD_REG_SET reload_reg_used_in_op_addr; +/* If reg is in use for a RELOAD_FOR_OPADDR_ADDR reload. */ +static HARD_REG_SET reload_reg_used_in_op_addr_reload; /* If reg is in use for a RELOAD_FOR_INSN reload. */ static HARD_REG_SET reload_reg_used_in_insn; /* If reg is in use for a RELOAD_FOR_OTHER_ADDRESS reload. */ @@ -4039,6 +4064,10 @@ mark_reload_reg_in_use (regno, opnum, type, mode) SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i); break; + case RELOAD_FOR_OPADDR_ADDR: + SET_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, i); + break; + case RELOAD_FOR_OTHER_ADDRESS: SET_HARD_REG_BIT (reload_reg_used_in_other_addr, i); break; @@ -4092,6 +4121,10 @@ clear_reload_reg_in_use (regno, opnum, type, mode) CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr, i); break; + case RELOAD_FOR_OPADDR_ADDR: + CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, i); + break; + case RELOAD_FOR_OTHER_ADDRESS: CLEAR_HARD_REG_BIT (reload_reg_used_in_other_addr, i); break; @@ -4142,6 +4175,9 @@ reload_reg_free_p (regno, opnum, type) || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)) return 0; + if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)) + return 0; + /* If it is used for some other input, can't use it. */ for (i = 0; i < reload_n_operands; i++) if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) @@ -4186,6 +4222,13 @@ reload_reg_free_p (regno, opnum, type) return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)); + case RELOAD_FOR_OPADDR_ADDR: + for (i = 0; i < reload_n_operands; i++) + if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) + return 0; + + return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)); + case RELOAD_FOR_OUTPUT: /* This cannot share a register with RELOAD_FOR_INSN reloads, other outputs, or an operand address for this or an earlier output. */ @@ -4294,6 +4337,7 @@ reload_reg_free_before_p (regno, opnum, type) return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno); case RELOAD_FOR_OPERAND_ADDRESS: + case RELOAD_FOR_OPADDR_ADDR: case RELOAD_FOR_INSN: /* These can't conflict with inputs, or each other, so all we have to test is input addresses and the addresses of OTHER items. */ @@ -4389,6 +4433,9 @@ reload_reg_reaches_end_p (regno, opnum, type) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) return 0; + if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)) + return 0; + return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)); @@ -4415,8 +4462,17 @@ reload_reg_reaches_end_p (regno, opnum, type) return 1; + case RELOAD_FOR_OPADDR_ADDR: + for (i = 0; i < reload_n_operands; i++) + if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) + || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) + return 0; + + return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) + && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)); + case RELOAD_FOR_INSN: - /* These conflict with other outputs with with RELOAD_OTHER. So + /* These conflict with other outputs with RELOAD_OTHER. So we need only check for output addresses. */ opnum = -1; @@ -4465,6 +4521,7 @@ reloads_conflict (r1, r2) case RELOAD_FOR_INPUT: return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OPERAND_ADDRESS + || r2_type == RELOAD_FOR_OPADDR_ADDR || r2_type == RELOAD_FOR_INPUT || (r2_type == RELOAD_FOR_INPUT_ADDRESS && r2_opnum > r1_opnum)); @@ -4480,6 +4537,10 @@ reloads_conflict (r1, r2) return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OPERAND_ADDRESS); + case RELOAD_FOR_OPADDR_ADDR: + return (r2_type == RELOAD_FOR_INPUT + || r2_type == RELOAD_FOR_OPADDR_ADDR); + case RELOAD_FOR_OUTPUT: return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT || (r2_type == RELOAD_FOR_OUTPUT_ADDRESS @@ -4750,6 +4811,7 @@ choose_reload_regs (insn, avoid_return_reg) HARD_REG_SET save_reload_reg_used_in_input[MAX_RECOG_OPERANDS]; HARD_REG_SET save_reload_reg_used_in_output[MAX_RECOG_OPERANDS]; HARD_REG_SET save_reload_reg_used_in_op_addr; + HARD_REG_SET save_reload_reg_used_in_op_addr_reload; HARD_REG_SET save_reload_reg_used_in_insn; HARD_REG_SET save_reload_reg_used_in_other_addr; HARD_REG_SET save_reload_reg_used_at_all; @@ -4761,6 +4823,7 @@ choose_reload_regs (insn, avoid_return_reg) CLEAR_HARD_REG_SET (reload_reg_used); CLEAR_HARD_REG_SET (reload_reg_used_at_all); CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr); + CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr_reload); CLEAR_HARD_REG_SET (reload_reg_used_in_insn); CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr); @@ -4888,6 +4951,10 @@ choose_reload_regs (insn, avoid_return_reg) COPY_HARD_REG_SET (save_reload_reg_used_at_all, reload_reg_used_at_all); COPY_HARD_REG_SET (save_reload_reg_used_in_op_addr, reload_reg_used_in_op_addr); + + COPY_HARD_REG_SET (save_reload_reg_used_in_op_addr_reload, + reload_reg_used_in_op_addr_reload); + COPY_HARD_REG_SET (save_reload_reg_used_in_insn, reload_reg_used_in_insn); COPY_HARD_REG_SET (save_reload_reg_used_in_other_addr, @@ -5257,6 +5324,8 @@ choose_reload_regs (insn, avoid_return_reg) COPY_HARD_REG_SET (reload_reg_used_at_all, save_reload_reg_used_at_all); COPY_HARD_REG_SET (reload_reg_used_in_op_addr, save_reload_reg_used_in_op_addr); + COPY_HARD_REG_SET (reload_reg_used_in_op_addr_reload, + save_reload_reg_used_in_op_addr_reload); COPY_HARD_REG_SET (reload_reg_used_in_insn, save_reload_reg_used_in_insn); COPY_HARD_REG_SET (reload_reg_used_in_other_addr, @@ -5466,6 +5535,7 @@ emit_reload_insns (insn) rtx output_reload_insns[MAX_RECOG_OPERANDS]; rtx output_address_reload_insns[MAX_RECOG_OPERANDS]; rtx operand_reload_insns = 0; + rtx other_operand_reload_insns = 0; rtx following_insn = NEXT_INSN (insn); rtx before_insn = insn; int special; @@ -5671,6 +5741,9 @@ emit_reload_insns (insn) case RELOAD_FOR_OPERAND_ADDRESS: where = &operand_reload_insns; break; + case RELOAD_FOR_OPADDR_ADDR: + where = &other_operand_reload_insns; + break; case RELOAD_FOR_OTHER_ADDRESS: where = &other_input_address_reload_insns; break; @@ -6286,6 +6359,8 @@ emit_reload_insns (insn) For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by the RELOAD_FOR_INPUT reload for the operand. + RELOAD_FOR_OPADDR_ADDRS reloads. + RELOAD_FOR_OPERAND_ADDRESS reloads. After the insn being reloaded, we write the following: @@ -6302,6 +6377,7 @@ emit_reload_insns (insn) emit_insns_before (input_reload_insns[j], before_insn); } + emit_insns_before (other_operand_reload_insns, before_insn); emit_insns_before (operand_reload_insns, before_insn); for (j = 0; j < reload_n_operands; j++)