Instruction selection now happens on a shadow tree, rather than on the IR tree
authorDavid Given <dg@cowlark.com>
Mon, 3 Oct 2016 18:52:36 +0000 (20:52 +0200)
committerDavid Given <dg@cowlark.com>
Mon, 3 Oct 2016 18:52:36 +0000 (20:52 +0200)
itself. Currently it's semantically the same but the implementation is cleaner.

mach/proto/mcg/ir.h
mach/proto/mcg/mcgg_generated_header.h
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/pass_ssa.c
mach/proto/mcg/table
util/mcgg/ir.dat
util/mcgg/mcgg.h

index ce90fcb..52c5dc7 100644 (file)
@@ -20,9 +20,6 @@ struct ir
                ARRAYOF(struct ir) phivalue;
        } u;
 
-       void* state_label; /* used by the iburg instruction selector */
-       int insn_no;       /* the table rule number for this instruction */
-       int goal_no;       /* the semantic type of this instruction; not stmt */
        IMAPOF(struct hop) hops; /* only for root IRs; by goal */
 };
 
index eead127..f190a98 100644 (file)
@@ -4,22 +4,7 @@
 
 #define PANIC printf
 
-#define OP_LABEL(p) burm_calculate_label(p)
-#define LEFT_CHILD(p) ((p)->left)
-#define RIGHT_CHILD(p) ((p)->right)
-        
 #define burm_assert(b, s) assert(b)
 
-extern int burm_calculate_label(struct ir* ir);
-extern void burm_panic_cannot_match(struct ir* ir);
-
-static bool burm_predicate_int(struct ir* ir)
-{
-       return ir->goal_no == 3;
-}
-
-static bool burm_predicate_float(struct ir* ir)
-{
-       return ir->goal_no == 5;
-}
+extern void burm_panic_cannot_match(NODEPTR_TYPE node);
 
index a1f80a8..5c92aae 100644 (file)
@@ -6,28 +6,21 @@ static struct ir* current_ir;
 
 static const struct burm_emitter_data emitter_data;
 
-void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
+void burm_trace(struct burm_node* p, int ruleno, int cost, int bestcost) {
     const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
        //tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
        //      insndata->name, cost, bestcost);
 }
 
-void burm_panic_cannot_match(struct ir* ir)
+void burm_panic_cannot_match(struct burm_node* node)
 {
        fprintf(stderr, "could not find any patterns to match:\n");
-       ir_print(0, ir);
+       ir_print(0, node->ir);
        fprintf(stderr, "aborting!\n");
        exit(1);
 }
 
-int burm_calculate_label(struct ir* ir)
-{
-    if (ir->root != current_ir)
-               return ir_to_esn(IR_REG, ir->size);
-       return ir_to_esn(ir->opcode, ir->size);
-}
-
-static void emit_reg(struct ir* ir, int goal)
+static void emit_reg(struct burm_node* node, int goal)
 {
     struct hop* hop = imap_get(&current_ir->hops, goal);
 
@@ -39,17 +32,17 @@ static void emit_string(const char* data)
        hop_add_string_insel(current_hop, data);
 }
 
-static void emit_fragment(struct ir* ir, int goal)
+static void emit_fragment(struct burm_node* node, int goal)
 {
-    int insn_no = burm_rule(ir->state_label, goal);
+    int insn_no = burm_rule(node->state_label, goal);
     const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
     if (insndata->emitter)
-        insndata->emitter(ir, &emitter_data);
+        insndata->emitter(node, &emitter_data);
 }
 
-static void emit_value(struct ir* ir)
+static void emit_value(struct burm_node* node)
 {
-       hop_add_value_insel(current_hop, ir);
+       hop_add_value_insel(current_hop, node->ir);
 }
 
 static void emit_eoi(void)
@@ -57,15 +50,17 @@ static void emit_eoi(void)
        hop_add_eoi_insel(current_hop);
 }
 
-static void emit_constraint_equals(struct ir* ir, int goal)
+static void emit_constraint_equals(struct burm_node* node, int goal)
 {
+#if 0
     struct hop* hop;
     
     if (!goal)
-        goal = 2;
+        goal = ir->goal_no;
     hop = imap_get(&current_ir->hops, goal);
 
     current_hop->output = hop->output;
+#endif
 }
 
 static const struct burm_emitter_data emitter_data =
@@ -79,13 +74,14 @@ static const struct burm_emitter_data emitter_data =
 };
 
 
-static void walk_instructions(struct ir* ir, int goal)
+static void walk_instructions(struct burm_node* node, int goal)
 {
-    struct ir* children[10];
-    int insn_no = burm_rule(ir->state_label, goal);
+    struct burm_node* children[10];
+    int insn_no = burm_rule(node->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;
+    struct ir* ir = node->ir;
     int i;
     
     if (!insndata->is_fragment)
@@ -99,17 +95,13 @@ static void walk_instructions(struct ir* ir, int goal)
         }
     }
 
-    burm_kids(ir, insn_no, children);
+    burm_kids(node, insn_no, children);
     for (i=0; nts[i]; i++)
         walk_instructions(children[i], nts[i]);
 
-    ir->insn_no = insn_no;
-    if (goal != 1)
-        ir->goal_no = goal;
-
     tracef('I', "I: $%d goal %d selected %s %d: %s\n",
         ir->id,
-        ir->goal_no,
+        goal,
         insndata->is_fragment ? "fragment" : "instruction",
         insn_no,
         insndata->name);
