Tracing cleanup. Simplified the IR code. Some more opcodes.
authorDavid Given <dg@cowlark.com>
Wed, 21 Sep 2016 22:15:48 +0000 (00:15 +0200)
committerDavid Given <dg@cowlark.com>
Wed, 21 Sep 2016 22:15:48 +0000 (00:15 +0200)
mach/proto/mcg/basicblock.c
mach/proto/mcg/build.lua
mach/proto/mcg/compile.c [new file with mode: 0644]
mach/proto/mcg/ir.c
mach/proto/mcg/ir.dat
mach/proto/mcg/ir.h
mach/proto/mcg/ircodes.sh
mach/proto/mcg/main.c
mach/proto/mcg/mcg.h
mach/proto/mcg/parse_em.c
mach/proto/mcg/treebuilder.c

index 0ac2a55..e44f553 100644 (file)
@@ -39,4 +39,8 @@ void bb_alias(struct basicblock* block, const char* name)
        p->block = block;
 }
 
+void bb_print(char k, struct basicblock* block)
+{
+}
+
 /* vim: set sw=4 ts=4 expandtab : */
index 46394d5..d1b2a3f 100644 (file)
@@ -24,7 +24,8 @@ cprogram {
                "modules/src/em_code+lib_k",
                "modules/src/em_data+lib",
                "modules/src/idf+lib",
-               "modules/src/read_em+lib_kv",
+               "modules/src/read_em+lib_ev",
+               "modules/src/string+lib",
                "modules/src/system+lib",
                "./*.h",
                "util/mcgg+mcgg",
diff --git a/mach/proto/mcg/compile.c b/mach/proto/mcg/compile.c
new file mode 100644 (file)
index 0000000..d8ae7e3
--- /dev/null
@@ -0,0 +1,41 @@
+#include "mcg.h"
+
+static void print_blocks(char k, struct procedure* proc)
+{
+       int i;
+
+       tracef(k, "%c: procedure %s\n", k, proc->name);
+       for (int i=0; i<proc->blocks_count; i++)
+       {
+               struct basicblock* bb = proc->blocks[i];
+               int j;
+
+               tracef(k, "%c: block %s\n", k, bb->name);
+
+               for (int j=0; j<bb->inblocks_count; j++)
+               {
+                       struct basicblock* obb = bb->inblocks[j];
+                       tracef(k, "%c:   %s ->\n", k, obb->name);
+               }
+
+               for (int j=0; j<bb->irs_count; j++)
+                       ir_print(k, bb->irs[j]);
+
+               for (int j=0; j<bb->outblocks_count; j++)
+               {
+                       struct basicblock* obb = bb->outblocks[j];
+                       tracef(k, "%c:   -> %s\n", k, obb->name);
+               }
+
+       }
+}
+
+void compile(struct procedure* proc)
+{
+       int i;
+
+       print_blocks('1', proc);
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
index 8141715..34fed73 100644 (file)
@@ -35,18 +35,16 @@ struct ir* new_labelir(const char* label)
        return ir;
 }
 
-struct ir* new_wordir(arith value)
+struct ir* new_constir(int size, arith value)
 {
-       struct ir* ir = new_ir0(IR_ICONST, EM_wordsize);
+       struct ir* ir = new_ir0(IR_CONST, size);
        ir->u.ivalue = value;
        return ir;
 }
 
-struct ir* new_regir(int reg)
+struct ir* new_wordir(arith value)
 {
-       struct ir* ir = new_ir0(IR_REG, EM_pointersize);
-       ir->u.rvalue = reg;
-       return ir;
+    return new_constir(EM_wordsize, value);
 }
 
 struct ir* new_bbir(struct basicblock* bb)
@@ -61,51 +59,50 @@ struct ir* new_anyir(int size)
        return new_ir0(IR_ANY, size);
 }
 
-struct ir* new_phiir(int size)
+struct ir* new_localir(int offset)
 {
-       return new_ir0(IR_PHI, size);
+    struct ir* ir = new_ir0(IR_LOCAL, EM_pointersize);
+    ir->u.ivalue = offset;
+    return ir;
 }
 
