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:
Jim Wilson 1997-08-19 16:04:22 +00:00 committed by Jeff Law
parent e9576d2c22
commit a94ce33311
3 changed files with 50 additions and 17 deletions

View File

@ -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.

View File

@ -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

View File

@ -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