*/
#include "mini.h"
+#include <mono/metadata/debug-helpers.h>
GList *
mono_varlist_insert_sorted (MonoCompile *cfg, GList *list, MonoMethodVar *mv, int sort_type)
regmask_t used_regs = 0;
gboolean cost_driven;
- cost_driven = (cfg->comp_done & MONO_COMP_LOOPS);
+ cost_driven = TRUE;
#ifdef DEBUG_LSCAN
printf ("Linears scan for %s\n", mono_method_full_name (cfg->method, TRUE));
max_regs = g_list_length (regs);
for (l = regs; l; l = l->next) {
- int regnum = (int)l->data;
+ int regnum = GPOINTER_TO_INT (l->data);
g_assert (regnum < G_N_ELEMENTS (gains));
gains [regnum] = 0;
}
while (active) {
amv = (MonoMethodVar *)active->data;
- if (amv->range.last_use.abs_pos >= vmv->range.first_use.abs_pos)
+ if (amv->range.last_use.abs_pos > vmv->range.first_use.abs_pos)
break;
#ifdef DEBUG_LSCAN
amv->range.last_use.abs_pos, amv->spill_costs, amv->reg);
#endif
active = g_list_delete_link (active, active);
- regs = g_list_prepend (regs, (gpointer)amv->reg);
+ regs = g_list_prepend (regs, GINT_TO_POINTER (amv->reg));
gains [amv->reg] += amv->spill_costs;
}
-
+
if (active && g_list_length (active) == max_regs) {
/* Spill */
g_assert (regs);
- vmv->reg = (int)regs->data;
+ vmv->reg = GPOINTER_TO_INT (regs->data);
used_regs |= 1LL << vmv->reg;
vmv = l->data;
if (vmv->reg >= 0) {
- if (gains [vmv->reg] > mono_arch_regalloc_cost (cfg, vmv)) {
+ if ((gains [vmv->reg] > mono_arch_regalloc_cost (cfg, vmv)) && (cfg->varinfo [vmv->idx]->opcode != OP_REGVAR)) {
cfg->varinfo [vmv->idx]->opcode = OP_REGVAR;
cfg->varinfo [vmv->idx]->dreg = vmv->reg;
if (cfg->verbose_level > 2)
printf ("REGVAR %d C%d R%d\n", vmv->idx, vmv->spill_costs, vmv->reg);
- } else
+ } else {
+ if (cfg->verbose_level > 2)
+ printf ("COSTLY: %s R%d C%d C%d %s\n", mono_method_full_name (cfg->method, TRUE), vmv->idx, vmv->spill_costs, mono_arch_regalloc_cost (cfg, vmv), mono_arch_regname (vmv->reg));
vmv->reg = -1;
+ }
+ }
+
+ if (vmv->reg == -1) {
+ if ((vmv->range.first_use.abs_pos >> 16) == (vmv->range.last_use.abs_pos >> 16)) {
+ /*
+ * This variables is only used in a single basic block so
+ * convert it into a virtual register.
+ * FIXME: This increases register pressure in the local
+ * allocator, leading to the well known 'branches inside
+ * basic blocks screw up the allocator' problem.
+ */
+#if 0
+ cfg->varinfo [vmv->idx]->opcode = OP_REGVAR;
+ cfg->varinfo [vmv->idx]->dreg = mono_regstate_next_int (cfg->rs);
+#endif
+ }
+ else {
+ if (cfg->verbose_level > 2)
+ printf ("NOT REGVAR: %d\n", vmv->idx);
+ }
}
}