Calculate phi congruency groups; use them to solve the
authorDavid Given <dg@cowlark.com>
Sun, 9 Oct 2016 20:04:20 +0000 (22:04 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 9 Oct 2016 20:04:20 +0000 (22:04 +0200)
importing-hreg-from-the-future problem (probably poorly).

mach/proto/mcg/mcg.h
mach/proto/mcg/pass_phigroups.c [new file with mode: 0644]
mach/proto/mcg/pass_registerallocator.c
mach/proto/mcg/procedure.c
mach/proto/mcg/reg.h

index a90bbb5..db4d570 100644 (file)
@@ -104,6 +104,7 @@ extern void tb_regvar(struct procedure* proc, arith offset, int size, int type,
 extern void pass_convert_locals_to_ssa(struct procedure* proc);
 extern void pass_convert_stack_ops(struct procedure* proc);
 extern void pass_eliminate_trivial_blocks(struct procedure* proc);
+extern void pass_find_phi_congruence_groups(void);
 extern void pass_group_irs(struct procedure* proc);
 extern void pass_instruction_selector(void);
 extern void pass_live_vreg_analysis(void);
diff --git a/mach/proto/mcg/pass_phigroups.c b/mach/proto/mcg/pass_phigroups.c
new file mode 100644 (file)
index 0000000..c773aa5
--- /dev/null
@@ -0,0 +1,85 @@
+#include "mcg.h"
+
+static PMAPOF(struct vreg, struct vreg) phimap;
+
+static void make_phimap(void)
+{
+       int i, j;
+
+       phimap.count = 0;
+       for (i=0; i<cfg.preorder.count; i++)
+       {
+               struct basicblock* bb = cfg.preorder.item[i];
+               
+               for (j=0; j<bb->phis.count; j++)
+               {
+                       struct vreg* vreg = bb->phis.item[j].left;
+                       struct phi* phi = bb->phis.item[j].right;
+                       struct vreg* prevvreg = phi->ir->result;
+
+                       pmap_add(&phimap, vreg, prevvreg);
+               }
+       }
+}
+
+static void recursively_associate_group(struct phicongruence* c, struct vreg* vreg)
+{
+       int i;
+
+       vreg->congruence = c;
+       array_appendu(&c->vregs, vreg);
+    tracef('V', "V: %%%d is a member of congruence group %d\n",
+        vreg->id, c->id);
+
+    if (vreg->defined)
+    {
+        struct constraint* constraint = pmap_findleft(&vreg->defined->constraints, vreg);
+        if ((c->attrs == 0) || (constraint->attrs < c->attrs))
+            c->attrs = constraint->attrs;
+
+        array_appendu(&c->definitions, vreg->defined);
+    }
+
+       for (;;)
+       {
+               struct vreg* child = pmap_findleft(&phimap, vreg);
+        if (!child)
+            break;
+
+        pmap_remove(&phimap, vreg, child);
+        recursively_associate_group(c, child);
+    }
+               
+    for (;;)
+    {
+               struct vreg* child = pmap_findright(&phimap, vreg);
+               if (!child)
+            break;
+
+        pmap_remove(&phimap, child, vreg);
+        recursively_associate_group(c, child);
+       }
+}
+
+static void associate_groups(void)
+{
+    static int number = 0;
+
+       while (phimap.count > 0)
+       {
+               struct phicongruence* c = calloc(1, sizeof(*c));
+        c->id = number++;
+               recursively_associate_group(c, phimap.item[0].left);
+       }
+}
+
+void pass_find_phi_congruence_groups(void)
+{
+       make_phimap();
+       associate_groups();
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
+
+
index 0bacdd2..2e2ad07 100644 (file)
@@ -164,10 +164,9 @@ void pass_register_allocator(void)
         {
             struct vreg* vreg = bb->phis.item[j].left;
             struct phi* phi = bb->phis.item[j].right;
-            if (!pmap_findright(old, vreg) && (vreg->used.count > 0))
+            if (!pmap_findright(old, vreg))
             {
-                struct hop* used = vreg->used.item[0];
-                struct constraint* c = pmap_findleft(&used->constraints, vreg);
+                struct phicongruence* c = vreg->congruence;
                 struct hreg* hreg = allocate_hreg(old, vreg, c->attrs);
 
                 tracef('R', "R: import fallback hreg %s for phi input %%%d from %s\n",
index b2970b6..329c384 100644 (file)
@@ -168,6 +168,7 @@ void procedure_compile(struct procedure* proc)
 
     pass_instruction_selector();
     print_hops('7', proc);
+    pass_find_phi_congruence_groups();
     pass_live_vreg_analysis();
     print_hops('8', proc);
     pass_register_allocator();
index 743b9c3..fc72f2a 100644 (file)
@@ -3,6 +3,14 @@
 
 #define WITH_ATTR(a) (1<<(a))
 
+struct phicongruence
+{
+    int id;
+    ARRAYOF(struct vreg) vregs;
+    ARRAYOF(struct hop) definitions;
+    uint32_t attrs;
+};
+
 struct hreg
 {
        const char* name;
@@ -14,6 +22,7 @@ struct hreg
 struct vreg
 {
        int id;
+    struct phicongruence* congruence;
     struct hop* defined;
     ARRAYOF(struct hop) used;
 };