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
This commit is contained in:
parent
e9576d2c22
commit
a94ce33311
3 changed files with 50 additions and 17 deletions
|
@ -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.
|
||||
|
|
29
gcc/reload.c
29
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue