Precisely one stack hreg gets allocated for each vreg/congruence group for
authorDavid Given <dg@cowlark.com>
Sat, 8 Sep 2018 16:59:55 +0000 (18:59 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 8 Sep 2018 16:59:55 +0000 (18:59 +0200)
eviction; this prevents us from having to worry about moving values from stack
slot to stack slot, which is hard.

mach/mips/mcg/platform.c
mach/powerpc/mcg/platform.c
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_phigroups.c
mach/proto/mcg/pass_registerallocator.c
mach/proto/mcg/reg.h

index ab00326..0b7ee65 100644 (file)
@@ -127,7 +127,7 @@ struct hop* platform_epilogue(void)
        return hop;
 }
 
-struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
+struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest)
 {
     struct hop* hop = new_hop(bb, NULL);
 
@@ -280,6 +280,8 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
                     goto nomove;
             }
         }
+        else if (src->is_stacked && dest->is_stacked)
+            fatal("tried to move stacked object %%%d of type 0x%x from %s to %s", vreg->id, type, src->id, dest->id);
         else
             goto nomove;
     }
@@ -294,6 +296,7 @@ struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg*
 {
     struct hop* hop = new_hop(bb, NULL);
 
+       tracef('R', "R: swap of %s to %s\n", src->id, dest->id);
     assert(!src->is_stacked);
     assert(!dest->is_stacked);
     assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS));
index 65b158c..7067972 100644 (file)
@@ -128,7 +128,7 @@ struct hop* platform_epilogue(void)
        return hop;
 }
 
-struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
+struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest)
 {
     struct hop* hop = new_hop(bb, NULL);
 
index 540f579..b813b79 100644 (file)
@@ -123,7 +123,7 @@ extern void pass_wire_up_return_values(void);
 extern void platform_calculate_offsets(void);
 extern struct hop* platform_prologue(void);
 extern struct hop* platform_epilogue(void);
-extern struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest);
+extern struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest);
 extern struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest);
 extern const char* platform_label(const char* label);
 
index e57378a..abb8924 100644 (file)
@@ -10,7 +10,8 @@ static void make_phimap(void)
        for (i=0; i<cfg.preorder.count; i++)
        {
                struct basicblock* bb = cfg.preorder.item[i];
-               
+
+               /* Registers imported through a phi can come from multiple locations. */
                for (j=0; j<bb->phis.count; j++)
                {
                        struct vreg* vreg = bb->phis.item[j].left;
index a5436bc..0a25fc4 100644 (file)
@@ -386,16 +386,28 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s
     for (i=0; i<hregs.count; i++)
     {
         hreg = hregs.item[i];
-        if ((hreg->attrs & srctype) &&
+        if (!hreg->is_stacked && (hreg->attrs & srctype) &&
             allocatable_through(hreg, vreg))
         {
             goto found;
         }
     }
 
-    /* No more registers --- allocate a stack slot. */
-
-    hreg = new_stacked_hreg(srctype);
+    /* No more registers --- allocate a stack slot. Ensure that we use the same stack
+     * slot for this vreg throughout the function. */
+
+       hreg = vreg->evicted;
+       if (!hreg)
+       {
+               if (vreg->congruence)
+                       hreg = vreg->evicted = vreg->congruence->evicted;
+               if (!hreg)
+               {
+                       hreg = vreg->evicted = new_stacked_hreg(srctype);
+                       if (vreg->congruence)
+                               vreg->congruence->evicted = hreg;
+               }
+       }
     array_append(&hregs, hreg);
 
 found:
@@ -617,7 +629,8 @@ static int insert_moves(struct basicblock* bb, int index,
         {
             /* Copy. */
 
-            hop = platform_move(bb, src, dest);
+                       struct vreg* vreg = pmap_findleft(srcregs, src);
+            hop = platform_move(bb, vreg, src, dest);
             pmap_remove(&copies, src, dest);
         }
         else
@@ -710,13 +723,17 @@ static void insert_phi_copies(void)
 
             for (k=0; k<bb->regsin.count; k++)
             {
-                struct hreg*hreg = bb->regsin.item[k].left;
+                struct hreg* hreg = bb->regsin.item[k].left;
                 struct vreg* vreg = bb->regsin.item[k].right;
                 struct hreg* src = pmap_findright(prevbb->regsout, vreg);
                 if (!pmap_findleft(&bb->phis, vreg))
                 {
                     tracef('R', "R: input map %%%d (%s) -> (%s)\n",
                         vreg->id, src->id, hreg->id);
+                    if ((src->id != hreg->id) && src->is_stacked && hreg->is_stacked)
+                        fatal("vreg %%%d is stacked in %s on entry to %s, but is passed in in %s from %s",
+                            vreg->id, hreg->id, bb->name,
+                            src->id, prevbb->name);
 
                     pmap_add(&destregs, hreg, vreg);
                 }
index 00c8220..b3f2314 100644 (file)
@@ -9,6 +9,7 @@ struct phicongruence
     ARRAYOF(struct vreg) vregs;
     ARRAYOF(struct hop) definitions;
     uint32_t type;
+    struct hreg* evicted; /* stack slot to evict to */
 };
 
 struct hreg
@@ -28,6 +29,7 @@ struct vreg
     struct phicongruence* congruence;
     struct hop* defined;
     ARRAYOF(struct hop) used;
+    struct hreg* evicted; /* stack slot to evict to */
 };
 
 typedef PMAPOF(struct hreg, struct vreg) register_assignment_t;