-void ir_print(const struct ir* ir)
+void ir_print(char k, const struct ir* ir)
 {
-    if (ir->left)
-        ir_print(ir->left);
-    if (ir->right)
-        ir_print(ir->right);
-
-       printf("\t; %c ",
-               ir->is_sequence ? 'S' : ' ');
-       printf("$%d = ", ir->id);
-       printf("%s%d(",
-               ir_names[ir->opcode],
-               ir->size);
+    if (ir->left && !ir->left->is_sequence)
+        ir_print(k, ir->left);
+    if (ir->right && !ir->right->is_sequence)
+        ir_print(k, ir->right);
+
+       tracef(k, "%c: %c ", k, ir->is_sequence ? 'S' : ' ');
+       tracef(k, "$%d = ", ir->id);
+    tracef(k, "%s", ir_names[ir->opcode]);
+    if (ir->size)
+        tracef(k, "%d", ir->size);
+    tracef(k, "(");
 
        switch (ir->opcode)
        {
-               case IR_ICONST:
-                       printf("%d", ir->u.ivalue);
+               case IR_CONST:
+        case IR_LOCAL:
+                       tracef(k, "%d", ir->u.ivalue);
                        break;
 
                case IR_LABEL:
-                       printf("%s", ir->u.lvalue);
-                       break;
-
-               case IR_REG:
-                       printf("%d", ir->u.rvalue);
+                       tracef(k, "%s", ir->u.lvalue);
                        break;
 
                case IR_BLOCK:
-                       printf("%s", ir->u.bvalue->name);
+                       tracef(k, "%s", ir->u.bvalue->name);
                        break;
 
                default:
             if (ir->left)
-                printf("$%d", ir->left->id);
+                tracef(k, "$%d", ir->left->id);
             if (ir->right)
-                printf(", $%d", ir->right->id);
+                tracef(k, ", $%d", ir->right->id);
        }
 
-       printf(")\n");
+       tracef(k, ")\n");
 }
 
 /* vim: set sw=4 ts=4 expandtab : */
index 4de21c0..0338973 100644 (file)
@@ -1,11 +1,11 @@
 # Simple terminals
-ICONST
+CONST
 REG
 LABEL
 BLOCK
 PAIR
 ANY
-PHI
+LOCAL
 
 # Magic stack operations
 PUSH
@@ -22,11 +22,17 @@ MUL
 DIV
 MOD
 NEG
-NOT
+
+ADDF
+SUBF
+MULF
+DIVF
+NEGF
 
 AND
 OR
 EOR
+NOT
 
 # Conversions
 CII1
@@ -55,6 +61,7 @@ CJUMP
 RET
 
 # Special
-SETREG
-GETREG
+STACKADJUST
+GETRET
+SETRET
 
index 6574ecb..10e171b 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef IR_H
 #define IR_H
 
-#include "ircodes.h"
-
 enum
 {
        IRR_LB = -1,
@@ -11,6 +9,14 @@ enum
        IRR_RR = -4,
 };
 
+enum
+{
+       IRS_1,
+       IRS_2,
+       IRS_4,
+       IRS_8
+};
+
 struct ir
 {
        int id;
@@ -23,9 +29,6 @@ struct ir
                int rvalue;
                const char* lvalue;
                struct basicblock* bvalue;
-               struct {
-                       ARRAY(struct ir, srcs);
-               } phivalue;
        } u;
        bool is_sequence : 1;
 };
@@ -39,13 +42,15 @@ extern struct ir* new_ir2(int opcode, int size,
        struct ir* c1, struct ir* c2);
 
 extern struct ir* new_labelir(const char* label);
-extern struct ir* new_regir(int reg);
 extern struct ir* new_wordir(arith value);
+extern struct ir* new_constir(int size, arith value);
 extern struct ir* new_bbir(struct basicblock* bb);
 extern struct ir* new_anyir(int size);
-extern struct ir* new_phiir(int size);
+extern struct ir* new_localir(int offset);
 
-extern void ir_print(const struct ir* ir);
+extern void ir_print(char k, const struct ir* ir);
+
+#include "ircodes.h"
 
 #endif
 
