Start putting the vreg stuff back in; vregs are now assigned (but we're not in
authorDavid Given <dg@cowlark.com>
Thu, 12 Jan 2017 22:29:23 +0000 (23:29 +0100)
committerDavid Given <dg@cowlark.com>
Thu, 12 Jan 2017 22:29:23 +0000 (23:29 +0100)
elementary form yet).

mach/proto/mcg/basicblock.h
mach/proto/mcg/build.lua
mach/proto/mcg/hop.c
mach/proto/mcg/hop.h
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_assignvregs.c [new file with mode: 0644]
mach/proto/mcg/procedure.c
mach/proto/mcg/reg.h

index 00298f6..6edafad 100644 (file)
@@ -21,6 +21,9 @@ struct basicblock
     PMAPOF(struct ir, struct ir) imports;
     PMAPOF(struct ir, struct ir) exports;
 
+    struct hashtable* inputmapping;
+    struct hashtable* outputmapping;
+
     bool is_fake : 1;
     bool is_root : 1;
     bool is_terminated : 1;
index a2ed528..df06844 100644 (file)
@@ -45,6 +45,9 @@ definerule("build_mcg",
                                headers,
                                tables, -- for .h file
                        },
+                       vars = {
+                               ["+cflags"] = "-Werror"
+                       }
                }
        end
 )
index 1d9e857..5899275 100644 (file)
@@ -187,36 +187,6 @@ void hop_walk(hop_walker_t* callback, void* user)
     }
 }
 
-static void print_header(char k, struct hop* hop)
-{
-    int i;
-
-    tracef(k, "%c: %d", k, hop->id);
-    if (hop->ir)
-        tracef(k, " from $%d", hop->ir->id);
-    tracef(k, ":");
-
-    for (i=0; i<hop->inputs.count; i++)
-    {
-        struct value* value = hop->inputs.item[i];
-        tracef(k, " r$%d:%d", value->ir->id, value->subid);
-    }
-
-    for (i=0; i<hop->outputs.count; i++)
-    {
-        struct value* value = hop->outputs.item[i];
-        tracef(k, " w$%d:%d", value->ir->id, value->subid);
-    }
-
-    for (i=0; i<hop->throughs.count; i++)
-    {
-        struct value* value = hop->throughs.item[i];
-        tracef(k, " =$%d:%d", value->ir->id, value->subid);
-    }
-
-    tracef(k, " ");
-}
-
 static char* appendf(const char* fmt, ...)
 {
     int n;
@@ -243,6 +213,49 @@ static char* appendf(const char* fmt, ...)
     return p;
 }
 
+void appendvalue(struct hop* hop, struct value* value)
+{
+    struct vreg* vreg;
+
+    if (hop->vregmapping && ((vreg = hashtable_get(hop->vregmapping, value))))
+        appendf("%%%d", vreg->id);
+    else
+        appendf("$%d:%d", value->ir->id, value->subid);
+}
+
+static void appendheader(struct hop* hop)
+{
+    int i;
+
+    appendf("%d", hop->id);
+    if (hop->ir)
+        appendf(" from $%d", hop->ir->id);
+    appendf(":");
+
+    for (i=0; i<hop->inputs.count; i++)
+    {
+        struct value* value = hop->inputs.item[i];
+        appendf(" r");
+        appendvalue(hop, value);
+    }
+
+    for (i=0; i<hop->outputs.count; i++)
+    {
+        struct value* value = hop->outputs.item[i];
+        appendf(" w");
+        appendvalue(hop, value);
+    }
+
+    for (i=0; i<hop->throughs.count; i++)
+    {
+        struct value* value = hop->throughs.item[i];
+        appendf(" =");
+        appendvalue(hop, value);
+    }
+
+    appendf(" ");
+}
+
 char* hop_render(struct hop* hop)
 {
     int i;
@@ -279,17 +292,7 @@ char* hop_render(struct hop* hop)
 
                        case INSEL_VREG:
             {
-                struct value* value = insel->u.value;
-                #if 0
-                struct hreg* hreg = pmap_findright(&hop->regsin, vreg);
-                if (!hreg)
-                    hreg = pmap_findright(&hop->regsout, vreg);
-                if (hreg)
-                    appendf("%s", hreg->brd->names[insel->index]);
-                else
-                    appendf("%%%d.%d", vreg->id, insel->index);
-                #endif
-                appendf("$%d:%d", value->ir->id, value->subid);
+                appendvalue(hop, insel->u.value);
                 if (insel->index)
                     appendf(".%d", insel->index);
                                break;
@@ -357,11 +360,19 @@ void hop_print(char k, struct hop* hop)
        int i;
        bool soi = false;
     char* p;
+    char* header;
+
+    appendf(""); /* ensure the buffer has been allocated */
+    bufferlen = 0;
+       buffer[0] = '\0';
+
+    appendheader(hop);
+    header = strdup(buffer);
 
     hop_render(hop);
 
     p = strtok(buffer, "\n");
-    print_header(k, hop);
+    tracef(k, "%c: %s", k, header);
     while (p)
     {
         tracef(k, "%s", p);
@@ -369,7 +380,7 @@ void hop_print(char k, struct hop* hop)
         if (p)
         {
             tracef(k, "\n");
-            print_header(k, hop);
+            tracef(k, "%c: %s", k, header);
         }
     }
     tracef(k, "\n");
index b97ed9b..6a97d85 100644 (file)
@@ -43,6 +43,8 @@ struct hop
        ARRAYOF(struct value) inputs;
        ARRAYOF(struct value) outputs;
        ARRAYOF(struct value) throughs;
+
+       struct hashtable* vregmapping;
 };
 
 extern struct hop* new_hop(struct basicblock* bb, struct ir* ir);
index e8b4659..19f2590 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <assert.h>
+#include "hashtable.h"
 #include "flt_arith.h"
 #include "em_arith.h"
 #include "em_label.h"
@@ -30,7 +31,6 @@
 #include "graph.h"
 #include "tables.h"
 #include "mcgg.h"
-#include "hashtable.h"
 #include "set.h"
 #include "bigraph.h"
 
@@ -107,6 +107,7 @@ extern void tb_fileend(void);
 extern void tb_procedure(void);
 extern void tb_regvar(struct procedure* proc, arith offset, int size, int type, int priority);
 
+extern void pass_assign_vregs(void);
 extern void pass_convert_inputs_to_phis(void);
 extern void pass_convert_locals_to_ssa(void);
 extern void pass_convert_nonlocal_phis(void);
diff --git a/mach/proto/mcg/pass_assignvregs.c b/mach/proto/mcg/pass_assignvregs.c
new file mode 100644 (file)
index 0000000..57bd2f4
--- /dev/null
@@ -0,0 +1,103 @@
+#include "mcg.h"
+
+static const struct hashtable empty_hashtable_of_values = HASHTABLE_OF_VALUES;
+
+static struct basicblock* current_bb;
+
+static int vregcount = 0;
+
+static void create_and_map_vreg(struct hashtable* mapping, struct value* value)
+{
+    struct vreg* vreg = heap_alloc(&proc_heap, 1, sizeof(*vreg));
+    vreg->id = vregcount++;
+    vreg->value = value;
+
+    assert(!hashtable_get(mapping, value));
+    hashtable_put(mapping, value, vreg);
+}
+
+static bool hop_reads_value(struct hop* hop, struct value* value)
+{
+    int i;
+
+    for (i=0; i<hop->inputs.count; i++)
+        if (value_comparison_function(hop->inputs.item[i], value))
+            return true;
+
+    for (i=0; i<hop->throughs.count; i++)
+        if (value_comparison_function(hop->throughs.item[i], value))
+            return true;
+
+    return false;
+}
+
+static void assign_vregs(void)
+{
+    int i, j;
+    struct hashtable* previous_mapping;
+    struct hashtable* current_mapping;
+    struct hop* hop;
+
+    /* Preload the mapping from the first hop. It might be a move, but that
+     * does no harm. */
+
+    hop = current_bb->hops.item[0];
+    current_bb->inputmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));
+    *current_bb->inputmapping = empty_hashtable_of_values;
+    hashtable_empty(current_bb->inputmapping);
+    for (i=0; i<hop->inputs.count; i++)
+        create_and_map_vreg(current_bb->inputmapping, hop->inputs.item[i]);
+    for (i=0; i<hop->throughs.count; i++)
+        create_and_map_vreg(current_bb->inputmapping, hop->throughs.item[i]);
+
+    previous_mapping = current_bb->inputmapping;
+    for (i=0; i<current_bb->hops.count; i++)
+    {
+        hop = current_bb->hops.item[i];
+
+        /* TODO: clone vregs here */
+
+        /* Copy the previous mapping to this hop, pruning out any unused values. */
+
+        current_mapping = hop->vregmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));;
+        *current_mapping = empty_hashtable_of_values;
+        {
+            struct hashtable_iterator hit = {};
+            while (hashtable_next(previous_mapping, &hit))
+            {
+                struct value* value = hit.key;
+                if (hop_reads_value(hop, value))
+                    hashtable_put(current_mapping, value, hit.value);
+            }
+        }
+
+        /* Create vregs for any new outputs. */
+
+        for (j=0; j<hop->outputs.count; j++)
+            create_and_map_vreg(current_mapping, hop->outputs.item[j]);
+
+        /* And move on to the next one. */
+
+        previous_mapping = current_mapping;
+    }
+
+    current_bb->outputmapping = previous_mapping;
+}
+
+void pass_assign_vregs(void)
+{
+    int i;
+
+    vregcount = 0;
+
+    for (i=0; i<dominance.preorder.count; i++)
+    {
+        current_bb = dominance.preorder.item[i];
+        assign_vregs();
+    }
+
+    tracef('V', "V: finished vreg assignment with %d vregs\n", vregcount);
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
index c9e3757..be59958 100644 (file)
@@ -185,6 +185,8 @@ void procedure_compile(struct procedure* proc)
     print_hops('7');
     pass_live_value_analysis();
     print_hops('8');
+    pass_assign_vregs();
+    print_hops('9');
 #if 0
     pass_split_live_ranges();
     pass_determine_vreg_usage();
index 9a54cec..60edd1c 100644 (file)
@@ -13,6 +13,12 @@ struct hreg
     ARRAYOF(struct hreg) aliases;
 };
 
+struct vreg
+{
+    int id;
+    struct value* value;
+};
+
 extern struct hreg* new_hreg(const struct burm_register_data* brd);
 extern struct hreg* new_stacked_hreg(uint32_t type);