shithub: mc

Download patch

ref: ae076c5f98e0dda484f92ac400b5657f5924efb5
parent: 7f27f8b727a213779d07a68a5ca4e0bc8893d761
author: Ori Bernstein <[email protected]>
date: Sun Feb 3 08:18:32 EST 2013

Hack to remove aliasing registers from mov targets

    We were effectively excluding registers that we shouldn't
    have been. Oops.

--- a/6/ra.c
+++ b/6/ra.c
@@ -303,6 +303,35 @@
     return 0;
 }
 
+/*
+ * If we have an edge between two aliasing registers,
+ * we should not increment the degree, since that would
+ * be double counting.
+ */
+static int degreechange(Isel *s, regid u, regid v)
+{
+    regid phys, virt, r;
+    size_t i;
+
+    if (bshas(s->prepainted, u)) {
+        phys = u;
+        virt = v;
+    } else if (bshas(s->prepainted, v)) {
+        phys = v;
+        virt = u;
+    } else {
+        return 1;
+    }
+
+    for (i = 0; i < Nmode; i++) {
+        r = regmap[colourmap[phys]][i];
+        if (r != phys && gbhasedge(s, virt, regmap[colourmap[phys]][i])) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static void addedge(Isel *s, regid u, regid v)
 {
     if (u == v || gbhasedge(s, u, v))
@@ -311,15 +340,16 @@
         return;
     if (v == Rrbp || v == Rrsp || v == Rrip)
         return;
+
     gbputedge(s, u, v);
     gbputedge(s, v, u);
     if (!bshas(s->prepainted, u)) {
         bsput(s->gadj[u], v);
-        s->degree[u]++;
+        s->degree[u] += degreechange(s, v, u);
     }
     if (!bshas(s->prepainted, v)) {
         bsput(s->gadj[v], u);
-        s->degree[v]++;
+        s->degree[v] += degreechange(s, u, v);
     }
 }
 
@@ -361,7 +391,7 @@
 {
     regid u[Maxuse], d[Maxdef];
     size_t nu, nd;
-    size_t i, k;
+    size_t i, k, a;
     ssize_t j;
     Bitset *live;
     Asmbb **bb;
@@ -391,8 +421,15 @@
             //iprintf(stdout, insn);
             if (ismove(insn)) {
                 /* live \= uses(i) */
-                for (k = 0; k < nu; k++)
-                    bsdel(live, u[k]);
+                for (k = 0; k < nu; k++) {
+                    /* remove all physical register aliases */
+                    if (bshas(s->prepainted, u[k])) {
+                        for (a = 0; a < Nmode; a++)
+                            bsdel(live, regmap[colourmap[u[k]]][a]);
+                    } else {
+                        bsdel(live, u[k]);
+                    }
+                }
 
                 for (k = 0; k < nu; k++)
                     lappend(&s->rmoves[u[k]], &s->nrmoves[u[k]], insn);
@@ -612,6 +649,8 @@
 {
     regid t;
 
+    if (debugopt['r'])
+        printf("check combinable %zd <=> %zd\n", u, v);
     /* Regs of different modes can't be combined as things stand.
      * In principle they should be combinable, but it confused the
      * whole mode dance. */
@@ -635,7 +674,7 @@
     size_t i, j;
     int has;
 
-    if (debugopt['r'])
+    if (debugopt['r'] || 1)
         printedge(stdout, "combining:", u, v);
     if (wlhas(s->wlfreeze, s->nwlfreeze, v, &idx))
         ldel(&s->wlfreeze, &s->nwlfreeze, idx);
@@ -659,7 +698,7 @@
     }
 
     for (t = 0; adjiter(s, v, &t); t++) {
-        if (debugopt['r'])
+        if (debugopt['r'] || 1)
             printedge(stdout, "combine-putedge:", v, t);
         addedge(s, t, u);
         decdegree(s, t);
@@ -1065,11 +1104,6 @@
         liveness(s);
         build(s);
         mkworklist(s);
-        if (spilled) {
-            wlprint(stdout, "spill", s->wlspill, s->nwlspill);
-            wlprint(stdout, "simp", s->wlsimp, s->nwlsimp);
-            wlprint(stdout, "freeze", s->wlfreeze, s->nwlfreeze);
-        }
         if (debugopt['r'])
             dumpasm(s, stdout);
         do {
--- a/6/regs.def
+++ b/6/regs.def
@@ -67,8 +67,6 @@
 Reg(Rrbx, "%rbx", ModeQ)
 Reg(Rrsi, "%rsi", ModeQ)
 Reg(Rrdi, "%rdi", ModeQ)
-Reg(Rrsp, "%rsp", ModeQ)
-Reg(Rrbp, "%rbp", ModeQ)
 Reg(Rr8, "%r8", ModeQ)
 Reg(Rr9, "%r9", ModeQ)
 Reg(Rr10, "%r10", ModeQ)
@@ -79,3 +77,5 @@
 Reg(Rr15, "%r15", ModeQ)
 
 Reg(Rrip, "%rip", ModeQ)
+Reg(Rrsp, "%rsp", ModeQ)
+Reg(Rrbp, "%rbp", ModeQ)