index 8f88b8b..f1219c5 100755 (executable)
@@ -4,11 +4,33 @@ in=$1
 header=$2
 source=$3
 
-echo "enum {" > $header
-sed -n 's/^[A-Z].*$/IR_&,/p' < $in >> $header
-echo "};" >> $header
+awk -f - $in >$header << "EOF"
+       BEGIN {
+               print "enum {"
+       }
 
-echo "const char* ir_names[] = {" > $source
-sed -n 's/^[A-Z].*$/"&",/p' < $in >> $source
-echo "};" >> $source
+       /^[^#]+/ {
+               print "\tIR_" $1 ","
+       }
+
+       END {
+               print "};"
+       }
+EOF
+
+awk -f - $in >$source << "EOF"
+       BEGIN {
+               print "#include \"mcg.h\""
+               print "#include \"ir.h\""
+               print "const char* ir_names[] = {"
+       }
+
+       /^[^#]+/ {
+               printf("\t\"%s\",\n", $1)
+       }
+
+       END {
+               print "};"
+       }
+EOF
 
index a89b5a7..61f0bd5 100644 (file)
@@ -33,6 +33,30 @@ const char* aprintf(const char* fmt, ...)
     return p;
 }
 
+bool tracing(char k)
+{
+    switch (k)
+    {
+        case 'E': return true;
+        case '0': return true;
+        case '1': return true;
+        case '2': return true;
+        default:  return true;
+    }
+}
+
+void tracef(char k, const char* fmt, ...)
+{
+    va_list ap;
+
+    if (tracing(k))
+    {
+        va_start(ap, fmt);
+        vprintf(fmt, ap);
+        va_end(ap);
+    }
+}
+
 int main(int argc, char* argv[])
 {
     symbol_init();
index 997ae53..5de8be0 100644 (file)
@@ -77,17 +77,18 @@ struct basicblock
 {
     const char* name;
     ARRAY(struct insn, insns);
+    ARRAY(struct ir, allirs);
     ARRAY(struct ir, irs);
     ARRAY(struct basicblock, inblocks);
     ARRAY(struct basicblock, outblocks);
-    ARRAY(struct ir, outs);
-    ARRAY(struct ir, ins);
     bool is_root : 1;
     bool is_terminated : 1;
 };
 
 extern void fatal(const char* s, ...);
 extern const char* aprintf(const char* fmt, ...);
+extern void tracef(char k, const char* fmt, ...);
+extern bool tracing(char k);
 
 extern void parse_em(void);
 
@@ -105,12 +106,15 @@ extern void data_bss(arith size, int init);
 extern void bb_init(void);
 extern struct basicblock* bb_get(const char* name);
 extern void bb_alias(struct basicblock* block, const char* name);
+extern void bb_print(char k, struct basicblock* block);
 
 extern void tb_filestart(void);
 extern void tb_fileend(void);
 extern void tb_procedure(struct procedure* proc);
 extern void tb_regvar(arith offset, int size, int type, int priority);
 
+extern void compile(struct procedure* proc);
+
 #endif
 
 /* vim: set sw=4 ts=4 expandtab : */
index a1c9889..e6d39f9 100644 (file)
@@ -289,6 +289,7 @@ static void parse_pseu(void)
 
                case ps_end: /* procedure end */
             tb_procedure(current_proc);
+            compile(current_proc);
 
             current_proc = NULL;
             code_bb = NULL;
index 5b014ec..82d7b14 100644 (file)
@@ -6,7 +6,7 @@ static struct basicblock* current_bb;
 static int stackptr;
 static struct ir* stack[64];
 
-static struct ir* convert(struct ir* src, int destsize, int opcode);
+static struct ir* convert(struct ir* src, int destsize, int opcodebase);
 static struct ir* appendir(struct ir* ir);
 
 static void reset_stack(void)
@@ -37,8 +37,10 @@ static struct ir* pop(int size)
         if (size < EM_wordsize)
             size = EM_wordsize;
         return
-            new_ir0(
-                IR_POP, size
+            appendir(
+                new_ir0(
+                    IR_POP, size
+                )
             );
     }
     else
@@ -60,13 +62,25 @@ static void print_stack(void)
 {
     int i;
 
-    printf("\t; stack:");
+    tracef('E', "E: stack:");
     for (i=0; i<stackptr; i++)
     {
         struct ir* ir = stack[i];
-        printf(" $%d.%d", ir->id, ir->size);
+        tracef('E', " $%d.%d", ir->id, ir->size);
     }
-    printf("  (top)\n");
+    tracef('E', "  (top)\n");
+}
+
+static void appendallirs(struct ir* ir)
+{
+    if (CONTAINS(current_bb->allirs, ir))
+        fatal("ir reachable from more than one place");
+
+    APPEND(current_bb->allirs, ir);
+    if (ir->left && !ir->left->is_sequence)
+        appendallirs(ir->left);
+    if (ir->right && !ir->right->is_sequence)
+        appendallirs(ir->right);
 }
 
 static struct ir* appendir(struct ir* ir)
@@ -76,8 +90,9 @@ static struct ir* appendir(struct ir* ir)
     assert(current_bb != NULL);
     ir->is_sequence = true;
     APPEND(current_bb->irs, ir);
+    appendallirs(ir);
 
-    ir_print(ir);
+    ir_print('0', ir);
     return ir;
 }
 
