Fleshed out hops and vregs. The result is almost looking like code now ---
authorDavid Given <dg@cowlark.com>
Mon, 26 Sep 2016 22:19:45 +0000 (00:19 +0200)
committerDavid Given <dg@cowlark.com>
Mon, 26 Sep 2016 22:19:45 +0000 (00:19 +0200)
uncanny.

mach/proto/mcg/hop.c
mach/proto/mcg/hop.h
mach/proto/mcg/ir.h
mach/proto/mcg/main.c
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/table
mach/proto/mcg/vreg.c [new file with mode: 0644]
mach/proto/mcg/vreg.h [new file with mode: 0644]

index ccc1805..9a87a34 100644 (file)
@@ -1,39 +1,92 @@
 #include "mcg.h"
 
+static char outbuf[256];
+static struct hop* current_hop;
+
+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->insn_no = insn_no;
        hop->ir = ir;
+       return hop;
 }
 
-static void add_reg(struct vreg* vregs[], struct vreg* vreg)
+static void append(const char* fmt, ...)
 {
-       int i;
+       va_list ap;
+       
+       va_start(ap, fmt);
+       vsprintf(outbuf + strlen(outbuf), fmt, ap);
+       va_end(ap);
+}
 
-       for (i=0; i<HOP_INOUT_REGS; i++)
-               if (!vregs[i])
-               {
-                       vregs[i] = vreg;
-                       return;
-               }
+static void emit_reg(struct ir* ir)
+{
+       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);
+       }
+}
 
-       fatal("too many input registers for instruction");
+static void emit_string(const char* data)
+{
+       append("%s", data);
 }
 
-void hop_add_in_reg(struct hop* hop, struct vreg* vreg)
+static void emit_value(struct ir* ir)
 {
-       add_reg(hop->invregs, vreg);
+       append("(val)");
 }
 
-void hop_add_out_reg(struct hop* hop, struct vreg* vreg)
+static void emit_resultreg(void)
 {
-       add_reg(hop->outvregs, vreg);
+       append("%%%d", current_hop->resultvreg->id);
 }
 
-void hop_emit(struct hop* hop, const struct burm_emitter_data* ed)
+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];
-       insndata->emitter(hop->ir, ed);
+
+       current_hop = hop;
+       outbuf[0] = 0;
+       if (insndata->emitter)
+       {
+               insndata->emitter(hop->ir, &emitter_data);
+
+               s = strtok(outbuf, "\n");
+               do
+               {
+                       tracef(k, "%c: %p: %s\n", k, hop, s);
+                       s = strtok(NULL, "\n");
+               }
+               while (s);
+       }
+       else
+               tracef(k, "%c: %p: (empty)\n", k, hop);
 }
 
index d6cc6e7..2cb0c9f 100644 (file)
@@ -1,26 +1,20 @@
 #ifndef HOP_H
 #define HOP_H
 
-struct vreg
-{
-       int id;
-       int regclass;
-};
-
-#define HOP_INOUT_REGS 4
-
 struct hop
 {
        int insn_no;
        struct ir* ir;
-       struct vreg* invregs[HOP_INOUT_REGS];
-       struct vreg* outvregs[HOP_INOUT_REGS];
+       struct vreg* resultvreg;
+       ARRAYOF(struct vreg) invregs;
+       ARRAYOF(struct vreg) outvregs;
+       ARRAYOF(struct vreg) newvregs;
+       ARRAYOF(struct vreg) deadvregs;
 };
 
 extern struct hop* new_hop(int insn_no, struct ir* ir);
 
-extern void hop_add_in_reg(struct hop* hop, struct vreg* reg);
-extern void hop_add_out_reg(struct hop* hop, struct vreg* reg);
+extern void hop_print(char k, struct hop* hop);
 
 #endif
 
index 79dbfdb..f63272a 100644 (file)
@@ -20,8 +20,8 @@ struct ir
        } u;
 
        void* state_label; /* used by the iburg instruction selector */
-       int insn_no;
-       int vreg;
+       int insn_no;       /* the table rule number for this instruction */
+       struct hop* hop;   /* only for IRs that root a hardware op */
 
        bool is_sequence : 1;
        bool is_generated : 1;
index 83d5101..c17b60b 100644 (file)
@@ -41,7 +41,8 @@ bool tracing(char k)
         case 'E': return false;
         case '0': return false;
         case '1': return false;
-        case '2': return true;
+        case '2': return false;
+        case 'I': return true;
         default:  return true;
     }
 }
index 8cf16f9..746f392 100644 (file)
@@ -20,6 +20,7 @@
 #include "map.h"
 #include "ir.h"
 #include "mcgg.h"
+#include "vreg.h"
 #include "hop.h"
 
 extern char em_pseu[][4];
index 9d17c06..a2a993c 100644 (file)
@@ -1,29 +1,6 @@
 #include "mcg.h"
 
