Actually, I don't need vregs: hops work just as well. Particularly if I
authorDavid Given <dg@cowlark.com>
Tue, 27 Sep 2016 21:38:47 +0000 (23:38 +0200)
committerDavid Given <dg@cowlark.com>
Tue, 27 Sep 2016 21:38:47 +0000 (23:38 +0200)
restructure things so that I don't need to walk the blasted ir / burg tree
every time I look at an instruction.

mach/proto/mcg/build.lua
mach/proto/mcg/hop.c
mach/proto/mcg/hop.h
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/table
mach/proto/mcg/vreg.c [deleted file]
mach/proto/mcg/vreg.h [deleted file]

index dc35042..0626c4a 100644 (file)
@@ -28,7 +28,6 @@ cprogram {
        vars = {
                ["+cflags"] = {
                        "-Werror-implicit-function-declaration",
-                       "-Wint-conversion"
                }
        }
 }
index 9a87a34..510190c 100644 (file)
@@ -1,6 +1,6 @@
 #include "mcg.h"
 
-static char outbuf[256];
+static int hop_count = 1;
 static struct hop* current_hop;
 
 static const struct burm_emitter_data emitter_data;
@@ -8,85 +8,97 @@ static const struct burm_emitter_data emitter_data;
 struct hop* new_hop(int insn_no, struct ir* ir)
 {
        struct hop* hop = calloc(1, sizeof *hop);
+       hop->id = hop_count++;
        hop->insn_no = insn_no;
        hop->ir = ir;
        return hop;
 }
 
-static void append(const char* fmt, ...)
+static struct insel* new_insel(enum insel_type type)
 {
-       va_list ap;
-       
-       va_start(ap, fmt);
-       vsprintf(outbuf + strlen(outbuf), fmt, ap);
-       va_end(ap);
+       struct insel* insel = calloc(1, sizeof(*insel));
+       insel->type = type;
+       return insel;
 }
 
-static void emit_reg(struct ir* ir)
+void hop_add_string_insel(struct hop* hop, const char* string)
 {
-       struct hop* hop = ir->hop;
-       if (hop)
-       {
-               /* Reference to another hop must be its result register. */
-               append("%%%d", hop->resultvreg->id);
-       }
-       else
-       {
-               /* ...if there is no hop, it's a fragment. */
-               const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
-        insndata->emitter(ir, &emitter_data);
-       }
+       struct insel* insel = new_insel(INSEL_STRING);
+       insel->u.string = string;
+       array_append(&hop->insels, insel);
 }
 
-static void emit_string(const char* data)
+void hop_add_reg_insel(struct hop* hop, struct hop* reg)
 {
-       append("%s", data);
+       struct insel* insel = new_insel(INSEL_REG);
+       insel->u.reg = reg;
+       array_append(&hop->insels, insel);
 }
 
-static void emit_value(struct ir* ir)
+void hop_add_value_insel(struct hop* hop, struct ir* ir)
 {
-       append("(val)");
+       struct insel* insel = new_insel(INSEL_VALUE);
+       insel->u.value = ir;
+       array_append(&hop->insels, insel);
 }
 
-static void emit_resultreg(void)
+void hop_add_eoi_insel(struct hop* hop)
 {
-       append("%%%d", current_hop->resultvreg->id);
+       struct insel* insel = new_insel(INSEL_EOI);
+       array_append(&hop->insels, insel);
 }
 
-static void emit_eoi(void)
-{
-       append("\n");
-}
-
-static const struct burm_emitter_data emitter_data =
-{
-    &emit_string,
-    &emit_reg,
-    &emit_value,
-    &emit_resultreg,
-    &emit_eoi
-};
-
 void hop_print(char k, struct hop* hop)
 {
-       char* s;
-    const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no];
+       int i;
+       bool soi = true;
 
