shithub: mc

Download patch

ref: cdda2a180d180c48e9ba197c4a0cecc7e075b782
parent: 14aeadb41737f1765b6f3489f3b8da330aeccf39
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Aug 21 23:37:33 EDT 2015

Do slightly better code gen.

    Remove some spurious spills.

--- a/6/ra.c
+++ b/6/ra.c
@@ -609,6 +609,8 @@
 
     ni = nodemoves(s, n, &il);
     for (i = 0; i < ni; i++) {
+        if (!bshas(s->mactiveset, il[i]->uid))
+            continue;
         for (j = 0; j < s->nmactive; j++) {
             if (il[i] == s->mactive[j]) {
                 ldel(&s->mactive, &s->nmactive, j);
@@ -1137,6 +1139,15 @@
     return useidx > 0 || defidx > 0;
 }
 
+static int nopmov(Insn *insn)
+{
+    if (insn->op != Imov && insn->op != Imovs)
+        return 0;
+    if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
+        return 0;
+    return insn->args[0]->reg.id == insn->args[1]->reg.id;
+}
+
 /*
  * Rewrite instructions using spilled registers, inserting
  * appropriate loads and stores into the BB
@@ -1155,6 +1166,8 @@
     if (!bb)
         return;
     for (j = 0; j < bb->ni; j++) {
+        if (nopmov(bb->il[j]))
+            continue;
         /* if there is a remapping, insert the loads and stores as needed */
         if (remap(s, bb->il[j], use, &nuse, def, &ndef)) {
             for (i = 0; i < nuse; i++) {
@@ -1208,6 +1221,34 @@
     htput(s->spillslots, itop(l->reg.id), itop(s->stksz->lit));
 }
 
+void replacealias(Isel *s, Asmbb *bb, Loc **map)
+{
+    size_t i, j;
+    Insn *insn;
+    Loc **alias;
+    Loc *l;
+
+    if (!map || !bb)
+        return;
+    alias = s->aliasmap;
+    s->aliasmap = alias;
+    for (i = 0; i < bb->ni; i++) {
+        insn = bb->il[i];
+        for (j = 0; j < insn->nargs; j++) {
+            l = insn->args[j];
+            if (l->type == Locreg) {
+                insn->args[j] = locmap[getalias(s, l->reg.id)];
+            } else if (l->type == Locmem || l->type == Locmeml) {
+                if (l->mem.base)
+                    l->mem.base = locmap[getalias(s, l->mem.base->reg.id)];
+                if (l->mem.idx)
+                    l->mem.idx = locmap[getalias(s, l->mem.idx->reg.id)];
+            }
+        }
+    }
+    s->aliasmap = alias;
+}
+
 /* 
  * Rewrites the function code so that it no longer contains
  * references to spilled registers. Every use of spilled regs
@@ -1220,7 +1261,7 @@
  *      insn %rZ,%rW
  *      mov %rW,234(%rsp)
  */
-static void rewrite(Isel *s)
+static void rewrite(Isel *s, Loc **aliasmap)
 {
     size_t i;
 
@@ -1231,6 +1272,8 @@
 
     /* rewrite instructions using them */
     for (i = 0; i < s->nbb; i++)
+        replacealias(s, s->bb[i], aliasmap);
+    for (i = 0; i < s->nbb; i++)
         rewritebb(s, s->bb[i]);
     htfree(s->spillslots);
     bsclear(s->spilled);
@@ -1276,6 +1319,7 @@
 {
     int spilled;
     size_t i;
+    Loc **aliasmap;
 
     /* Initialize the list of prepainted registers */
     s->prepainted = mkbs();
@@ -1289,6 +1333,7 @@
     for (i = 0; i < s->nsaved; i++)
         bsput(s->shouldspill, s->calleesave[i]->reg.id);
     do {
+        aliasmap = NULL;
         setup(s);
         liveness(s);
         build(s);
@@ -1302,12 +1347,15 @@
                 coalesce(s);
             else if (s->nwlfreeze)
                 freeze(s);
-            else if (s->nwlspill)
+            else if (s->nwlspill) {
+                if (!aliasmap)
+                    aliasmap = memdup(s->aliasmap, s->nreg * sizeof(Loc*));
                 selspill(s);
+            }
         } while (s->nwlsimp || s->nwlmove || s->nwlfreeze || s->nwlspill);
         spilled = paint(s);
         if (spilled)
-            rewrite(s);
+            rewrite(s, aliasmap);
     } while (spilled);
     delnops(s);
     bsfree(s->prepainted);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -524,6 +524,7 @@
 {
     Type *t;
 
+    t = NULL;
     if (!n->lit.type) {
         switch (n->lit.littype) {
             case Lchr:      t = mktype(n->loc, Tychar);                         break;