2005-03-20 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / mini / linear-scan.c
index 0e3c37283a7a6da13f9719945c5aea41b03457e4..16728389f31f22dff293c890e4d6a27755740795 100644 (file)
@@ -63,7 +63,7 @@ mono_varlist_sort (MonoCompile *cfg, GList *list, int sort_type)
        return NULL;
 }
 
-//#define DEBUG_LSCAN
+// #define DEBUG_LSCAN
 
 void
 mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_mask)
@@ -90,7 +90,7 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
        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;
        }
@@ -107,18 +107,18 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
                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
                        printf ("EXPIR  %2d %08x %08x C%d R%d\n", amv->idx, amv->range.first_use.abs_pos, 
                                amv->range.last_use.abs_pos, amv->spill_costs, amv->reg);
 #endif
-                       active = g_list_remove_link (active, active);
-                       regs = g_list_prepend (regs, (gpointer)amv->reg);
+                       active = g_list_delete_link (active, active);
+                       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 */
 
@@ -129,7 +129,7 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
                            (!cost_driven && amv->range.last_use.abs_pos > vmv->range.last_use.abs_pos)) {
                                vmv->reg = amv->reg;
                                amv->reg = -1;
-                               active = g_list_remove_link (active, a);
+                               active = g_list_delete_link (active, a);
 
                                if (cost_driven)
                                        active = mono_varlist_insert_sorted (cfg, active, vmv, 2);      
@@ -154,11 +154,11 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
 
                        g_assert (regs);
 
-                       vmv->reg = (int)regs->data;
+                       vmv->reg = GPOINTER_TO_INT (regs->data);
 
                        used_regs |= 1LL << vmv->reg;
 
-                       regs = g_list_remove_link (regs, regs);
+                       regs = g_list_delete_link (regs, regs);
 
 #ifdef DEBUG_LSCAN
                        printf ("ADD    %2d %08x %08x C%d R%d\n",  vmv->idx, 
@@ -188,7 +188,7 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
                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)
@@ -209,6 +209,11 @@ mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_ma
 
        *used_mask |= used_regs;
 
+#ifdef DEBUG_LSCAN
+       if (cfg->verbose_level > 2)
+               printf ("EXIT: final used mask: %08x\n", *used_mask);
+#endif
+
        g_list_free (regs);
        g_list_free (active);
        g_list_free (vars);