Fix a horrifying bug where bogus data was being recorded for output equality
authorDavid Given <dg@cowlark.com>
Sun, 5 Feb 2017 21:57:16 +0000 (22:57 +0100)
committerDavid Given <dg@cowlark.com>
Sun, 5 Feb 2017 21:57:16 +0000 (22:57 +0100)
constraints; actually apply output equality constraints; tentative fix for edge
cases where if input==output and the hop does no work a move was added to it
even if it already had an insel.

mach/proto/mcg/main.c
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/pass_registerallocator.c
mach/proto/mcg/procedure.c

index bc776b5..7baa12f 100644 (file)
@@ -119,7 +119,7 @@ int main(int argc, char* const argv[])
        if (!EM_open((char*) inputfilename))
                fatal("couldn't open input '%s': %s",
             inputfilename ? inputfilename : "<stdin>", EM_error);
-       
+
     if (outputfilename)
     {
         outputfile = fopen(outputfilename, "w");
index eac6ae9..9bb7758 100644 (file)
@@ -136,7 +136,7 @@ static void constrain_output_reg(uint32_t attr)
 static void constrain_output_reg_equal_to(int child)
 {
     struct value* value = find_value_of_child(child);
-    pmap_add(&current_hop->equals_constraint, &current_hop->value, value);
+    pmap_add(&current_hop->equals_constraint, &current_insn->value, value);
 }
 
 static const struct burm_emitter_data emitter_data =
@@ -228,7 +228,8 @@ static struct insn* walk_instructions(struct burm_node* node, int goal)
                 switch (node->label)
                 {
                     case ir_to_esn(IR_REG, 0):
-                        hop_add_move(current_hop, &node->ir->value, current_hop->value);
+                        if (current_hop->insels.count == 0)
+                            hop_add_move(current_hop, &node->ir->value, current_hop->value);
                         break;
 
                     case ir_to_esn(IR_NOP, 'I'):
index 9327dc2..6a3a7bf 100644 (file)
@@ -92,6 +92,18 @@ static void generate_graph(void)
                 if (hop->is_move && invreg1 && outvreg1)
                     graph_add_edge(&affinity, invreg1, outvreg1);
             }
+
+            /* Ensure that registers which are constrained to be in the same hreg for input
+             * and output are coalesced. */
+
+            for (k=0; k<hop->equals_constraint.count; k++)
+            {
+                struct value* left = hop->equals_constraint.item[k].left;
+                struct value* right = hop->equals_constraint.item[k].right;
+                struct vreg* leftvreg = actual(hop_find_output_vreg(hop, left));
+                struct vreg* rightvreg = actual(hop_find_input_vreg(hop, right));
+                coalesce(leftvreg, rightvreg);
+            }
         }
     }
 }
index b9bd485..004b606 100644 (file)
@@ -184,6 +184,7 @@ static void write_dominance_graph(const char* name)
 void procedure_compile(struct procedure* proc)
 {
     current_proc = proc;
+    tracef('P', "P: compiling %s\n", proc->name);
 
     pass_group_irs();
        print_blocks('a');