Commit a1ed7bdb by Jan Hubicka Committed by Jan Hubicka

local-alloc.c (qty): New structure and static variable.

	* local-alloc.c (qty): New structure and static variable.
	(qty_phys_reg): Remove, all references changed to qty.
	(qty_n_refs): Likewise.
	(qty_min_class): Likewise.
	(qty_birth): Likewise.
	(qty_death): Likewise.
	(qty_size): Likewise.
	(qty_mode): Likewise.
	(qty_n_calls_crossed): Likewise.
	(qty_alternate_class): Likewise.
	(qty_changes_size): Likewise.
	(qty_first_reg): Likewise.
	(alloc_qty): Rename variable QTY to QTYNO.
	(finf_free_reg): Likewise.
	(local_alloc): Allocate qty, do not allocate the removed variables.

From-SVN: r30651
parent 7e8a11bb
Wed Nov 24 14:12:15 MET 1999 Jan Hubicka <hubicka@freesoft.cz>
* local-alloc.c (qty): New structure and static variable.
(qty_phys_reg): Remove, all references changed to qty.
(qty_n_refs): Likewise.
(qty_min_class): Likewise.
(qty_birth): Likewise.
(qty_death): Likewise.
(qty_size): Likewise.
(qty_mode): Likewise.
(qty_n_calls_crossed): Likewise.
(qty_alternate_class): Likewise.
(qty_changes_size): Likewise.
(qty_first_reg): Likewise.
(alloc_qty): Rename variable QTY to QTYNO.
(finf_free_reg): Likewise.
(local_alloc): Allocate qty, do not allocate the removed variables.
Wed Nov 24 17:26:05 1999 Geoffrey Keating <geoffk@cygnus.com> Wed Nov 24 17:26:05 1999 Geoffrey Keating <geoffk@cygnus.com>
* config/mips/mips.h (ASM_SPEC): Don't pass -G to the assembler * config/mips/mips.h (ASM_SPEC): Don't pass -G to the assembler
......
...@@ -78,100 +78,108 @@ Boston, MA 02111-1307, USA. */ ...@@ -78,100 +78,108 @@ Boston, MA 02111-1307, USA. */
static int next_qty; static int next_qty;
/* In all the following vectors indexed by quantity number. */ /* Information we maitain about each quantity. */
struct qty
{
/* The number of refs to quantity Q. */
/* Element Q is the hard reg number chosen for quantity Q, int n_refs;
or -1 if none was found. */
static short *qty_phys_reg; /* Insn number (counting from head of basic block)
where quantity Q was born. -1 if birth has not been recorded. */
/* We maintain two hard register sets that indicate suggested hard registers int birth;
for each quantity. The first, qty_phys_copy_sugg, contains hard registers
that are tied to the quantity by a simple copy. The second contains all
hard registers that are tied to the quantity via an arithmetic operation.
The former register set is given priority for allocation. This tends to /* Insn number (counting from head of basic block)
eliminate copy insns. */ where given quantity died. Due to the way tying is done,
and the fact that we consider in this pass only regs that die but once,
a quantity can die only once. Each quantity's life span
is a set of consecutive insns. -1 if death has not been recorded. */
/* Element Q is a set of hard registers that are suggested for quantity Q by int death;
copy insns. */
static HARD_REG_SET *qty_phys_copy_sugg; /* Number of words needed to hold the data in given quantity.
This depends on its machine mode. It is used for these purposes:
1. It is used in computing the relative importances of qtys,
which determines the order in which we look for regs for them.
2. It is used in rules that prevent tying several registers of
different sizes in a way that is geometrically impossible
(see combine_regs). */
/* Element Q is a set of hard registers that are suggested for quantity Q by int size;
arithmetic insns. */
static HARD_REG_SET *qty_phys_sugg; /* Number of times a reg tied to given qty lives across a CALL_INSN. */
/* Element Q is the number of suggested registers in qty_phys_copy_sugg. */ int n_calls_crossed;
static short *qty_phys_num_copy_sugg; /* The register number of one pseudo register whose reg_qty value is Q.
This register should be the head of the chain
maintained in reg_next_in_qty. */
/* Element Q is the number of suggested registers in qty_phys_sugg. */ int first_reg;
static short *qty_phys_num_sugg; /* Reg class contained in (smaller than) the preferred classes of all
the pseudo regs that are tied in given quantity.
This is the preferred class for allocating that quantity. */
enum reg_class min_class;
/* Element Q is the number of refs to quantity Q. */ /* Register class within which we allocate given qty if we can't get
its preferred class. */
static int *qty_n_refs; enum reg_class alternate_class;
/* Element Q is a reg class contained in (smaller than) the /* This holds the mode of the registers that are tied to given qty,
preferred classes of all the pseudo regs that are tied in quantity Q. or VOIDmode if registers with differing modes are tied together. */
This is the preferred class for allocating that quantity. */
static enum reg_class *qty_min_class; enum machine_mode mode;
/* Insn number (counting from head of basic block) /* the hard reg number chosen for given quantity,
where quantity Q was born. -1 if birth has not been recorded. */ or -1 if none was found. */
static int *qty_birth; short phys_reg;
/* Insn number (counting from head of basic block) /* Nonzero if this quantity has been used in a SUBREG that changes
where quantity Q died. Due to the way tying is done, its size. */
and the fact that we consider in this pass only regs that die but once,
a quantity can die only once. Each quantity's life span
is a set of consecutive insns. -1 if death has not been recorded. */
static int *qty_death; char changes_size;
/* Number of words needed to hold the data in quantity Q. };
This depends on its machine mode. It is used for these purposes:
1. It is used in computing the relative importances of qtys,
which determines the order in which we look for regs for them.
2. It is used in rules that prevent tying several registers of
different sizes in a way that is geometrically impossible
(see combine_regs). */
static int *qty_size; static struct qty *qty;
/* This holds the mode of the registers that are tied to qty Q, /* These fields are kept separately to speedup their clearing. */
or VOIDmode if registers with differing modes are tied together. */
static enum machine_mode *qty_mode; /* We maintain two hard register sets that indicate suggested hard registers
for each quantity. The first, phys_copy_sugg, contains hard registers
that are tied to the quantity by a simple copy. The second contains all
hard registers that are tied to the quantity via an arithmetic operation.
/* Number of times a reg tied to qty Q lives across a CALL_INSN. */ The former register set is given priority for allocation. This tends to
eliminate copy insns. */
static int *qty_n_calls_crossed; /* Element Q is a set of hard registers that are suggested for quantity Q by
copy insns. */
/* Register class within which we allocate qty Q if we can't get static HARD_REG_SET *qty_phys_copy_sugg;
its preferred class. */
static enum reg_class *qty_alternate_class; /* Element Q is a set of hard registers that are suggested for quantity Q by
arithmetic insns. */
static HARD_REG_SET *qty_phys_sugg;
/* Element Q is the number of suggested registers in qty_phys_copy_sugg. */
/* Element Q is nonzero if this quantity has been used in a SUBREG static short *qty_phys_num_copy_sugg;
that changes its size. */
static char *qty_changes_size; /* Element Q is the number of suggested registers in qty_phys_sugg. */
/* Element Q is the register number of one pseudo register whose static short *qty_phys_num_sugg;
reg_qty value is Q. This register should be the head of the chain
maintained in reg_next_in_qty. */
static int *qty_first_reg;
/* If (REG N) has been assigned a quantity number, is a register number /* If (REG N) has been assigned a quantity number, is a register number
of another register assigned the same quantity number, or -1 for the of another register assigned the same quantity number, or -1 for the
end of the chain. qty_first_reg point to the head of this chain. */ end of the chain. qty->first_reg point to the head of this chain. */
static int *reg_next_in_qty; static int *reg_next_in_qty;
...@@ -278,21 +286,21 @@ alloc_qty (regno, mode, size, birth) ...@@ -278,21 +286,21 @@ alloc_qty (regno, mode, size, birth)
enum machine_mode mode; enum machine_mode mode;
int size, birth; int size, birth;
{ {
register int qty = next_qty++; register int qtyno = next_qty++;
reg_qty[regno] = qty; reg_qty[regno] = qtyno;
reg_offset[regno] = 0; reg_offset[regno] = 0;
reg_next_in_qty[regno] = -1; reg_next_in_qty[regno] = -1;
qty_first_reg[qty] = regno; qty[qtyno].first_reg = regno;
qty_size[qty] = size; qty[qtyno].size = size;
qty_mode[qty] = mode; qty[qtyno].mode = mode;
qty_birth[qty] = birth; qty[qtyno].birth = birth;
qty_n_calls_crossed[qty] = REG_N_CALLS_CROSSED (regno); qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno);
qty_min_class[qty] = reg_preferred_class (regno); qty[qtyno].min_class = reg_preferred_class (regno);
qty_alternate_class[qty] = reg_alternate_class (regno); qty[qtyno].alternate_class = reg_alternate_class (regno);
qty_n_refs[qty] = REG_N_REFS (regno); qty[qtyno].n_refs = REG_N_REFS (regno);
qty_changes_size[qty] = REG_CHANGES_SIZE (regno); qty[qtyno].changes_size = REG_CHANGES_SIZE (regno);
} }
/* Main entry point of this file. */ /* Main entry point of this file. */
...@@ -326,25 +334,12 @@ local_alloc () ...@@ -326,25 +334,12 @@ local_alloc ()
See the declarations of these variables, above, See the declarations of these variables, above,
for what they mean. */ for what they mean. */
qty_phys_reg = (short *) xmalloc (max_qty * sizeof (short)); qty = (struct qty *) xmalloc (max_qty * sizeof (struct qty));
qty_phys_copy_sugg qty_phys_copy_sugg
= (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET)); = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short)); qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short));
qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET)); qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short)); qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short));
qty_birth = (int *) xmalloc (max_qty * sizeof (int));
qty_death = (int *) xmalloc (max_qty * sizeof (int));
qty_first_reg = (int *) xmalloc (max_qty * sizeof (int));
qty_size = (int *) xmalloc (max_qty * sizeof (int));
qty_mode
= (enum machine_mode *) xmalloc (max_qty * sizeof (enum machine_mode));
qty_n_calls_crossed = (int *) xmalloc (max_qty * sizeof (int));
qty_min_class
= (enum reg_class *) xmalloc (max_qty * sizeof (enum reg_class));
qty_alternate_class
= (enum reg_class *) xmalloc (max_qty * sizeof (enum reg_class));
qty_n_refs = (int *) xmalloc (max_qty * sizeof (int));
qty_changes_size = (char *) xmalloc (max_qty * sizeof (char));
reg_qty = (int *) xmalloc (max_regno * sizeof (int)); reg_qty = (int *) xmalloc (max_regno * sizeof (int));
reg_offset = (char *) xmalloc (max_regno * sizeof (char)); reg_offset = (char *) xmalloc (max_regno * sizeof (char));
...@@ -413,21 +408,11 @@ local_alloc () ...@@ -413,21 +408,11 @@ local_alloc ()
block_alloc (b); block_alloc (b);
} }
free (qty_phys_reg); free (qty);
free (qty_phys_copy_sugg); free (qty_phys_copy_sugg);
free (qty_phys_num_copy_sugg); free (qty_phys_num_copy_sugg);
free (qty_phys_sugg); free (qty_phys_sugg);
free (qty_phys_num_sugg); free (qty_phys_num_sugg);
free (qty_birth);
free (qty_death);
free (qty_first_reg);
free (qty_size);
free (qty_mode);
free (qty_n_calls_crossed);
free (qty_min_class);
free (qty_alternate_class);
free (qty_n_refs);
free (qty_changes_size);
free (reg_qty); free (reg_qty);
free (reg_offset); free (reg_offset);
...@@ -1356,10 +1341,10 @@ block_alloc (b) ...@@ -1356,10 +1341,10 @@ block_alloc (b)
{ {
q = qty_order[i]; q = qty_order[i];
if (qty_phys_num_sugg[q] != 0 || qty_phys_num_copy_sugg[q] != 0) if (qty_phys_num_sugg[q] != 0 || qty_phys_num_copy_sugg[q] != 0)
qty_phys_reg[q] = find_free_reg (qty_min_class[q], qty_mode[q], q, qty[q].phys_reg = find_free_reg (qty[q].min_class, qty[q].mode, q,
0, 1, qty_birth[q], qty_death[q]); 0, 1, qty[q].birth, qty[q].death);
else else
qty_phys_reg[q] = -1; qty[q].phys_reg = -1;
} }
/* Order the qtys so we assign them registers in order of /* Order the qtys so we assign them registers in order of
...@@ -1406,7 +1391,7 @@ block_alloc (b) ...@@ -1406,7 +1391,7 @@ block_alloc (b)
for (i = 0; i < next_qty; i++) for (i = 0; i < next_qty; i++)
{ {
q = qty_order[i]; q = qty_order[i];
if (qty_phys_reg[q] < 0) if (qty[q].phys_reg < 0)
{ {
#ifdef INSN_SCHEDULING #ifdef INSN_SCHEDULING
/* These values represent the adjusted lifetime of a qty so /* These values represent the adjusted lifetime of a qty so
...@@ -1426,9 +1411,9 @@ block_alloc (b) ...@@ -1426,9 +1411,9 @@ block_alloc (b)
If allocation using the extended lifetime fails we will try If allocation using the extended lifetime fails we will try
again with the qty's unadjusted lifetime. */ again with the qty's unadjusted lifetime. */
int fake_birth = MAX (0, qty_birth[q] - 2 + qty_birth[q] % 2); int fake_birth = MAX (0, qty[q].birth - 2 + qty[q].birth % 2);
int fake_death = MIN (insn_number * 2 + 1, int fake_death = MIN (insn_number * 2 + 1,
qty_death[q] + 2 - qty_death[q] % 2); qty[q].death + 2 - qty[q].death % 2);
#endif #endif
if (N_REG_CLASSES > 1) if (N_REG_CLASSES > 1)
...@@ -1446,17 +1431,17 @@ block_alloc (b) ...@@ -1446,17 +1431,17 @@ block_alloc (b)
&& !SMALL_REGISTER_CLASSES) && !SMALL_REGISTER_CLASSES)
{ {
qty_phys_reg[q] = find_free_reg (qty_min_class[q], qty[q].phys_reg = find_free_reg (qty[q].min_class,
qty_mode[q], q, 0, 0, qty[q].mode, q, 0, 0,
fake_birth, fake_death); fake_birth, fake_death);
if (qty_phys_reg[q] >= 0) if (qty[q].phys_reg >= 0)
continue; continue;
} }
#endif #endif
qty_phys_reg[q] = find_free_reg (qty_min_class[q], qty[q].phys_reg = find_free_reg (qty[q].min_class,
qty_mode[q], q, 0, 0, qty[q].mode, q, 0, 0,
qty_birth[q], qty_death[q]); qty[q].birth, qty[q].death);
if (qty_phys_reg[q] >= 0) if (qty[q].phys_reg >= 0)
continue; continue;
} }
...@@ -1465,15 +1450,15 @@ block_alloc (b) ...@@ -1465,15 +1450,15 @@ block_alloc (b)
if (flag_schedule_insns_after_reload if (flag_schedule_insns_after_reload
&& !optimize_size && !optimize_size
&& !SMALL_REGISTER_CLASSES && !SMALL_REGISTER_CLASSES
&& qty_alternate_class[q] != NO_REGS) && qty[q].alternate_class != NO_REGS)
qty_phys_reg[q] = find_free_reg (qty_alternate_class[q], qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
qty_mode[q], q, 0, 0, qty[q].mode, q, 0, 0,
fake_birth, fake_death); fake_birth, fake_death);
#endif #endif
if (qty_alternate_class[q] != NO_REGS) if (qty[q].alternate_class != NO_REGS)
qty_phys_reg[q] = find_free_reg (qty_alternate_class[q], qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
qty_mode[q], q, 0, 0, qty[q].mode, q, 0, 0,
qty_birth[q], qty_death[q]); qty[q].birth, qty[q].death);
} }
} }
...@@ -1481,10 +1466,10 @@ block_alloc (b) ...@@ -1481,10 +1466,10 @@ block_alloc (b)
to the pseudo regs belonging to the qtys. */ to the pseudo regs belonging to the qtys. */
for (q = 0; q < next_qty; q++) for (q = 0; q < next_qty; q++)
if (qty_phys_reg[q] >= 0) if (qty[q].phys_reg >= 0)
{ {
for (i = qty_first_reg[q]; i >= 0; i = reg_next_in_qty[i]) for (i = qty[q].first_reg; i >= 0; i = reg_next_in_qty[i])
reg_renumber[i] = qty_phys_reg[q] + reg_offset[i]; reg_renumber[i] = qty[q].phys_reg + reg_offset[i];
} }
/* Clean up. */ /* Clean up. */
...@@ -1509,8 +1494,8 @@ block_alloc (b) ...@@ -1509,8 +1494,8 @@ block_alloc (b)
QTY_CMP_PRI is also used by qty_sugg_compare. */ QTY_CMP_PRI is also used by qty_sugg_compare. */
#define QTY_CMP_PRI(q) \ #define QTY_CMP_PRI(q) \
((int) (((double) (floor_log2 (qty_n_refs[q]) * qty_n_refs[q] * qty_size[q]) \ ((int) (((double) (floor_log2 (qty[q].n_refs) * qty[q].n_refs * qty[q].size) \
/ (qty_death[q] - qty_birth[q])) * 10000)) / (qty[q].death - qty[q].birth)) * 10000))
static int static int
qty_compare (q1, q2) qty_compare (q1, q2)
...@@ -1656,7 +1641,7 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead) ...@@ -1656,7 +1641,7 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
/* Do not combine with a smaller already-assigned object /* Do not combine with a smaller already-assigned object
if that smaller object is already combined with something bigger. */ if that smaller object is already combined with something bigger. */
|| (ssize > usize && ureg >= FIRST_PSEUDO_REGISTER || (ssize > usize && ureg >= FIRST_PSEUDO_REGISTER
&& usize < qty_size[reg_qty[ureg]]) && usize < qty[reg_qty[ureg]].size)
/* Can't combine if SREG is not a register we can allocate. */ /* Can't combine if SREG is not a register we can allocate. */
|| (sreg >= FIRST_PSEUDO_REGISTER && reg_qty[sreg] == -1) || (sreg >= FIRST_PSEUDO_REGISTER && reg_qty[sreg] == -1)
/* Don't combine with a pseudo mentioned in a REG_NO_CONFLICT note. /* Don't combine with a pseudo mentioned in a REG_NO_CONFLICT note.
...@@ -1745,30 +1730,30 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead) ...@@ -1745,30 +1730,30 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
are compatible. */ are compatible. */
if ((already_dead || find_regno_note (insn, REG_DEAD, ureg)) if ((already_dead || find_regno_note (insn, REG_DEAD, ureg))
&& reg_meets_class_p (sreg, qty_min_class[reg_qty[ureg]])) && reg_meets_class_p (sreg, qty[reg_qty[ureg]].min_class))
{ {
/* Add SREG to UREG's quantity. */ /* Add SREG to UREG's quantity. */
sqty = reg_qty[ureg]; sqty = reg_qty[ureg];
reg_qty[sreg] = sqty; reg_qty[sreg] = sqty;
reg_offset[sreg] = reg_offset[ureg] + offset; reg_offset[sreg] = reg_offset[ureg] + offset;
reg_next_in_qty[sreg] = qty_first_reg[sqty]; reg_next_in_qty[sreg] = qty[sqty].first_reg;
qty_first_reg[sqty] = sreg; qty[sqty].first_reg = sreg;
/* If SREG's reg class is smaller, set qty_min_class[SQTY]. */ /* If SREG's reg class is smaller, set qty[SQTY].min_class. */
update_qty_class (sqty, sreg); update_qty_class (sqty, sreg);
/* Update info about quantity SQTY. */ /* Update info about quantity SQTY. */
qty_n_calls_crossed[sqty] += REG_N_CALLS_CROSSED (sreg); qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
qty_n_refs[sqty] += REG_N_REFS (sreg); qty[sqty].n_refs += REG_N_REFS (sreg);
if (usize < ssize) if (usize < ssize)
{ {
register int i; register int i;
for (i = qty_first_reg[sqty]; i >= 0; i = reg_next_in_qty[i]) for (i = qty[sqty].first_reg; i >= 0; i = reg_next_in_qty[i])
reg_offset[i] -= offset; reg_offset[i] -= offset;
qty_size[sqty] = ssize; qty[sqty].size = ssize;
qty_mode[sqty] = GET_MODE (setreg); qty[sqty].mode = GET_MODE (setreg);
} }
} }
else else
...@@ -1791,23 +1776,23 @@ reg_meets_class_p (reg, class) ...@@ -1791,23 +1776,23 @@ reg_meets_class_p (reg, class)
|| reg_class_subset_p (class, rclass)); || reg_class_subset_p (class, rclass));
} }
/* Update the class of QTY assuming that REG is being tied to it. */ /* Update the class of QTYNO assuming that REG is being tied to it. */
static void static void
update_qty_class (qty, reg) update_qty_class (qtyno, reg)
int qty; int qtyno;
int reg; int reg;
{ {
enum reg_class rclass = reg_preferred_class (reg); enum reg_class rclass = reg_preferred_class (reg);
if (reg_class_subset_p (rclass, qty_min_class[qty])) if (reg_class_subset_p (rclass, qty[qtyno].min_class))
qty_min_class[qty] = rclass; qty[qtyno].min_class = rclass;
rclass = reg_alternate_class (reg); rclass = reg_alternate_class (reg);
if (reg_class_subset_p (rclass, qty_alternate_class[qty])) if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
qty_alternate_class[qty] = rclass; qty[qtyno].alternate_class = rclass;
if (REG_CHANGES_SIZE (reg)) if (REG_CHANGES_SIZE (reg))
qty_changes_size[qty] = 1; qty[qtyno].changes_size = 1;
} }
/* Handle something which alters the value of an rtx REG. /* Handle something which alters the value of an rtx REG.
...@@ -1870,7 +1855,7 @@ reg_is_born (reg, birth) ...@@ -1870,7 +1855,7 @@ reg_is_born (reg, birth)
/* If this register has a quantity number, show that it isn't dead. */ /* If this register has a quantity number, show that it isn't dead. */
if (reg_qty[regno] >= 0) if (reg_qty[regno] >= 0)
qty_death[reg_qty[regno]] = -1; qty[reg_qty[regno]].death = -1;
} }
} }
...@@ -1931,7 +1916,7 @@ wipe_dead_reg (reg, output_p) ...@@ -1931,7 +1916,7 @@ wipe_dead_reg (reg, output_p)
} }
else if (reg_qty[regno] >= 0) else if (reg_qty[regno] >= 0)
qty_death[reg_qty[regno]] = 2 * this_insn_number + output_p; qty[reg_qty[regno]].death = 2 * this_insn_number + output_p;
} }
/* Find a block of SIZE words of hard regs in reg_class CLASS /* Find a block of SIZE words of hard regs in reg_class CLASS
...@@ -1940,18 +1925,18 @@ wipe_dead_reg (reg, output_p) ...@@ -1940,18 +1925,18 @@ wipe_dead_reg (reg, output_p)
and still free between insn BORN_INDEX and insn DEAD_INDEX, and still free between insn BORN_INDEX and insn DEAD_INDEX,
and return the number of the first of them. and return the number of the first of them.
Return -1 if such a block cannot be found. Return -1 if such a block cannot be found.
If QTY crosses calls, insist on a register preserved by calls, If QTYNO crosses calls, insist on a register preserved by calls,
unless ACCEPT_CALL_CLOBBERED is nonzero. unless ACCEPT_CALL_CLOBBERED is nonzero.
If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested
register is available. If not, return -1. */ register is available. If not, return -1. */
static int static int
find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
born_index, dead_index) born_index, dead_index)
enum reg_class class; enum reg_class class;
enum machine_mode mode; enum machine_mode mode;
int qty; int qtyno;
int accept_call_clobbered; int accept_call_clobbered;
int just_try_suggested; int just_try_suggested;
int born_index, dead_index; int born_index, dead_index;
...@@ -1972,12 +1957,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -1972,12 +1957,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
/* Don't let a pseudo live in a reg across a function call /* Don't let a pseudo live in a reg across a function call
if we might get a nonlocal goto. */ if we might get a nonlocal goto. */
if (current_function_has_nonlocal_label if (current_function_has_nonlocal_label
&& qty_n_calls_crossed[qty] > 0) && qty[qtyno].n_calls_crossed > 0)
return -1; return -1;
if (accept_call_clobbered) if (accept_call_clobbered)
COPY_HARD_REG_SET (used, call_fixed_reg_set); COPY_HARD_REG_SET (used, call_fixed_reg_set);
else if (qty_n_calls_crossed[qty] == 0) else if (qty[qtyno].n_calls_crossed == 0)
COPY_HARD_REG_SET (used, fixed_reg_set); COPY_HARD_REG_SET (used, fixed_reg_set);
else else
COPY_HARD_REG_SET (used, call_used_reg_set); COPY_HARD_REG_SET (used, call_used_reg_set);
...@@ -2009,7 +1994,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -2009,7 +1994,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
#endif #endif
#ifdef CLASS_CANNOT_CHANGE_SIZE #ifdef CLASS_CANNOT_CHANGE_SIZE
if (qty_changes_size[qty]) if (qty[qtyno].changes_size)
IOR_HARD_REG_SET (used, IOR_HARD_REG_SET (used,
reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]); reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
#endif #endif
...@@ -2024,10 +2009,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -2024,10 +2009,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
if (just_try_suggested) if (just_try_suggested)
{ {
if (qty_phys_num_copy_sugg[qty] != 0) if (qty_phys_num_copy_sugg[qtyno] != 0)
IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qty]); IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qtyno]);
else else
IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qty]); IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qtyno]);
} }
/* If all registers are excluded, we can't do anything. */ /* If all registers are excluded, we can't do anything. */
...@@ -2044,7 +2029,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -2044,7 +2029,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
#endif #endif
if (! TEST_HARD_REG_BIT (first_used, regno) if (! TEST_HARD_REG_BIT (first_used, regno)
&& HARD_REGNO_MODE_OK (regno, mode) && HARD_REGNO_MODE_OK (regno, mode)
&& (qty_n_calls_crossed[qty] == 0 && (qty[qtyno].n_calls_crossed == 0
|| accept_call_clobbered || accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
{ {
...@@ -2072,12 +2057,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -2072,12 +2057,12 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
/* If it would be profitable to allocate a call-clobbered register /* If it would be profitable to allocate a call-clobbered register
and save and restore it around calls, do that. */ and save and restore it around calls, do that. */
if (just_try_suggested && qty_phys_num_copy_sugg[qty] != 0 if (just_try_suggested && qty_phys_num_copy_sugg[qtyno] != 0
&& qty_phys_num_sugg[qty] != 0) && qty_phys_num_sugg[qtyno] != 0)
{ {
/* Don't try the copy-suggested regs again. */ /* Don't try the copy-suggested regs again. */
qty_phys_num_copy_sugg[qty] = 0; qty_phys_num_copy_sugg[qtyno] = 0;
return find_free_reg (class, mode, qty, accept_call_clobbered, 1, return find_free_reg (class, mode, qtyno, accept_call_clobbered, 1,
born_index, dead_index); born_index, dead_index);
} }
...@@ -2088,10 +2073,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested, ...@@ -2088,10 +2073,10 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
if (! accept_call_clobbered if (! accept_call_clobbered
&& flag_caller_saves && flag_caller_saves
&& ! just_try_suggested && ! just_try_suggested
&& qty_n_calls_crossed[qty] != 0 && qty[qtyno].n_calls_crossed != 0
&& CALLER_SAVE_PROFITABLE (qty_n_refs[qty], qty_n_calls_crossed[qty])) && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs, qty[qtyno].n_calls_crossed))
{ {
i = find_free_reg (class, mode, qty, 1, 0, born_index, dead_index); i = find_free_reg (class, mode, qtyno, 1, 0, born_index, dead_index);
if (i >= 0) if (i >= 0)
caller_save_needed = 1; caller_save_needed = 1;
return i; return i;
......
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