@@ -119,7 +111,7 @@ static void walk_instructions(struct ir* ir, int goal)
         /* This may cause the vregs to be reassigned for this instruction (and
          * fragments contained within it). */
 
-        insndata->emitter(ir, &emitter_data);
+        insndata->emitter(node, &emitter_data);
 
         hop_print('I', current_hop);
         array_append(&ir->hops, current_hop);
@@ -127,6 +119,27 @@ static void walk_instructions(struct ir* ir, int goal)
     }
 }
 
+static struct burm_node* build_shadow_tree(struct ir* root, struct ir* ir)
+{
+    struct burm_node* node = calloc(1, sizeof(*node));
+    node->ir = ir;
+
+    if (ir->root == root)
+    {
+        node->label = ir_to_esn(ir->opcode, ir->size);
+
+        if (ir->left)
+            node->left = build_shadow_tree(root, ir->left);
+
+        if (ir->right)
+            node->right = build_shadow_tree(root, ir->right);
+    }
+    else
+        node->label = ir_to_esn(IR_REG, 0);
+
+    return node;
+}
+
 static void select_instructions(void)
 {
        int i;
@@ -135,16 +148,19 @@ static void select_instructions(void)
 
        for (i=0; i<current_bb->irs.count; i++)
        {
+        struct burm_node* shadow;
                int insnno;
+
                current_ir = current_bb->irs.item[i];
-               burm_label(current_ir);
+        shadow = build_shadow_tree(current_ir, current_ir);
+               burm_label(shadow);
 
-               insnno = burm_rule(current_ir->state_label, 1);
+               insnno = burm_rule(shadow->state_label, 1);
                if (!insnno)
-                       burm_panic_cannot_match(current_ir);
+                       burm_panic_cannot_match(shadow);
 
         ir_print('I', current_ir);
-               walk_instructions(current_ir, 1);
+               walk_instructions(shadow, 1);
        }
 }
 
index 87a0b97..265ade1 100644 (file)
@@ -174,6 +174,7 @@ static bool rewrite_loads_cb(struct ir* ir, void* user)
     if (is_local(ir))
     {
         ir->opcode = IR_NOP;
+        ir->size = 0;
         ir->left = definition;
         ir->right = NULL;
     }
@@ -214,6 +215,7 @@ static void recursively_rewrite_tree(struct basicblock* bb)
             if (ir->opcode == IR_STORE)
             {
                 ir->opcode = IR_NOP;
+                ir->size = 0;
                 ir->left = ir->right;
                 ir->right = NULL;
             }
index 0db5f6a..5f589d1 100644 (file)
@@ -67,12 +67,12 @@ PATTERNS
                emit "add sp, sp, %delta"
                cost 4;
 
-       reg = in:REG4
+       reg = in:REG
                with (reg == in)
                emit "reg %reg"
                cost 1;
 
-       reg = NOP4(in:reg)
+       reg = NOP(in:reg)
                with (reg == in)
                cost 1;
 
index baa4617..50c2e44 100644 (file)
@@ -5,14 +5,14 @@
 # Simple terminals
 S CONST # must be followed by float form
 S CONSTF
-S REG
-S NOP
+V REG
+V NOP
 S LABEL
 S BLOCK
 V PAIR
 S ANY
 S LOCAL
-S PHI
+V PHI
 
 # Magic stack operations
 S PUSH
index 1d80685..9180113 100644 (file)
                  (size-1)))
 
 #define STATE_TYPE void*
-typedef struct ir* NODEPTR_TYPE;
 
 #define STATE_LABEL(p) ((p)->state_label)
+#define OP_LABEL(p) ((p)->label)
+#define LEFT_CHILD(p) ((p)->left)
+#define RIGHT_CHILD(p) ((p)->right)
 
-extern void* burm_label(struct ir* ir);
+struct burm_node
+{
+    int label;
+    void* state_label;
+    struct burm_node* left;
+    struct burm_node* right;
+    struct ir* ir;
+};
+
+typedef struct burm_node* NODEPTR_TYPE;
+
+extern void* burm_label(NODEPTR_TYPE node);
 extern int burm_rule(void* state, int goalnt);
 extern const short *burm_nts[];
-extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]);
-extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost);
+extern NODEPTR_TYPE* burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
+extern void burm_trace(NODEPTR_TYPE p, int ruleno, int cost, int bestcost);
 
 struct burm_emitter_data
 {
     void (*emit_string)(const char* data);
-    void (*emit_fragment)(struct ir* ir, int goal);
-    void (*emit_reg)(struct ir* ir, int goal);
-    void (*emit_value)(struct ir* ir);
+    void (*emit_fragment)(NODEPTR_TYPE node, int goal);
+    void (*emit_reg)(NODEPTR_TYPE node, int goal);
+    void (*emit_value)(NODEPTR_TYPE node);
     void (*emit_eoi)(void);
-    void (*emit_constraint_equals)(struct ir* rightir, int rightgoal);
+    void (*emit_constraint_equals)(NODEPTR_TYPE node, int goal);
 };
 
-typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data);
+typedef void burm_emitter_t(NODEPTR_TYPE node, const struct burm_emitter_data* data);
 
 struct burm_instruction_data
 {