Commit c02cad8f by Bernd Schmidt Committed by Bernd Schmidt

Add a frontend function for reload_reg_free_for_value_p; need to check all

registers in a multi-reg value.

From-SVN: r37916
parent 53895717
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
(try_combine, can_combine_p, combinable_i3pat): Delete old (try_combine, can_combine_p, combinable_i3pat): Delete old
SMALL_REGISTER_CLASSES tests. SMALL_REGISTER_CLASSES tests.
* reload1.c (free_for_value_p): New function, frontend to
reload_reg_free_for_value_p. All callers of the latter now call
this function with an additional mode argument.
2000-12-01 Alexandre Oliva <aoliva@redhat.com> 2000-12-01 Alexandre Oliva <aoliva@redhat.com>
* config/sh/sh.c (shiftcosts): Don't get INTVAL before testing * config/sh/sh.c (shiftcosts): Don't get INTVAL before testing
......
...@@ -413,6 +413,9 @@ static int reload_reg_free_p PARAMS ((unsigned int, int, ...@@ -413,6 +413,9 @@ static int reload_reg_free_p PARAMS ((unsigned int, int,
enum reload_type)); enum reload_type));
static int reload_reg_free_for_value_p PARAMS ((int, int, enum reload_type, static int reload_reg_free_for_value_p PARAMS ((int, int, enum reload_type,
rtx, rtx, int, int)); rtx, rtx, int, int));
static int free_for_value_p PARAMS ((int, enum machine_mode, int,
enum reload_type, rtx, rtx,
int, int));
static int reload_reg_reaches_end_p PARAMS ((unsigned int, int, static int reload_reg_reaches_end_p PARAMS ((unsigned int, int,
enum reload_type)); enum reload_type));
static int allocate_reload_reg PARAMS ((struct insn_chain *, int, static int allocate_reload_reg PARAMS ((struct insn_chain *, int,
...@@ -4650,25 +4653,8 @@ rtx reload_override_in[MAX_RELOADS]; ...@@ -4650,25 +4653,8 @@ rtx reload_override_in[MAX_RELOADS];
or -1 if we did not need a register for this reload. */ or -1 if we did not need a register for this reload. */
int reload_spill_index[MAX_RELOADS]; int reload_spill_index[MAX_RELOADS];
/* Return 1 if the value in reload reg REGNO, as used by a reload /* Subroutine of free_for_value_p, used to check a single register. */
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
Other read-only reloads with the same value do not conflict
unless OUT is non-zero and these other reloads have to live while
output reloads live.
If OUT is CONST0_RTX, this is a special case: it means that the
test should not be for using register REGNO as reload register, but
for copying from register REGNO into the reload register.
RELOADNUM is the number of the reload we want to load this value for;
a reload does not conflict with itself.
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
reloads that load an address for the very reload we are considering.
The caller has to make sure that there is no conflict with the return
register. */
static int static int
reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum, reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
ignore_address_reloads) ignore_address_reloads)
...@@ -4883,6 +4869,48 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum, ...@@ -4883,6 +4869,48 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
return 1; return 1;
} }
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
MODE is the mode in which the register is used, this is needed to
determine how many hard regs to test.
Other read-only reloads with the same value do not conflict
unless OUT is non-zero and these other reloads have to live while
output reloads live.
If OUT is CONST0_RTX, this is a special case: it means that the
test should not be for using register REGNO as reload register, but
for copying from register REGNO into the reload register.
RELOADNUM is the number of the reload we want to load this value for;
a reload does not conflict with itself.
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
reloads that load an address for the very reload we are considering.
The caller has to make sure that there is no conflict with the return
register. */
static int
free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
ignore_address_reloads)
int regno;
enum machine_mode mode;
int opnum;
enum reload_type type;
rtx value, out;
int reloadnum;
int ignore_address_reloads;
{
int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0)
if (! reload_reg_free_for_value_p (regno, opnum, type, value, out,
reloadnum, ignore_address_reloads))
return 0;
return 1;
}
/* Determine whether the reload reg X overlaps any rtx'es used for /* Determine whether the reload reg X overlaps any rtx'es used for
overriding inheritance. Return nonzero if so. */ overriding inheritance. Return nonzero if so. */
...@@ -5039,11 +5067,9 @@ allocate_reload_reg (chain, r, last_reload) ...@@ -5039,11 +5067,9 @@ allocate_reload_reg (chain, r, last_reload)
/* We check reload_reg_used to make sure we /* We check reload_reg_used to make sure we
don't clobber the return register. */ don't clobber the return register. */
&& ! TEST_HARD_REG_BIT (reload_reg_used, regnum) && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
&& reload_reg_free_for_value_p (regnum, && free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
rld[r].opnum, rld[r].when_needed, rld[r].in,
rld[r].when_needed, rld[r].out, r, 1)))
rld[r].in,
rld[r].out, r, 1)))
&& TEST_HARD_REG_BIT (reg_class_contents[class], regnum) && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
&& HARD_REGNO_MODE_OK (regnum, rld[r].mode) && HARD_REGNO_MODE_OK (regnum, rld[r].mode)
/* Look first for regs to share, then for unshared. But /* Look first for regs to share, then for unshared. But
...@@ -5386,10 +5412,9 @@ choose_reload_regs (chain) ...@@ -5386,10 +5412,9 @@ choose_reload_regs (chain)
&& (rld[r].nregs == max_group_size && (rld[r].nregs == max_group_size
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class], || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
i)) i))
&& reload_reg_free_for_value_p (i, rld[r].opnum, && free_for_value_p (i, rld[r].mode, rld[r].opnum,
rld[r].when_needed, rld[r].when_needed, rld[r].in,
rld[r].in, const0_rtx, r, 1))
const0_rtx, r, 1))
{ {
/* If a group is needed, verify that all the subsequent /* If a group is needed, verify that all the subsequent
registers still have their values intact. */ registers still have their values intact. */
...@@ -5422,9 +5447,10 @@ choose_reload_regs (chain) ...@@ -5422,9 +5447,10 @@ choose_reload_regs (chain)
break; break;
if (i1 != n_earlyclobbers if (i1 != n_earlyclobbers
|| ! (reload_reg_free_for_value_p || ! (free_for_value_p (i, rld[r].mode,
(i, rld[r].opnum, rld[r].when_needed, rld[r].opnum,
rld[r].in, rld[r].out, r, 1)) rld[r].when_needed, rld[r].in,
rld[r].out, r, 1))
/* Don't use it if we'd clobber a pseudo reg. */ /* Don't use it if we'd clobber a pseudo reg. */
|| (TEST_HARD_REG_BIT (reg_used_in_insn, i) || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
&& rld[r].out && rld[r].out
...@@ -5528,10 +5554,9 @@ choose_reload_regs (chain) ...@@ -5528,10 +5554,9 @@ choose_reload_regs (chain)
and of the desired class. */ and of the desired class. */
if (equiv != 0 if (equiv != 0
&& ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno) && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
&& ! reload_reg_free_for_value_p (regno, rld[r].opnum, && ! free_for_value_p (regno, rld[r].mode,
rld[r].when_needed, rld[r].opnum, rld[r].when_needed,
rld[r].in, rld[r].in, rld[r].out, r, 1))
rld[r].out, r, 1))
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class], || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
regno))) regno)))
equiv = 0; equiv = 0;
...@@ -5749,13 +5774,11 @@ choose_reload_regs (chain) ...@@ -5749,13 +5774,11 @@ choose_reload_regs (chain)
check_reg = reload_override_in[r]; check_reg = reload_override_in[r];
else else
continue; continue;
if (! reload_reg_free_for_value_p (true_regnum (check_reg), if (! free_for_value_p (true_regnum (check_reg), rld[r].mode,
rld[r].opnum, rld[r].opnum, rld[r].when_needed, rld[r].in,
rld[r].when_needed, (reload_inherited[r]
rld[r].in, ? rld[r].out : const0_rtx),
(reload_inherited[r] r, 1))
? rld[r].out : const0_rtx),
r, 1))
{ {
if (pass) if (pass)
continue; continue;
...@@ -6079,10 +6102,8 @@ emit_input_reload_insns (chain, rl, old, j) ...@@ -6079,10 +6102,8 @@ emit_input_reload_insns (chain, rl, old, j)
/* Don't use OLDEQUIV if any other reload changes it at an /* Don't use OLDEQUIV if any other reload changes it at an
earlier stage of this insn or at this stage. */ earlier stage of this insn or at this stage. */
if (! reload_reg_free_for_value_p (regno, rl->opnum, if (! free_for_value_p (regno, rl->mode, rl->opnum, rl->when_needed,
rl->when_needed, rl->in, const0_rtx, j, 0))
rl->in, const0_rtx, j,
0))
oldequiv = 0; oldequiv = 0;
/* If it is no cheaper to copy from OLDEQUIV into the /* If it is no cheaper to copy from OLDEQUIV into the
...@@ -6232,11 +6253,8 @@ emit_input_reload_insns (chain, rl, old, j) ...@@ -6232,11 +6253,8 @@ emit_input_reload_insns (chain, rl, old, j)
/* This is unsafe if some other reload /* This is unsafe if some other reload
uses the same reg first. */ uses the same reg first. */
&& ! conflicts_with_override (reloadreg) && ! conflicts_with_override (reloadreg)
&& reload_reg_free_for_value_p (REGNO (reloadreg), && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum,
rl->opnum, rl->when_needed, old, rl->out, j, 0))
rl->when_needed,
old, rl->out,
j, 0))
{ {
rtx temp = PREV_INSN (insn); rtx temp = PREV_INSN (insn);
while (temp && GET_CODE (temp) == NOTE) while (temp && GET_CODE (temp) == NOTE)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment