shithub: mc

Download patch

ref: 6a7f16a2b8e1be9639a79726d8195fc6cfae27f1
parent: c910735b4604acd14bffe223d8fc378b9d6f417b
author: Ori Bernstein <[email protected]>
date: Wed Jun 13 20:12:35 EDT 2012

Move towards generating flow graphs properly.

--- a/8/asm.h
+++ b/8/asm.h
@@ -89,6 +89,8 @@
     Insn **il;
     size_t ni;
 
+    Bitset *pred;
+    Bitset *succ;
     Bitset *use;
     Bitset *def;
     Bitset *livein;
--- a/8/insns.def
+++ b/8/insns.def
@@ -52,14 +52,14 @@
 Insn(Isetge,      "\tsetge %v\n",               Use(),	Def(.l={2}))
 
 /* branch instructions */
-Insn(Icall,     "\tcall %v\n",                  Use(.l={2}), Def())
-Insn(Ijmp,      "\tjmp %v\n",                   Use(.l={2}), Def())
-Insn(Ijz,       "\tjz %v\n",                    Use(.l={2}), Def())
-Insn(Ijnz,      "\tjnz %v\n",                   Use(.l={2}), Def())
-Insn(Ijl,       "\tjl %v\n",                    Use(.l={2}), Def())
-Insn(Ijle,      "\tjle %v\n",                   Use(.l={2}), Def())
-Insn(Ijg,       "\tjg %v\n",                    Use(.l={2}), Def())
-Insn(Ijge,      "\tjge %v\n",                   Use(.l={2}), Def())
+Insn(Icall,     "\tcall %v\n",                  Use(.l={1}), Def())
+Insn(Ijmp,      "\tjmp %v\n",                   Use(.l={1}), Def())
+Insn(Ijz,       "\tjz %v\n",                    Use(.l={1}), Def())
+Insn(Ijnz,      "\tjnz %v\n",                   Use(.l={1}), Def())
+Insn(Ijl,       "\tjl %v\n",                    Use(.l={1}), Def())
+Insn(Ijle,      "\tjle %v\n",                   Use(.l={1}), Def())
+Insn(Ijg,       "\tjg %v\n",                    Use(.l={1}), Def())
+Insn(Ijge,      "\tjge %v\n",                   Use(.l={1}), Def())
 Insn(Iret,      "\tret\n",                      Use(), Def())
 
 /* not really an insn... */
--- a/8/isel.c
+++ b/8/isel.c
@@ -616,7 +616,7 @@
                 modeidx = 0;
             default:
                 if (isdigit(*p))
-                    modeidx = strtol(p, &p, 10);
+                    modeidx = strtol(p, &p, 10) - 1;
 
                 if (*p == 't')
                     fputc(modenames[insn->args[modeidx]->mode], fd);
@@ -692,9 +692,17 @@
             iprintf(fd, s->bb[j]->il[i]);
 }
 
-static Asmbb *mkasmbb()
+static Asmbb *mkasmbb(Bb *bb)
 {
-    return zalloc(sizeof(Asmbb));
+    Asmbb *as;
+
+    as = zalloc(sizeof(Asmbb));
+    as->id = bb->id;
+    as->pred = bsdup(bb->pred);
+    as->succ = bsdup(bb->succ);
+    as->lbls = memdup(bb->lbls, bb->nlbls*sizeof(char*));
+    as->nlbls = bb->nlbls;
+    return as;
 }
 
 /* genasm requires all nodes in 'nl' to map cleanly to operations that are
@@ -710,23 +718,21 @@
     is.ret = fn->ret;
     is.cfg = fn->cfg;
 
-    is.bb = zalloc(fn->cfg->nbb * sizeof(Asmbb*));
+    for (i = 0; i < fn->cfg->nbb; i++)
+        lappend(&is.bb, &is.nbb, mkasmbb(fn->cfg->bb[i]));
 
-    lappend(&is.bb, &is.nbb, mkasmbb());
-    is.curbb = is.bb[is.nbb - 1];
+    is.curbb = is.bb[0];
     prologue(&is, fn->stksz);
-
     for (j = 0; j < fn->cfg->nbb; j++) {
-        lappend(&is.bb, &is.nbb, mkasmbb());
-        is.curbb = is.bb[is.nbb - 1];
+        is.curbb = is.bb[j + 1];
         for (i = 0; i < fn->cfg->bb[j]->nnl; i++) {
             isel(&is, fn->cfg->bb[j]->nl[i]);
         }
     }
-    lappend(&is.bb, &is.nbb, mkasmbb());
     is.curbb = is.bb[is.nbb - 1];
     epilogue(&is);
 
+    regalloc(&is);
     if (debug)
       writeasm(fn, &is, stdout);
 
--- a/8/ra.c
+++ b/8/ra.c
@@ -49,7 +49,8 @@
     for (i = 0; i < Maxarg; i++) {
 	if (!usetab[insn->op].l[i])
 	    break;
-	k = usetab[insn->op].l[i];
+	k = usetab[insn->op].l[i] - 1;
+	/* non-registers are handled later */
 	if (insn->args[k]->type == Locreg)
 	    u[j++] = insn->args[k]->reg.id;
     }
@@ -85,7 +86,7 @@
     for (i = 0; i < Maxarg; i++) {
 	if (!deftab[insn->op].l[i])
 	    break;
-	k = deftab[insn->op].l[i];
+	k = deftab[insn->op].l[i] - 1;
 	if (insn->args[k]->type == Locreg)
 	    d[j++] = insn->args[k]->reg.id;
     }
@@ -124,20 +125,39 @@
 
 void liveness(Isel *s)
 {
-    Cfg *cfg;
-    ssize_t i;
+    Bitset *old;
+    Asmbb **bb;
+    size_t nbb;
+    size_t i, j;
     int changed;
 
-    cfg = s->cfg;
-    cfg = cfg; /* shut up GCC for now */
-    for (i = s->nbb - 1; i >= 0; i--)
+    bb = s->bb;
+    nbb = s->nbb;
+    for (i = 0; i < nbb; i++) {
 	bbliveness(s->bb[i]);
+	bb[i]->livein = bsclear(bb[i]->livein);
+	bb[i]->liveout = bsclear(bb[i]->liveout);
+    }
 
     changed = 1;
     while (changed) {
-	for (i = s->nbb - 1; i >= 0; i--) {
-	}
 	changed = 0;
+	for (i = 0; i < nbb; i--) {
+	    old = bsdup(bb[i]->liveout);
+	    /* liveout[b] = U(s in succ) livein[s] */
+	    for (j = 0; j < bsmax(bb[i]->succ); j++) {
+		if (!bshas(bb[i]->succ, j))
+		    continue;
+		bsunion(bb[i]->liveout, bb[j]->livein);
+	    }
+	    /* livein[b] = use[b] U (out[b] \ def[b]) */
+	    bb[i]->livein = bsclear(bb[i]->livein);
+	    bsunion(bb[i]->livein, bb[i]->liveout);
+	    bsdiff(bb[i]->liveout, bb[i]->def);
+	    bsunion(bb[i]->liveout, bb[i]->use);
+	    if (!changed)
+		changed = !bseq(old, bb[i]->liveout);
+	}
     }
 }
 
--- a/opt/cfg.c
+++ b/opt/cfg.c
@@ -21,8 +21,8 @@
 
     bb = zalloc(sizeof(Bb));
     bb->id = nextbbid++;
-    bb->in = mkbs();
-    bb->out = mkbs();
+    bb->pred = mkbs();
+    bb->succ = mkbs();
     lappend(&cfg->bb, &cfg->nbb, bb);
     return bb;
 }