-       current_hop = hop;
-       outbuf[0] = 0;
-       if (insndata->emitter)
+       i = 0;
+       for (i=0; i<hop->insels.count; i++)
        {
-               insndata->emitter(hop->ir, &emitter_data);
+               struct insel* insel = hop->insels.item[i];
 
-               s = strtok(outbuf, "\n");
-               do
+               if (soi)
                {
-                       tracef(k, "%c: %p: %s\n", k, hop, s);
-                       s = strtok(NULL, "\n");
+                       tracef(k, "%c: %d: ", k, hop->id);
+                       soi = false;
+               }
+
+               switch (insel->type)
+               {
+                       case INSEL_EOI:
+                               tracef(k, "\n");
+                               soi = true;
+                               break;
+
+                       case INSEL_REG:
+                               tracef(k, "%%%d", insel->u.reg->id);
+                               break;
+
+                       case INSEL_STRING:
+                               tracef(k, "%s", insel->u.string);
+                               break;
+
+                       case INSEL_VALUE:
+                       {
+                               struct ir* ir = insel->u.value;
+                               switch (ir->opcode)
+                               {
+                                       case IR_BLOCK:
+                                               tracef(k, "%s", ir->u.bvalue->name);
+                                               break;
+
+                                       case IR_LOCAL:
+                                       case IR_CONST:
+                                               tracef(k, "0x%d", ir->u.ivalue);
+                                               break;
+                               }
+                               break;
+                       }
                }
-               while (s);
        }
-       else
-               tracef(k, "%c: %p: (empty)\n", k, hop);
+
+       if (!soi)
+               tracef(k, "\n", k);
 }
 
index 2cb0c9f..8f92d89 100644 (file)
@@ -1,19 +1,43 @@
 #ifndef HOP_H
 #define HOP_H
 
+enum insel_type
+{
+       INSEL_STRING,
+       INSEL_REG,
+       INSEL_VALUE,
+       INSEL_EOI
+};
+
+struct insel
+{
+       enum insel_type type;
+       union
+       {
+               const char* string;
+               struct hop* reg;
+               struct ir* value;
+       }
+       u;
+};
+
 struct hop
 {
+       int id;
        int insn_no;
        struct ir* ir;
-       struct vreg* resultvreg;
-       ARRAYOF(struct vreg) invregs;
-       ARRAYOF(struct vreg) outvregs;
-       ARRAYOF(struct vreg) newvregs;
-       ARRAYOF(struct vreg) deadvregs;
+       struct hop* result;
+       ARRAYOF(struct hop) params;
+       ARRAYOF(struct insel) insels;
 };
 
 extern struct hop* new_hop(int insn_no, struct ir* ir);
 
+extern void hop_add_string_insel(struct hop* hop, const char* string);
+extern void hop_add_reg_insel(struct hop* hop, struct hop* reg);
+extern void hop_add_value_insel(struct hop* hop, struct ir* ir);
+extern void hop_add_eoi_insel(struct hop* hop);
+
 extern void hop_print(char k, struct hop* hop);
 
 #endif
index 746f392..8cf16f9 100644 (file)
@@ -20,7 +20,6 @@
 #include "map.h"
 #include "ir.h"
 #include "mcgg.h"
-#include "vreg.h"
 #include "hop.h"
 
 extern char em_pseu[][4];
index a2a993c..13d3d89 100644 (file)
@@ -1,6 +1,9 @@
 #include "mcg.h"
 
 static struct basicblock* current_bb;
+static struct hop* current_hop;
+
+static const struct burm_emitter_data emitter_data;
 
 void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
     const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
@@ -16,28 +19,67 @@ void burm_panic_cannot_match(struct ir* ir)
        exit(1);
 }
 
