Add a fairly clunky pass which converts @copy pseudos into moves. Seems to
authorDavid Given <dg@cowlark.com>
Sun, 22 Jan 2017 22:31:22 +0000 (23:31 +0100)
committerDavid Given <dg@cowlark.com>
Sun, 22 Jan 2017 22:31:22 +0000 (23:31 +0100)
work, but needs more thought.

mach/proto/mcg/hop.c
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_copiestomoves.c [new file with mode: 0644]
mach/proto/mcg/procedure.c

index a6b57f9..67ebfa0 100644 (file)
@@ -55,9 +55,21 @@ static struct insel* new_insel(enum insel_type type)
 
 void hop_add_string_insel(struct hop* hop, const char* string)
 {
-    struct insel* insel = new_insel(INSEL_STRING);
-    insel->u.string = string;
-    array_append(&hop->insels, insel);
+    if ((hop->insels.count == 0) && (string[0] == '@'))
+    {
+        char* pseudo = strdup(string+1);
+        char* end = strchr(pseudo, ' ');
+        if (end)
+            *end = '\0';
+
+        hop->pseudo = pseudo;
+    }
+    else if (!hop->pseudo)
+    {
+        struct insel* insel = new_insel(INSEL_STRING);
+        insel->u.string = string;
+        array_append(&hop->insels, insel);
+    }
 }
 
 void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index)
@@ -326,21 +338,25 @@ char* hop_render(struct hop* hop)
         while (hashtable_next(hop->valueusage, &hit))
         {
             struct valueusage* usage = hit.value;
-            struct vreg* left = actual(usage->invreg);
-            struct vreg* right = actual(usage->outvreg);
-            if (left != right)
+            if (usage->input && usage->output)
             {
-                appendf(" ");
-                appendvreg(usage->invreg);
-                appendf("->");
-                appendvreg(usage->outvreg);
+                struct vreg* left = actual(usage->invreg);
+                struct vreg* right = actual(usage->outvreg);
+                if (left != right)
+                {
+                    appendf(" ");
+                    appendvreg(usage->invreg);
+                    appendf("->");
+                    appendvreg(usage->outvreg);
+                }
             }
         }
         appendf("\n");
+        return buffer;
     }
 
     if (hop->pseudo)
-        appendf("@");
+        appendf("@%s ", hop->pseudo);
 
        for (i=0; i<hop->insels.count; i++)
        {
index 692127e..c7a81f0 100644 (file)
@@ -109,6 +109,7 @@ extern void tb_regvar(struct procedure* proc, arith offset, int size, int type,
 
 extern void pass_assign_vregs(void);
 extern void pass_calculate_vreg_spillibility(void);
+extern void pass_convert_copies_to_moves(void);
 extern void pass_convert_inputs_to_phis(void);
 extern void pass_convert_locals_to_ssa(void);
 extern void pass_convert_nonlocal_phis(void);
diff --git a/mach/proto/mcg/pass_copiestomoves.c b/mach/proto/mcg/pass_copiestomoves.c
new file mode 100644 (file)
index 0000000..f13b42b
--- /dev/null
@@ -0,0 +1,46 @@
+#include "mcg.h"
+
+void pass_convert_copies_to_moves(void)
+{
+    int i, j;
+
+    for (i=0; i<cfg.preorder.count; i++)
+    {
+        struct basicblock* bb = cfg.preorder.item[i];
+        for (j=0; j<bb->hops.count; j++)
+        {
+            struct hop* hop = bb->hops.item[j];
+            if (hop->pseudo && (strcmp(hop->pseudo, "copy") == 0))
+            {
+                struct valueusage* usage;
+                struct hashtable_iterator hit = {};
+                struct vreg* invreg = NULL;
+                struct vreg* outvreg = NULL;
+                while (hashtable_next(hop->valueusage, &hit))
+                {
+                    usage = hit.value;
+                    if (usage->input)
+                    {
+                        assert(!invreg);
+                        invreg = usage->invreg;
+                    }
+                    if (usage->output)
+                    {
+                        assert(!outvreg);
+                        outvreg = usage->outvreg;
+                    }
+                }
+                assert(invreg && outvreg);
+
+                usage = hop_get_value_usage(hop, outvreg->value);
+                assert(!usage->invreg);
+                assert(!usage->input);
+                usage->input = true;
+                usage->invreg = invreg;
+                hop->is_move = true;
+            }
+        }
+    }
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
index 100bbb4..32bf393 100644 (file)
@@ -223,6 +223,7 @@ void procedure_compile(struct procedure* proc)
     print_hops('8');
     pass_assign_vregs();
     pass_calculate_vreg_spillibility();
+    pass_convert_copies_to_moves();
     print_hops('9');
     pass_register_allocator();
 #if 0