-static int vregcount;
-
-#if 0
-static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
-#ifdef TRACE
-       int eruleno = burm_rule(STATE_LABEL(p), goalnt);
-       const short *nts = burm_nts[eruleno];
-       NODEPTR_TYPE kids[10];
-       int i;
-
-       for (i = 0; i < indent; i++)
-               fprintf(stderr, " ");
-       fprintf(stderr, "%s\n", burm_string[eruleno]);
-       burm_kids(p, eruleno, kids);
-       for (i = 0; nts[i]; i++)
-       {
-               if (kids[i])
-                       dumpCover(kids[i], nts[i], indent + 1);
-               else
-                       fprintf(stderr, "failed!\n");
-       }
-#endif
-}
-#endif
+static struct basicblock* current_bb;
 
 void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
     const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
@@ -39,72 +16,30 @@ void burm_panic_cannot_match(struct ir* ir)
        exit(1);
 }
 
-static const struct burm_emitter_data emitter_data;
-
-static void emit_string(const char* data)
-{
-    tracef('I', "I: emit: %s\n", data);
-}
-
-static void emit_reg(struct ir* ir)
-{
-    const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
-    if (insndata->is_fragment)
-        insndata->emitter(ir, &emitter_data);
-    else
-        tracef('I', "I: emit reg %d\n", ir->vreg);
-}
-
-static void emit_value(struct ir* ir)
-{
-    tracef('I', "I: emit value\n");
-}
-
-static void emit_resultreg(void)
-{
-    tracef('I', "I: emit resultreg\n");
-}
-
-static void emit_eoi(void)
-{
-    tracef('I', "I: emit eoi\n");
-}
-
-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)
+static void walk_instructions(struct hop* hop, 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];
     int i;
-    int resultreg = 0;
-
+    
     ir->insn_no = insn_no;
+    if (!insndata->is_fragment)
+        hop = ir->hop = new_hop(insn_no, ir);;
 
     if (insndata->allocate)
     {
-        resultreg = vregcount++;
-        tracef('I', "I: new %s %d\n",
-            burm_register_class_names[insndata->allocate], resultreg);
+        hop->resultvreg = new_vreg();
+        array_append(&hop->newvregs, hop->resultvreg);
+        array_append(&hop->outvregs, hop->resultvreg);
     }
 
     burm_kids(ir, insn_no, children);
     for (i=0; nts[i]; i++)
-        walk_instructions(children[i], nts[i]);
+        walk_instructions(hop, children[i], nts[i]);
 
-    if (ir->vreg)
-        tracef('I', "I: use %d\n", ir->vreg);
-    if (resultreg)
-        ir->vreg = resultreg;
+    ir->is_generated = true;
 
     tracef('I', "I: $%d %s selected %s %d: %s\n",
         ir->id,
@@ -112,30 +47,33 @@ static void walk_instructions(struct ir* ir, int goal)
         insndata->is_fragment ? "fragment" : "instruction",
         insn_no,
         insndata->name);
-    ir->is_generated = true;
 
-    if (!insndata->is_fragment && insndata->emitter)
-        insndata->emitter(ir, &emitter_data);
+    if (!insndata->is_fragment)
+    {
+        array_append(&current_bb->hops, hop);
+        hop_print('I', hop);
+    }
 }
 
 
-static void select_instructions(struct basicblock* bb)
+static void select_instructions(void)
 {
        int i;
 
-       tracef('I', "I: BLOCK: %s\n", bb->name);
+       tracef('I', "I: BLOCK: %s\n", current_bb->name);
 
-       for (i=0; i<bb->irs.count; i++)
+       for (i=0; i<current_bb->irs.count; i++)
        {
                int insnno;
-               struct ir* ir = bb->irs.item[i];
+               struct ir* ir = current_bb->irs.item[i];
                burm_label(ir);
 
                insnno = burm_rule(ir->state_label, 1);
                if (!insnno)
                        burm_panic_cannot_match(ir);
 
-               walk_instructions(ir, 1);
+        ir_print('I', ir);
+               walk_instructions(NULL, ir, 1);
        }
 }
 
@@ -143,12 +81,10 @@ void pass_instruction_selector(struct procedure* proc)
 {
     int i;
 
-    vregcount = 1;
-
     for (i=0; i<proc->blocks.count; i++)
     {
-        struct basicblock* bb = proc->blocks.item[i];
-        select_instructions(bb);
+        current_bb = proc->blocks.item[i];
+        select_instructions();
     }
 }
 
index d450842..f0303a4 100644 (file)
@@ -102,7 +102,7 @@ PATTERNS
 
        CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
                emit "beq $true"
-               emit "bne $false"
+               emit "b $false"
                cost 8;
 
 
diff --git a/mach/proto/mcg/vreg.c b/mach/proto/mcg/vreg.c
new file mode 100644 (file)
index 0000000..c841822
--- /dev/null
@@ -0,0 +1,10 @@
+#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
new file mode 100644 (file)
index 0000000..b764d38
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef VREG_H
+#define VREG_H
+
+struct vreg
+{
+       int id;
+};
+
+extern struct vreg* new_vreg(void);
+
+#endif
+
+