aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@cygnus.com>1997-08-19 16:04:22 +0000
committerJeff Law <law@gcc.gnu.org>1997-08-19 10:04:22 -0600
commita94ce33311d4bbc1f98d6f55beb133616347c682 (patch)
tree25b3a60e6623c4cd6da8ad483c50546a449f0d52 /gcc
parente9576d2c229b3caea1c0c7fb0bd56eb1dd8537ee (diff)
downloadgcc-a94ce33311d4bbc1f98d6f55beb133616347c682.zip
gcc-a94ce33311d4bbc1f98d6f55beb133616347c682.tar.gz
gcc-a94ce33311d4bbc1f98d6f55beb133616347c682.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/reload.c29
-rw-r--r--gcc/reload1.c32
3 files changed, 50 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1b1beac..aef412e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+Mon Aug 18 21:49:02 1997 Jim Wilson <wilson@cygnus.com>
+
+ * 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 a8bd5de..efd4aca 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 8067787..a3361ab 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