-static void walk_instructions(struct hop* hop, struct ir* ir, int goal)
+static void emit_reg(struct ir* ir)
+{
+    if (ir->hop)
+               hop_add_reg_insel(current_hop, ir->hop);
+    else
+    {
+        const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
+        if (insndata->emitter)
+            insndata->emitter(ir, &emitter_data);
+    }
+}
+
+static void emit_string(const char* data)
+{
+       hop_add_string_insel(current_hop, data);
+}
+
+static void emit_value(struct ir* ir)
+{
+       hop_add_value_insel(current_hop, ir);
+}
+
+static void emit_resultreg(void)
+{
+       hop_add_reg_insel(current_hop, current_hop);
+}
+
+static void emit_eoi(void)
+{
+       hop_add_eoi_insel(current_hop);
+}
+
+static const struct burm_emitter_data emitter_data =
+{
+    &emit_string,
+    &emit_reg,
+    &emit_value,
+    &emit_resultreg,
+    &emit_eoi
+};
+
+
+static void walk_instructions(struct ir* ir, int goal)
 {
     struct ir* children[10];
     int insn_no = burm_rule(ir->state_label, goal);
     const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
     const short* nts = burm_nts[insn_no];
+    struct hop* parent_hop = NULL;
     int i;
     
     ir->insn_no = insn_no;
     if (!insndata->is_fragment)
-        hop = ir->hop = new_hop(insn_no, ir);;
-
-    if (insndata->allocate)
     {
-        hop->resultvreg = new_vreg();
-        array_append(&hop->newvregs, hop->resultvreg);
-        array_append(&hop->outvregs, hop->resultvreg);
+        parent_hop = current_hop;
+        current_hop = ir->hop = new_hop(insn_no, ir);
     }
 
     burm_kids(ir, insn_no, children);
     for (i=0; nts[i]; i++)
-        walk_instructions(hop, children[i], nts[i]);
+        walk_instructions(children[i], nts[i]);
 
     ir->is_generated = true;
 
@@ -50,8 +92,12 @@ static void walk_instructions(struct hop* hop, struct ir* ir, int goal)
 
     if (!insndata->is_fragment)
     {
-        array_append(&current_bb->hops, hop);
-        hop_print('I', hop);
+        if (insndata->emitter)
+            insndata->emitter(ir, &emitter_data);
+
+        hop_print('I', current_hop);
+        array_append(&current_bb->hops, current_hop);
+        current_hop = parent_hop;
     }
 }
 
@@ -73,7 +119,7 @@ static void select_instructions(void)
                        burm_panic_cannot_match(ir);
 
         ir_print('I', ir);
-               walk_instructions(NULL, ir, 1);
+               walk_instructions(ir, 1);
        }
 }
 
index f0303a4..3348787 100644 (file)
@@ -21,6 +21,7 @@ DECLARATIONS
        aluparam  fragment;
        reg       allocates(GPR);
        tristate  allocates(CC);
+       bistate   allocates(CC);
 
 PATTERNS
 
@@ -105,6 +106,11 @@ PATTERNS
                emit "b $false"
                cost 8;
 
+       CJUMPEQ(value:bistate, PAIR(true:BLOCK4, false:BLOCK4))
+               emit "beq $true"
+               emit "b $false"
+               cost 8;
+
 
 /* Comparisons */
 
@@ -112,12 +118,21 @@ PATTERNS
                emit "cmp %left, %right"
                cost 4;
 
+       bistate = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4)
+               emit "cmp %left, %right"
+               cost 4;
+
        reg = tristate
                emit "mov %reg, #0"
                emit "movlt %reg, #-1"
                emit "movgt %reg, #1"
                cost 12;
 
+       reg = bistate
+               emit "moveq %reg, #1"
+               emit "movne %reg, #0"
+               cost 8;
+
 
 /* Conversions */
 
diff --git a/mach/proto/mcg/vreg.c b/mach/proto/mcg/vreg.c
deleted file mode 100644 (file)
index c841822..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "mcg.h"
-
-static int vreg_count = 0;
-
-struct vreg* new_vreg(void)
-{
-       struct vreg* vreg = calloc(1, sizeof *vreg);
-       vreg->id = vreg_count++;
-       return vreg;
-}
diff --git a/mach/proto/mcg/vreg.h b/mach/proto/mcg/vreg.h
deleted file mode 100644 (file)
index b764d38..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef VREG_H
-#define VREG_H
-
-struct vreg
-{
-       int id;
-};
-
-extern struct vreg* new_vreg(void);
-
-#endif
-
-