@@ -101,15 +101,15 @@
             targ = htget(cfg->lblmap, a->lbl.name);
             if (!targ)
                 die("No bb with label %s", a->lbl.name);
-            bsput(bb->out, targ->id);
-            bsput(targ->in, bb->id);
+            bsput(bb->succ, targ->id);
+            bsput(targ->pred, bb->id);
         }
         if (b) {
             targ = htget(cfg->lblmap, b->lbl.name);
             if (!targ)
                 die("No bb with label %s", b->lbl.name);
-            bsput(bb->out, targ->id);
-            bsput(targ->in, bb->id);
+            bsput(bb->succ, targ->id);
+            bsput(targ->pred, bb->id);
         }
     }
     return cfg;
@@ -134,8 +134,8 @@
         /* in edges */
         fprintf(fd, "In:  ");
         sep = "";
-        for (i = 0; i < bsmax(bb->in); i++) {
-            if (bshas(bb->in, i)) {
+        for (i = 0; i < bsmax(bb->pred); i++) {
+            if (bshas(bb->pred, i)) {
                 fprintf(fd, "%s%zd", sep, i);
                 sep = ",";
             }
@@ -145,8 +145,8 @@
         /* out edges */
         fprintf(fd, "Out: ");
         sep = "";
-        for (i = 0; i < bsmax(bb->out); i++) {
-             if (bshas(bb->out, i)) {
+        for (i = 0; i < bsmax(bb->succ); i++) {
+             if (bshas(bb->succ, i)) {
                 fprintf(fd, "%s%zd", sep, i);
                 sep = ",";
              }
--- a/opt/opt.h
+++ b/opt/opt.h
@@ -19,8 +19,8 @@
     size_t nlbls;
     Node **nl;
     size_t nnl;
-    Bitset *in;
-    Bitset *out;
+    Bitset *pred;
+    Bitset *succ;
 };
 
 /* Takes a reduced block, and returns a flow graph. */
--- a/parse/bitset.c
+++ b/parse/bitset.c
@@ -33,7 +33,7 @@
     return bs;
 }
 
-Bitset *dupbs(Bitset *a)
+Bitset *bsdup(Bitset *a)
 {
     Bitset *bs;
 
@@ -131,6 +131,17 @@
     eqsz(a, b);
     for (i = 0; i < a->nchunks; i++)
         a->chunks[i] &= ~b->chunks[i];
+}
+
+int bseq(Bitset *a, Bitset *b)
+{
+    size_t i;
+
+    eqsz(a, b);
+    for (i = 0; i < a->nchunks; i++)
+	if (a->chunks[i] != b->chunks[i])
+	    return 0;
+    return 1;
 }
 
 int bsissubset(Bitset *set, Bitset *sub)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -155,9 +155,9 @@
         if (a->cstrs && b->cstrs)
             bsunion(b->cstrs, a->cstrs);
         else if (a->cstrs)
-            b->cstrs = dupbs(a->cstrs);
+            b->cstrs = bsdup(a->cstrs);
         else if (b->cstrs)
-            a->cstrs = dupbs(b->cstrs);
+            a->cstrs = bsdup(b->cstrs);
     } else {
         if (!cstrcheck(a, b))
             fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -224,7 +224,7 @@
 
 /* data structures */
 Bitset *mkbs(void);
-Bitset *dupbs(Bitset *bs);
+Bitset *bsdup(Bitset *bs);
 Bitset *bsclear(Bitset *bs);
 void delbs(Bitset *bs);
 void bsput(Bitset *bs, uint elt);
@@ -233,6 +233,7 @@
 void bsintersect(Bitset *a, Bitset *b);
 void bsdiff(Bitset *a, Bitset *b);
 int  bshas(Bitset *bs, uint elt);
+int  bseq(Bitset *a, Bitset *b);
 int  bsissubset(Bitset *set, Bitset *sub);
 size_t bscount(Bitset *bs);
 size_t bsmax(Bitset *bs);