@@ -112,16 +127,6 @@ void tb_regvar(arith offset, int size, int type, int priority)
     /* ignored */
 }
 
-static struct ir* address_of_local(int index)
-{
-    return
-        new_ir2(
-            IR_ADD, EM_pointersize,
-            new_regir((index < 0) ? IRR_LB : IRR_AB),
-            new_wordir(index)
-        );
-}
-
 static struct ir* address_of_external(const char* label, arith offset)
 {
     if (offset != 0)
@@ -162,7 +167,7 @@ static struct ir* tristate_compare(int size, int opcode)
 
     return
         new_ir2(
-            opcode, size,
+            opcode, EM_wordsize,
             left, right
         );
 }
@@ -173,8 +178,8 @@ static void simple_convert(int opcode)
     struct ir* srcsize = pop(EM_wordsize);
     struct ir* value;
 
-    assert(srcsize->opcode == IR_ICONST);
-    assert(destsize->opcode == IR_ICONST);
+    assert(srcsize->opcode == IR_CONST);
+    assert(destsize->opcode == IR_CONST);
 
     value = pop(srcsize->u.ivalue);
     push(
@@ -241,7 +246,7 @@ static void simple_branch2(int opcode, int size,
         new_ir2(
             IR_CJUMP, 0,
             new_ir2(
-                irop, size,
+                irop,  size,
                 left, right
             ),
             new_ir2(
@@ -336,11 +341,17 @@ static void insn_ivalue(int opcode, arith value)
         case op_xor: simple_alu2(opcode, value, IR_EOR); break;
         case op_com: simple_alu1(opcode, value, IR_NOT); break;
 
+        case op_adf: simple_alu2(opcode, value, IR_ADDF); break;
+        case op_sbf: simple_alu2(opcode, value, IR_SUBF); break;
+        case op_mlf: simple_alu2(opcode, value, IR_MULF); break;
+        case op_dvf: simple_alu2(opcode, value, IR_DIVF); break;
+        case op_ngf: simple_alu1(opcode, value, IR_NEGF); break;
+
         case op_lol:
             push(
                 new_ir1(
                     IR_LOAD, EM_wordsize,
-                    address_of_local(value)
+                    new_localir(value)
                 )
             );
             break;
@@ -349,7 +360,7 @@ static void insn_ivalue(int opcode, arith value)
             appendir(
                 new_ir2(
                     IR_STORE, EM_wordsize,
-                    address_of_local(value),
+                    new_localir(value),
                     pop(EM_wordsize)
                 )
             );
@@ -357,7 +368,7 @@ static void insn_ivalue(int opcode, arith value)
 
         case op_lal:
             push(
-                address_of_local(value)
+                new_localir(value)
             );
             break;
 
@@ -476,17 +487,21 @@ static void insn_ivalue(int opcode, arith value)
                     break;
 
                 default:
-                    appendir(
-                        new_ir2(
-                            IR_SETREG, EM_pointersize,
-                            new_regir(IRR_SP),
-                            new_ir2(
-                                IR_ADD, EM_pointersize,
-                                new_regir(IRR_SP),
+                    while ((value > 0) && (stackptr > 0))
+                    {
+                        struct ir* ir = pop(stack[stackptr-1]->size);
+                        value -= ir->size;
+                    }
+
+                    if (value != 0)
+                    {
+                        appendir(
+                            new_ir1(
+                                IR_STACKADJUST, EM_pointersize,
                                 new_wordir(value)
                             )
-                        )
-                    );
+                        );
+                    }
                     break;
             }
             break;
@@ -497,10 +512,10 @@ static void insn_ivalue(int opcode, arith value)
             if (value > 0)
             {
                 struct ir* retval = pop(value);
+                materialise_stack();
                 appendir(
-                    new_ir2(
-                        IR_SETREG, value,
-                        new_regir(IRR_RR),
+                    new_ir1(
+                        IR_SETRET, value,
                         retval
                     )
                 );
@@ -518,9 +533,8 @@ static void insn_ivalue(int opcode, arith value)
         {
             push(
                 appendir(
-                    new_ir1(
-                        IR_GETREG, value,
-                        new_regir(IRR_RR)
+                    new_ir0(
+                        IR_GETRET, value
                     )
                 )
             );
@@ -630,13 +644,7 @@ static void generate_tree(struct basicblock* bb)
 {
     int i;
 
-    printf("; BLOCK %s\n", bb->name);
-    if (bb->inblocks_count > 0)
-    {
-        printf("; Entered from:\n");
-        for (i=0; i<bb->inblocks_count; i++)
-            printf(";    %s\n", bb->inblocks[i]->name);
-    }
+    tracef('0', "0: block %s\n", bb->name);
 
     current_bb = bb;
     reset_stack();
@@ -644,30 +652,30 @@ static void generate_tree(struct basicblock* bb)
     for (i=0; i<bb->insns_count; i++)
     {
         struct insn* insn = bb->insns[i];
-        printf("\t; EM: %s ", em_mnem[insn->opcode - sp_fmnem]);
+        tracef('E', "E: read %s ", em_mnem[insn->opcode - sp_fmnem]);
         switch (insn->paramtype)
         {
             case PARAM_NONE:
-                printf("\n");
+                tracef('E', "\n");
                 insn_simple(insn->opcode);
                 break;
 
             case PARAM_IVALUE:
-                printf("value=%d\n", insn->u.ivalue);
+                tracef('E', "value=%d\n", insn->u.ivalue);
                 insn_ivalue(insn->opcode, insn->u.ivalue);
                 break;
 
             case PARAM_LVALUE:
-                printf("label=%s offset=%d\n", 
+                tracef('E', "label=%s offset=%d\n", 
                     insn->u.lvalue.label, insn->u.lvalue.offset);
                 insn_lvalue(insn->opcode, insn->u.lvalue.label, insn->u.lvalue.offset);
                 break;
 
             case PARAM_BVALUE:
-                printf("true=%s", insn->u.bvalue.left->name);
+                tracef('E', "true=%s", insn->u.bvalue.left->name);
                 if (insn->u.bvalue.right)
-                    printf(" false=%s", insn->u.bvalue.right->name);
-                printf("\n");
+                    tracef('E', " false=%s", insn->u.bvalue.right->name);
+                tracef('E', "\n");
                 insn_bvalue(insn->opcode, insn->u.bvalue.left, insn->u.bvalue.right);
                 break;
 
@@ -675,18 +683,11 @@ static void generate_tree(struct basicblock* bb)
                 assert(0);
         }
 
-        print_stack();
+        if (tracing('E'))
+            print_stack();
     }
 
     assert(stackptr == 0);
-
-    if (bb->outblocks_count > 0)
-    {
-        printf("; Exiting to:\n");
-        for (i=0; i<bb->outblocks_count; i++)
-            printf(";    %s\n", bb->outblocks[i]->name);
-    }
-    printf("\n");
 }
 
 void tb_procedure(struct procedure* current_proc)