values and vregs for which we have no register class information don't default
authorDavid Given <dg@cowlark.com>
Sun, 30 Sep 2018 22:29:56 +0000 (00:29 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 30 Sep 2018 22:29:56 +0000 (00:29 +0200)
to ints now (as this was causing empty register sets when trying to coalesce an
int and a double). It seems to work now, although painfully slowly.

mach/proto/mcg/hop.c
mach/proto/mcg/ir.c
mach/proto/mcg/ir.h
mach/proto/mcg/pass_assignvregs.c
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/pass_lowerpushes.c
mach/proto/mcg/pass_registerallocator.c
mach/proto/mcg/procedure.c
mach/proto/mcg/treebuilder.c
util/mcgg/build.lua
util/mcgg/registers.h

index 0c0f88b..c96af16 100644 (file)
@@ -318,7 +318,9 @@ static struct vreg* actual(struct vreg* vreg)
 
 void appendvreg(struct vreg* vreg)
 {
-    appendf("($%d:%d=%%%d", vreg->value->ir->id, vreg->value->subid, vreg->id);
+    appendf("($%d:%d=%%%d:%s",
+               vreg->value->ir->id, vreg->value->subid, vreg->id,
+               vreg->regclass ? vreg->regclass->name : "?");
     if (vreg->hreg != -1)
         appendf("=R%d", vreg->hreg);
     if (vreg->is_spilt)
@@ -357,6 +359,8 @@ static void appendheader(struct hop* hop)
                 if (usage->corrupted)
                     appendf("!");
                 appendf("$%d:%d", value->ir->id, value->subid);
+                if (value->regclass != UNASSIGNED_REGCLASS)
+                    appendf(",%d", value->regclass);
             }
         }
     }
