From a94ce33311d4bbc1f98d6f55beb133616347c682 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Tue, 19 Aug 1997 16:04:22 +0000 Subject: [PATCH] reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR reloads to... * reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR reloads to RELOAD_FOR_OPERAND_ADDRESS reloads. * reload1.c: Undo bugfix from Aug 11. Back out "simple" patch for PA reload bug and install the one accepted by the FSF. From-SVN: r14847 --- gcc/ChangeLog | 6 ++++++ gcc/reload.c | 29 +++++++++++++++++++++++++++++ gcc/reload1.c | 32 +++++++++++++++----------------- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b1beacc56f..aef412e73c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Mon Aug 18 21:49:02 1997 Jim Wilson + + * reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR + reloads to RELOAD_FOR_OPERAND_ADDRESS reloads. + * reload1.c: Undo bugfix from Aug 11. + Tue Aug 19 09:34:57 1997 Jeffrey A Law (law@cygnus.com) * Makefile.in (EXPECT, RUNTEST, RUNTESTFLAGS): Define. diff --git a/gcc/reload.c b/gcc/reload.c index a8bd5de579a..efd4aca2e94 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -3871,6 +3871,35 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) reload_opnum[i] = goal_alternative_matches[reload_opnum[i]]; } + /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads. + If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR + reloads to RELOAD_FOR_OPERAND_ADDRESS reloads. + + choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never + conflict with RELOAD_FOR_OPERAND_ADDRESS reloads. This is true for a + single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads. + However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload, + then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all + RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it. + This is complicated by the fact that a single operand can have more + than one RELOAD_FOR_OPERAND_ADDRESS reload. It is very difficult to fix + choose_reload_regs without affecting code quality, and cases that + actually fail are extremely rare, so it turns out to be better to fix + the problem here by not generating cases that choose_reload_regs will + fail for. */ + + { + int op_addr_reloads = 0; + for (i = 0; i < n_reloads; i++) + if (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS) + op_addr_reloads++; + + if (op_addr_reloads > 1) + for (i = 0; i < n_reloads; i++) + if (reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR) + reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS; + } + /* See if we have any reloads that are now allowed to be merged because we've changed when the reload is needed to RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS. Only diff --git a/gcc/reload1.c b/gcc/reload1.c index 80677874783..a3361abbfad 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1341,8 +1341,8 @@ reload (first, global, dumpfile) don't conflict with things needed to reload inputs or outputs. */ - in_max = MAX ((insn_needs.op_addr.regs[j][i] - + insn_needs.op_addr_reload.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]); @@ -1374,8 +1374,8 @@ reload (first, global, dumpfile) = MAX (out_max, insn_needs.out_addr_addr[j].groups[i]); } - in_max = MAX ((insn_needs.op_addr.groups[i] - + insn_needs.op_addr_reload.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]); @@ -4605,13 +4605,7 @@ reload_reg_free_p (regno, opnum, type) if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) return 0; - /* ??? A OPADDR_ADDR reload does not conflict with the OPERAND_ADDRESS - reload that uses it. However, the same operand can have multiple - OPERAND_ADDRESS reloads, and a OPADDR_ADDR reload does conflict with - other OPERAND_ADDRESS reloads for the same operand, hence we must - say that OPADDR_ADDR and OPERAND_ADDRESS reloads always conflict. */ return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) - && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno) && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)); case RELOAD_FOR_OPADDR_ADDR: @@ -4619,8 +4613,7 @@ reload_reg_free_p (regno, opnum, type) 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) - && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)); + 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 @@ -4737,6 +4730,12 @@ 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: + /* Earlier reloads include RELOAD_FOR_OPADDR_ADDR reloads. */ + if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)) + return 0; + + /* ... fall through ... */ + case RELOAD_FOR_OPADDR_ADDR: case RELOAD_FOR_INSN: /* These can't conflict with inputs, or each other, so all we have to @@ -4880,7 +4879,8 @@ reload_reg_reaches_end_p (regno, opnum, type) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) return 0; - return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)); + 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 RELOAD_OTHER. So @@ -4955,13 +4955,11 @@ reloads_conflict (r1, r2) case RELOAD_FOR_OPERAND_ADDRESS: return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN - || r2_type == RELOAD_FOR_OPERAND_ADDRESS - || r2_type == RELOAD_FOR_OPADDR_ADDR); + || r2_type == RELOAD_FOR_OPERAND_ADDRESS); case RELOAD_FOR_OPADDR_ADDR: return (r2_type == RELOAD_FOR_INPUT - || r2_type == RELOAD_FOR_OPADDR_ADDR - || r2_type == RELOAD_FOR_OPERAND_ADDRESS); + || r2_type == RELOAD_FOR_OPADDR_ADDR); case RELOAD_FOR_OUTPUT: return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT -- 2.30.2