Commit f5d8c9f4 by Bernd Schmidt Committed by Bernd Schmidt

Simplify reload register allocation

From-SVN: r30890
parent 2cf4028a
1999-12-10 Bernd Schmidt <bernds@cygnus.co.uk>
* hard-reg-set.h (inv_reg_alloc_order): Declare if REG_ALLOC_ORDER is
defined.
* regclass.c (inv_reg_alloc_order): New array.
(regclass_init): If REG_ALLOC_ORDER is defined, initialize it.
* reload.h (struct insn_chain): Delete fields group_size, group_mode,
counted_for_groups, counted_for_nongroups. Add fields rld and
n_reloads.
* reload.c (push_secondary_reload): Don't set nongroup field of
new reloads.
(push_reload): Likewise.
(find_reloads): Delete code to compute nongroup fields.
* reload1.c (reload_insn_firstobj): New static variable.
(pseudos_counted, spilled_pseudos): Now of type regset_head. All
users changed.
(calculate_needs, find_tworeg_group, find_group, possible_group_p,
count_possible_groups, modes_equiv_for_class_p, new_spill_reg,
dump_needs, maybe_mark_pseudo_spilled, hard_reg_use_compare): Delete
functions.
(count_pseudo, select_reload_regs, copy_reloads, find_reg): New
functions.
(struct hard_reg_n_uses): Deleted.
(potential_reload_regs): Deleted.
(init_reload): Initialize spilled_pseudos and pseudos_counted.
(reload): Don't try to allocate reload registers if we already know
we have to make another pass. Call select_reload_regs. Free memory
starting with reload_firstobj when starting another pass.
Don't allocate spilled_pseudos.
(calculate_needs_all_insns): Call copy_reloads for an insn that
needs reloads; don't call calculate_needs.
(spill_cost): New static array.
(used_spill_regs_local): New static variable.
(order_regs_for_reload): Rewrite to lose hard_reg_n_uses and the code
to compute potential_reload_regs.
(find_reload_regs): Completely rewritten to use find_reg.
(allocate_reload_reg): Don't test counted_for_groups or
counted_for_nongroups. Lose NOERROR arg and code to give an error;
all cllers changed.
(choose_reload_regs): Add fallback code that uses the existing
register allocation from find_reload_regs.
Mon Dec 13 00:54:14 1999 Philippe De Muyter <phdm@macqel.be> Mon Dec 13 00:54:14 1999 Philippe De Muyter <phdm@macqel.be>
* flow.c (create_edge_list): Cast xmalloc return value. * flow.c (create_edge_list): Cast xmalloc return value.
......
...@@ -429,10 +429,14 @@ extern HARD_REG_SET call_fixed_reg_set; ...@@ -429,10 +429,14 @@ extern HARD_REG_SET call_fixed_reg_set;
extern char global_regs[FIRST_PSEUDO_REGISTER]; extern char global_regs[FIRST_PSEUDO_REGISTER];
#ifdef REG_ALLOC_ORDER
/* Table of register numbers in the order in which to try to use them. */ /* Table of register numbers in the order in which to try to use them. */
#ifdef REG_ALLOC_ORDER /* Avoid undef symbol in certain broken linkers. */
extern int reg_alloc_order[FIRST_PSEUDO_REGISTER]; extern int reg_alloc_order[FIRST_PSEUDO_REGISTER];
/* The inverse of reg_alloc_order. */
extern int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
#endif #endif
/* For each reg class, a HARD_REG_SET saying which registers are in it. */ /* For each reg class, a HARD_REG_SET saying which registers are in it. */
......
...@@ -118,6 +118,9 @@ char global_regs[FIRST_PSEUDO_REGISTER]; ...@@ -118,6 +118,9 @@ char global_regs[FIRST_PSEUDO_REGISTER];
/* Table of register numbers in the order in which to try to use them. */ /* Table of register numbers in the order in which to try to use them. */
#ifdef REG_ALLOC_ORDER #ifdef REG_ALLOC_ORDER
int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
/* The inverse of reg_alloc_order. */
int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
#endif #endif
/* For each reg class, a HARD_REG_SET saying which registers are in it. */ /* For each reg class, a HARD_REG_SET saying which registers are in it. */
...@@ -251,6 +254,11 @@ init_reg_sets () ...@@ -251,6 +254,11 @@ init_reg_sets ()
/* Do any additional initialization regsets may need */ /* Do any additional initialization regsets may need */
INIT_ONCE_REG_SET (); INIT_ONCE_REG_SET ();
#ifdef REG_ALLOC_ORDER
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
inv_reg_alloc_order[reg_alloc_order[i]] = i;
#endif
} }
/* After switches have been processed, which perhaps alter /* After switches have been processed, which perhaps alter
......
...@@ -465,7 +465,6 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode, ...@@ -465,7 +465,6 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
rld[t_reload].outmode = ! in_p ? t_mode : VOIDmode; rld[t_reload].outmode = ! in_p ? t_mode : VOIDmode;
rld[t_reload].reg_rtx = 0; rld[t_reload].reg_rtx = 0;
rld[t_reload].optional = optional; rld[t_reload].optional = optional;
rld[t_reload].nongroup = 0;
rld[t_reload].inc = 0; rld[t_reload].inc = 0;
/* Maybe we could combine these, but it seems too tricky. */ /* Maybe we could combine these, but it seems too tricky. */
rld[t_reload].nocombine = 1; rld[t_reload].nocombine = 1;
...@@ -535,7 +534,6 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode, ...@@ -535,7 +534,6 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
rld[s_reload].outmode = ! in_p ? mode : VOIDmode; rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
rld[s_reload].reg_rtx = 0; rld[s_reload].reg_rtx = 0;
rld[s_reload].optional = optional; rld[s_reload].optional = optional;
rld[s_reload].nongroup = 0;
rld[s_reload].inc = 0; rld[s_reload].inc = 0;
/* Maybe we could combine these, but it seems too tricky. */ /* Maybe we could combine these, but it seems too tricky. */
rld[s_reload].nocombine = 1; rld[s_reload].nocombine = 1;
...@@ -1246,7 +1244,6 @@ push_reload (in, out, inloc, outloc, class, ...@@ -1246,7 +1244,6 @@ push_reload (in, out, inloc, outloc, class,
rld[i].outmode = outmode; rld[i].outmode = outmode;
rld[i].reg_rtx = 0; rld[i].reg_rtx = 0;
rld[i].optional = optional; rld[i].optional = optional;
rld[i].nongroup = 0;
rld[i].inc = 0; rld[i].inc = 0;
rld[i].nocombine = 0; rld[i].nocombine = 0;
rld[i].in_reg = inloc ? *inloc : 0; rld[i].in_reg = inloc ? *inloc : 0;
...@@ -4119,67 +4116,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -4119,67 +4116,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
abort (); abort ();
#endif #endif
/* Set which reloads must use registers not used in any group. Start
with those that conflict with a group and then include ones that
conflict with ones that are already known to conflict with a group. */
changed = 0;
for (i = 0; i < n_reloads; i++)
{
enum machine_mode mode = rld[i].inmode;
enum reg_class class = rld[i].class;
int size;
if (GET_MODE_SIZE (rld[i].outmode) > GET_MODE_SIZE (mode))
mode = rld[i].outmode;
size = CLASS_MAX_NREGS (class, mode);
if (size == 1)
for (j = 0; j < n_reloads; j++)
if ((CLASS_MAX_NREGS (rld[j].class,
(GET_MODE_SIZE (rld[j].outmode)
> GET_MODE_SIZE (rld[j].inmode))
? rld[j].outmode : rld[j].inmode)
> 1)
&& !rld[j].optional
&& (rld[j].in != 0 || rld[j].out != 0
|| rld[j].secondary_p)
&& reloads_conflict (i, j)
&& reg_classes_intersect_p (class, rld[j].class))
{
rld[i].nongroup = 1;
changed = 1;
break;
}
}
while (changed)
{
changed = 0;
for (i = 0; i < n_reloads; i++)
{
enum machine_mode mode = rld[i].inmode;
enum reg_class class = rld[i].class;
int size;
if (GET_MODE_SIZE (rld[i].outmode) > GET_MODE_SIZE (mode))
mode = rld[i].outmode;
size = CLASS_MAX_NREGS (class, mode);
if (! rld[i].nongroup && size == 1)
for (j = 0; j < n_reloads; j++)
if (rld[j].nongroup
&& reloads_conflict (i, j)
&& reg_classes_intersect_p (class, rld[j].class))
{
rld[i].nongroup = 1;
changed = 1;
break;
}
}
}
/* Compute reload_mode and reload_nregs. */ /* Compute reload_mode and reload_nregs. */
for (i = 0; i < n_reloads; i++) for (i = 0; i < n_reloads; i++)
{ {
......
...@@ -231,25 +231,9 @@ struct insn_chain ...@@ -231,25 +231,9 @@ struct insn_chain
regset live_before; regset live_before;
regset live_after; regset live_after;
/* For each class, size of group of consecutive regs /* Copies of the global variables computed by find_reloads. */
that is needed for the reloads of this class. */ struct reload *rld;
char group_size[N_REG_CLASSES]; int n_reloads;
/* For each class, the machine mode which requires consecutive
groups of regs of that class.
If two different modes ever require groups of one class,
they must be the same size and equally restrictive for that class,
otherwise we can't handle the complexity. */
enum machine_mode group_mode[N_REG_CLASSES];
/* Indicates if a register was counted against the need for
groups. 0 means it can count against max_nongroup instead. */
HARD_REG_SET counted_for_groups;
/* Indicates if a register was counted against the need for
non-groups. 0 means it can become part of a new group.
During choose_reload_regs, 1 here means don't use this reg
as part of a group, even if it seems to be otherwise ok. */
HARD_REG_SET counted_for_nongroups;
/* Indicates which registers have already been used for spills. */ /* Indicates which registers have already been used for spills. */
HARD_REG_SET used_spill_regs; HARD_REG_SET used_spill_regs;
......
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