index e6e5d6b..c6a9160 100644 (file)
@@ -22,6 +22,7 @@ struct ir* new_ir0(int opcode, int size)
 {
        struct ir* ir = calloc(1,  sizeof(struct ir));
     ir->value.ir = ir;
+    ir->value.regclass = UNASSIGNED_REGCLASS;
        ir->id = next_id++;
        ir->opcode = opcode;
        ir->size = size;
index 0da01a0..4389766 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "ircodes.h"
 
+#define UNASSIGNED_REGCLASS (-1)
+
 struct value
 {
        struct ir* ir;
index 3a6f301..de82075 100644 (file)
@@ -51,11 +51,22 @@ static bool hop_reads_value(struct hop* hop, struct value* value)
 
 static void setup_regclass(struct vreg* vreg, struct value* value)
 {
-    const struct burm_regclass_data* regclass = &burm_regclass_data[value->regclass];
-    assert(!vreg->regclass || (vreg->regclass == regclass));
-
-    if (!vreg->regclass)
+    const struct burm_regclass_data* regclass =
+        (value->regclass == UNASSIGNED_REGCLASS)
+        ? NULL
+        : &burm_regclass_data[value->regclass];
+    assert(!vreg->regclass || !regclass || (vreg->regclass == regclass));
+
+       tracef('V', "V: %%%d has class %s; value $%d has class %s\n",
+               vreg->id,
+               vreg->regclass ? vreg->regclass->name : "?",
+               value->ir->id,
+               regclass ? regclass->name : "?");
+
+    if (!vreg->regclass && regclass)
     {
+        tracef('V', "V: assigning register class %s to %%%d from $%d\n",
+            regclass->name, vreg->id, value->ir->id);
         memcpy(vreg->registers, regclass->bitmap, sizeof(burm_register_bitmap_t));
         vreg->regclass = regclass;
     }
index 2631c1d..a9f5f87 100644 (file)
@@ -141,6 +141,7 @@ static struct insn* walk_instructions(struct burm_node* node, int goal)
     int i;
 
     insn->value.ir = current_ir;
+    insn->value.regclass = UNASSIGNED_REGCLASS;
     /* hop IDs count in preorder, so the result is always in $thing:0. */
     insn->value.subid = hop_id++;
 
index c990f86..3550d8c 100644 (file)
@@ -108,6 +108,7 @@ static void consider_push(struct ir* ir)
                        new_wordir(delta)
                );
                ir->left->root = ir->left->left->root = ir->left->right->root = ir->root;
+               ir->left->bb = ir->left->left->bb = ir->left->right->bb = current_bb;
                ir->right = value_ir;
 
                delta += ir->size;
@@ -119,6 +120,7 @@ static void consider_push(struct ir* ir)
 
        ir = new_ir1(IR_STACKADJUST, EM_pointersize, new_wordir(-delta));
        ir->left->root = ir->root = ir;
+       ir->left->bb = ir->bb = current_bb;
        array_insert(&current_bb->irs, ir, runstart);
        cursor++;
 }
index 8678b38..d6e889d 100644 (file)
@@ -15,6 +15,16 @@ static struct graph interference;
 static struct graph affinity;
 static ARRAYOF(struct vreg) simplified;
 
+static void bitmap_trace(void* bitmap, int size)
+{
+       uint8_t* p = bitmap;
+       int bytes = ((size-1) / 8) + 1;
+       int i;
+
+       for (i=0; i<bytes; i++)
+               tracef('R', "%02x ", p[i]);
+}
+
 static struct vreg* actual(struct vreg* vreg)
 {
     if (!vreg)
@@ -28,6 +38,22 @@ static void coalesce(struct vreg* vmaster, struct vreg* vslave)
 {
     vmaster = actual(vmaster);
     vslave = actual(vslave);
+    if (tracing('R'))
+    {
+        if (vmaster->regclass)
+        {
+                       tracef('R', "R: master is %10s ", vmaster->regclass->name);
+                       bitmap_trace(vmaster->registers, burm_register_count);
+                       tracef('R', "\n");
+               }
+               if (vslave->regclass)
+               {
+                       tracef('R', "R:  slave is %10s ", vslave->regclass->name);
+                       bitmap_trace(vslave->registers, burm_register_count);
+                       tracef('R', "\n");
+               }
+    }
+
     if (vmaster->regclass && vslave->regclass)
     {
         bitmap_and(vmaster->registers, burm_register_count, vslave->registers);
@@ -101,7 +127,12 @@ static void generate_graph(void)
                 }
 
                 if (hop->is_move && invreg1 && outvreg1)
+                {
+                    tracef('R', "R: adding affinity edge between %%%d and %%%d:\n",
+                        invreg1->id, outvreg1->id);
+                    hop_print('R', hop);
                     graph_add_edge(&affinity, invreg1, outvreg1);
+                               }
             }
 
             /* Ensure that registers which are constrained to be in the same hreg for input
index f7dc813..418d099 100644 (file)
@@ -106,7 +106,9 @@ static void print_hops(char k)
             {
                 struct value* value = hit.key;
                 struct vreg* vreg = hit.value;
-                tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id);
+                tracef(k, " $%d.%d->%%%d(%s)",
+                    value->ir->id, value->subid, vreg->id,
+                    vreg->regclass ? vreg->regclass->name : "?");
             }
             tracef(k, "\n");
         }
@@ -119,7 +121,9 @@ static void print_hops(char k)
             {
                 struct value* value = hit.key;
                 struct vreg* vreg = hit.value;
-                tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id);
+                tracef(k, " $%d.%d->%%%d(%s)",
+                                       value->ir->id, value->subid, vreg->id,
+                                       vreg->regclass ? vreg->regclass->name : "?");
             }
             tracef(k, "\n");
         }
index 0e9c9a8..d0e8fe9 100644 (file)
@@ -1859,7 +1859,7 @@ static void emit_jumptable(struct ir* targetvalue, struct jumptable* jumptable)
        materialise_stack();
     while (hashtable_next(&jumptable->targets, &hit))
        {
-               int value = (int) hit.key;
+               int value = (int)(intptr_t) hit.key;
                struct basicblock* target = hit.value;
                struct basicblock* nextblock = bb_get(NULL);
 
index 1bd242a..ebb4e72 100644 (file)
@@ -47,6 +47,7 @@ cprogram {
                matching(filenamesof("+yacc"), "%.c$")
        },
        deps = {
+               "./registers.h",
                "./iburg.h",
                "+lib",
                "+yacc",
index 53145f1..7162a7e 100644 (file)
@@ -30,7 +30,6 @@ extern struct reg* makereg(const char* name);
 extern void setregnames(struct reg* reg, struct stringlist* names);
 extern void addregattr(struct reg* reg, const char* regattr);
 extern void addregusage(struct reg* reg, struct stringlist* uses);
-extern struct regattr* getregattr(const char* name);
 
 extern void analyse_registers(void);
 
@@ -38,6 +37,7 @@ extern void emitregisterattrs(void);
 extern void emitregisters(void);
 
 extern struct regattr* findregattr(const char* name);
+extern struct regattr* makeregattr(const char* name);
 
 #endif