Simplify reload register allocation

From-SVN: r30890
This commit is contained in:
Bernd Schmidt 1999-12-13 13:21:35 +00:00 committed by Bernd Schmidt
parent 2cf4028a7c
commit f5d8c9f405
6 changed files with 443 additions and 1157 deletions

View File

@ -1,3 +1,46 @@
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>
* flow.c (create_edge_list): Cast xmalloc return value.

View File

@ -429,10 +429,14 @@ extern HARD_REG_SET call_fixed_reg_set;
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. */
#ifdef REG_ALLOC_ORDER /* Avoid undef symbol in certain broken linkers. */
extern int reg_alloc_order[FIRST_PSEUDO_REGISTER];
/* The inverse of reg_alloc_order. */
extern int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
#endif
/* For each reg class, a HARD_REG_SET saying which registers are in it. */

View File

@ -118,6 +118,9 @@ char global_regs[FIRST_PSEUDO_REGISTER];
/* Table of register numbers in the order in which to try to use them. */
#ifdef 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
/* For each reg class, a HARD_REG_SET saying which registers are in it. */
@ -251,6 +254,11 @@ init_reg_sets ()
/* Do any additional initialization regsets may need */
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

View File

@ -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].reg_rtx = 0;
rld[t_reload].optional = optional;
rld[t_reload].nongroup = 0;
rld[t_reload].inc = 0;
/* Maybe we could combine these, but it seems too tricky. */
rld[t_reload].nocombine = 1;
@ -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].reg_rtx = 0;
rld[s_reload].optional = optional;
rld[s_reload].nongroup = 0;
rld[s_reload].inc = 0;
/* Maybe we could combine these, but it seems too tricky. */
rld[s_reload].nocombine = 1;
@ -1246,7 +1244,6 @@ push_reload (in, out, inloc, outloc, class,
rld[i].outmode = outmode;
rld[i].reg_rtx = 0;
rld[i].optional = optional;
rld[i].nongroup = 0;
rld[i].inc = 0;
rld[i].nocombine = 0;
rld[i].in_reg = inloc ? *inloc : 0;
@ -4119,67 +4116,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
abort ();
#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. */
for (i = 0; i < n_reloads; i++)
{

View File

@ -231,25 +231,9 @@ struct insn_chain
regset live_before;
regset live_after;
/* For each class, size of group of consecutive regs
that is needed for the reloads of this class. */
char group_size[N_REG_CLASSES];
/* 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;
/* Copies of the global variables computed by find_reloads. */
struct reload *rld;
int n_reloads;
/* Indicates which registers have already been used for spills. */
HARD_REG_SET used_spill_regs;

File diff suppressed because it is too large Load Diff