shithub: mc

Download patch

ref: ce58af0c3497db7f716dc1912009c8b9da55b0a5
parent: 0754332ab1945f9dda29185966d9fd5aad99a8f5
author: Ori Bernstein <[email protected]>
date: Wed Jun 13 22:11:22 EDT 2012

Fix build function.

    We should now try to build a correct interference graph, modulo
    actually building the graph.

--- a/8/asm.h
+++ b/8/asm.h
@@ -110,6 +110,12 @@
 
     /* increased when we spill */
     Loc *stksz;
+
+    /* register allocator state */
+    Insn ***moves;
+    size_t *nmoves;
+    Insn **wlmove;
+    size_t nwlmove;
 };
 
 /* entry points */
@@ -117,6 +123,9 @@
 void gen(Node *file, char *out);
 
 /* location generation */
+extern int maxregid;
+extern Loc **loctab; /* mapping from reg id => Loc * */
+
 Loc *loclbl(Node *lbl);
 Loc *locstrlbl(char *lbl);
 Loc *locreg(Mode m);
@@ -131,12 +140,12 @@
 void iprintf(FILE *fd, Insn *insn);
 
 /* register allocation */
+extern char *regnames[]; /* name table */
+extern Mode regmodes[];  /* mode table */
+
 void regalloc(Isel *s);
 size_t uses(Insn *i, long *uses);
 size_t defs(Insn *i, long *defs);
-extern char *regnames[];
-extern Mode regmodes[];
-extern Loc **loctab;
 
 
 /* useful functions */
--- a/8/insns.def
+++ b/8/insns.def
@@ -27,7 +27,7 @@
 Insn(Iadd,      "\tadd%t %r,%x\n",              Use(.l={1,2}),			Def(.l={2}))
 Insn(Isub,      "\tsub%t %r,%x\n",              Use(.l={1,2}),			Def(.l={2}))
 Insn(Imul,      "\tmul%t %r\n",              	Use(.l={1},.r={Reax}),		Def(.r={Reax,Redx}))
-Insn(Idiv,      "\tdiv%t %r\n",              	Use(.l={1},.r={Reax,Redx}),	Def(.l={Reax,Redx}))
+Insn(Idiv,      "\tdiv%t %r\n",              	Use(.l={1},.r={Reax,Redx}),	Def(.r={Reax,Redx}))
 Insn(Ineg,      "\tneg%t %r\n",              	Use(.l={1}),			Def(.l={1}))
 Insn(Iand,      "\tand%t %r,%x\n",              Use(.l={1,2}),			Def(.l={2}))
 Insn(Ior,       "\tor%t %r,%x\n",               Use(.l={1,2}),			Def(.l={2}))
--- a/8/ra.c
+++ b/8/ra.c
@@ -81,7 +81,7 @@
     int k;
 
     j = 0;
-    /* Add all the registers dsed and defined. Ddplicates
+    /* Add all the registers dsed and defined. Duplicates
      * in this list are fine, since they're being added to
      * a set anyways */
     for (i = 0; i < Maxarg; i++) {
@@ -162,6 +162,71 @@
     }
 }
 
+int ismove(Insn *i)
+{
+    return i->op == Imov;
+}
+
+void addedge(Isel *s, int u, int v)
+{
+}
+
+void build(Isel *s)
+{
+    /* uses/defs */
+    long u[2*Maxarg], d[2*Maxarg];
+    size_t nu, nd;
+    /* indexes */
+    size_t i, k;
+    ssize_t j;
+    /* liveness */
+    Bitset *live;
+    /* convenience vars */
+    Asmbb **bb;
+    size_t nbb;
+    Insn *insn;
+    uint l;
+
+    bb = s->bb;
+    nbb = s->nbb;
+    s->moves = zalloc(maxregid * sizeof(Loc **));
+    s->nmoves = zalloc(maxregid * sizeof(size_t));
+    for (i = 0; i < nbb; i++) {
+	live = bsdup(bb[i]->liveout);
+	for (j = bb[i]->ni - 1; j >= 0; j--) {
+	    insn = bb[i]->il[j];
+	    nu = uses(insn, u);
+	    nd = defs(insn, d);
+	    if (ismove(insn)) {
+		/* live \= uses(i) */
+		for (k = 0; k < nu; k++)
+		    bsdel(live, u[k]);
+
+		for (k = 0; k < nu; k++)
+		    lappend(&s->moves[u[k]], &s->nmoves[u[k]], insn);
+		for (k = 0; k < nd; k++)
+		    lappend(&s->moves[d[k]], &s->nmoves[d[k]], insn);
+		lappend(&s->wlmove, &s->nwlmove, insn);
+	    }
+	    for (k = 0; k < nd; k++)
+		bsput(live, d[k]);
+
+	    for (k = 0; k < nd; k++)
+		for (l = 0; bsiter(live, &l); l++)
+		    addedge(s, d[k], l);
+	}
+    }
+
+}
+
+void regalloc(Isel *s)
+{
+    liveness(s);
+    if (debug)
+	dumpasm(s->bb, s->nbb, stdout);
+    build(s);
+}
+
 void setprint(FILE *fd, Bitset *s)
 {
     char *sep;
@@ -230,9 +295,3 @@
     fprintf(fd, "ENDASM -------- \n");
 }
 
-void regalloc(Isel *s)
-{
-    liveness(s);
-    if (debug)
-	dumpasm(s->bb, s->nbb, stdout);
-}
--- a/8/regalloc.c
+++ b/8/regalloc.c
@@ -71,16 +71,17 @@
 }
 
 Loc **loctab = NULL;
+int maxregid = 0;
+
 Loc *locreg(Mode m)
 {
     Loc *l;
-    static long nextid = 0;
 
     l = zalloc(sizeof(Loc));
     l->type = Locreg;
     l->mode = m;
-    l->reg.id = nextid++;
-    loctab = xrealloc(loctab, nextid * sizeof(Loc*));
+    l->reg.id = maxregid++;
+    loctab = xrealloc(loctab, maxregid * sizeof(Loc*));
     loctab[l->reg.id] = l;
     return l;
 }
--- a/parse/bitset.c
+++ b/parse/bitset.c
@@ -67,6 +67,19 @@
     return n;
 }
 
+int bsiter(Bitset *bs, uint *elt)
+{
+    uint i;
+
+    for (i = *elt; i < bsmax(bs); i++) {
+	if (bshas(bs, i)) {
+	    *elt = i;
+	    return 1;
+	}
+    }
+    return 0;
+}
+
 /* Returns the largest value that the bitset can possibly
  * hold. It's conservative, but scanning the entire bitset
  * is a bit slow. This is mostly an aid to iterate over it. */
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -235,8 +235,9 @@
 int  bshas(Bitset *bs, uint elt);
 int  bseq(Bitset *a, Bitset *b);
 int  bsissubset(Bitset *set, Bitset *sub);
-size_t bscount(Bitset *bs);
+int  bsiter(Bitset *bs, uint *elt);
 size_t bsmax(Bitset *bs);
+size_t bscount(Bitset *bs);
 
 Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2));
 int htput(Htab *ht, void *k, void *v);