\f
/* Perform allocation of pseudo-registers not allocated by local_alloc.
- FILE is a file to output debugging information on,
- or zero if such output is not desired.
Return value is nonzero if reload failed
and we must not do any more for this function. */
static int
-global_alloc (FILE *file)
+global_alloc (void)
{
int retval;
#ifdef ELIMINABLE_REGS
/* Establish mappings from register number to allocation number
and vice versa. In the process, count the allocnos. */
- reg_allocno = xmalloc (max_regno * sizeof (int));
+ reg_allocno = XNEWVEC (int, max_regno);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
reg_allocno[i] = -1;
/* Initialize the shared-hard-reg mapping
from the list of pairs that may share. */
- reg_may_share = xcalloc (max_regno, sizeof (int));
+ reg_may_share = XCNEWVEC (int, max_regno);
for (x = regs_may_share; x; x = XEXP (XEXP (x, 1), 1))
{
int r1 = REGNO (XEXP (x, 0));
else
reg_allocno[i] = -1;
- allocno = xcalloc (max_allocno, sizeof (struct allocno));
+ allocno = XCNEWVEC (struct allocno, max_allocno);
for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_allocno[i] >= 0)
/* We used to use alloca here, but the size of what it would try to
allocate would occasionally cause it to exceed the stack limit and
cause unpredictable core dumps. Some examples were > 2Mb in size. */
- conflicts = xcalloc (max_allocno * allocno_row_words, sizeof (INT_TYPE));
+ conflicts = XCNEWVEC (INT_TYPE, max_allocno * allocno_row_words);
- allocnos_live = xmalloc (allocno_row_words * sizeof (INT_TYPE));
+ allocnos_live = XNEWVEC (INT_TYPE, allocno_row_words);
/* If there is work to be done (at least one reg to allocate),
perform global conflict analysis and allocate the regs. */
/* Determine the order to allocate the remaining pseudo registers. */
- allocno_order = xmalloc (max_allocno * sizeof (int));
+ allocno_order = XNEWVEC (int, max_allocno);
for (i = 0; i < (size_t) max_allocno; i++)
allocno_order[i] = i;
prune_preferences ();
- if (file)
- dump_conflicts (file);
+ if (dump_file)
+ dump_conflicts (dump_file);
/* Try allocating them, one by one, in that order,
except for parameters marked with reg_live_length[regno] == -2. */
int *block_start_allocnos;
/* Make a vector that mark_reg_{store,clobber} will store in. */
- regs_set = xmalloc (max_parallel * sizeof (rtx) * 2);
+ regs_set = XNEWVEC (rtx, max_parallel * 2);
- block_start_allocnos = xmalloc (max_allocno * sizeof (int));
+ block_start_allocnos = XNEWVEC (int, max_allocno);
FOR_EACH_BB (b)
{
{
int i;
int num;
- int *allocno_to_order = xmalloc (max_allocno * sizeof (int));
+ int *allocno_to_order = XNEWVEC (int, max_allocno);
/* Scan least most important to most important.
For each allocno, remove from preferences registers that cannot be used,
so we can use it instead. */
if (best_reg < 0 && !retrying
/* Let's not bother with multi-reg allocnos. */
- && allocno[num].size == 1)
+ && allocno[num].size == 1
+ && REG_BASIC_BLOCK (allocno[num].reg) == REG_BLOCK_GLOBAL)
{
/* Count from the end, to find the least-used ones first. */
for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
variables so as to avoid excess precision problems that occur
on an i386-unknown-sysv4.2 (unixware) host. */
- double tmp1 = ((double) local_reg_freq[regno]
+ double tmp1 = ((double) local_reg_freq[regno] * local_reg_n_refs[regno]
/ local_reg_live_length[regno]);
- double tmp2 = ((double) allocno[num].freq
+ double tmp2 = ((double) allocno[num].freq * allocno[num].n_refs
/ allocno[num].live_length);
if (tmp1 < tmp2)
/* Hard reg REGNO was used less in total by local regs
than it would be used by this one allocno! */
int k;
+ if (dump_file)
+ {
+ fprintf (dump_file, "Regno %d better for global %d, ",
+ regno, allocno[num].reg);
+ fprintf (dump_file, "fr:%d, ll:%d, nr:%d ",
+ allocno[num].freq, allocno[num].live_length,
+ allocno[num].n_refs);
+ fprintf (dump_file, "(was: fr:%d, ll:%d, nr:%d)\n",
+ local_reg_freq[regno],
+ local_reg_live_length[regno],
+ local_reg_n_refs[regno]);
+ }
+
for (k = 0; k < max_regno; k++)
if (reg_renumber[k] >= 0)
{
= r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (k)];
if (regno >= r && regno < endregno)
- reg_renumber[k] = -1;
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Local Reg %d now on stack\n", k);
+ reg_renumber[k] = -1;
+ }
}
best_reg = regno;
int i;
int *rts_order;
- rts_order = xmalloc (sizeof (int) * (n_basic_blocks - NUM_FIXED_BLOCKS));
+ rts_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
post_order_compute (rts_order, false);
for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
BB_INFO_BY_INDEX (rts_order [i])->rts_number = i;
}
/* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */
-static void
+static unsigned int
rest_of_handle_global_alloc (void)
{
bool failure;
pass fixing up any insns that are invalid. */
if (optimize)
- failure = global_alloc (dump_file);
+ failure = global_alloc ();
else
{
build_insn_chain (get_insns ());
gcc_assert (reload_completed || failure);
reload_completed = !failure;
+ return 0;
}
struct tree_opt_pass pass_global_alloc =