summary refs log tree commit diff
path: root/lisc/rega.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-25 16:19:03 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-25 16:19:03 -0400
commite80b84ebdb6c0623442a26ac10fc763cc6d9e6e9 (patch)
tree6c6e0417537bfe7dd2a1ba1bb509c89691c551af /lisc/rega.c
parent03d5ec674a4c8576bf3b508c6573431729a63222 (diff)
downloadroux-e80b84ebdb6c0623442a26ac10fc763cc6d9e6e9.tar.gz
fresh new trace based allocator (needs tuning)
Diffstat (limited to 'lisc/rega.c')
-rw-r--r--lisc/rega.c132
1 files changed, 97 insertions, 35 deletions
diff --git a/lisc/rega.c b/lisc/rega.c
index 7dcb929..1199409 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -5,6 +5,8 @@
 #endif
 
 typedef struct RMap RMap;
+typedef struct Trace Trace;
+
 struct RMap {
 	int t[NReg];
 	int r[NReg];
@@ -12,6 +14,11 @@ struct RMap {
 	int n;
 };
 
+struct Trace {
+	Blk *b;
+	ulong w;
+};
+
 extern Ins insb[NIns], *curi;
 static ulong regu;     /* registers used */
 static Tmp *tmp;       /* function temporaries */
@@ -21,6 +28,13 @@ static struct {
 } *pm;                 /* parallel move constructed */
 static int cpm, npm;   /* capacity and size of pm */
 
+static int *
+hint(int t)
+{
+	t = phirepr(tmp, t);
+	return &tmp[t].hint;
+}
+
 static int
 rfind(RMap *m, int t)
 {
@@ -75,14 +89,14 @@ ralloc(RMap *m, int t)
 		r = rfind(m, t);
 		assert(r != -1);
 	} else {
-		r = tmp[t].hint;
+		r = *hint(t);
 		if (r == -1 || BGET(m->b, r))
 			for (r=RAX; BGET(m->b, r); r++)
 				if (r+1 == RAX+NReg)
 					diag("rega: no more regs");
 		radd(m, t, r);
-		if (tmp[t].hint == -1)
-			tmp[t].hint = r;
+		if (*hint(t) == -1)
+			*hint(t) = r;
 	}
 	return TMP(r);
 }
@@ -275,7 +289,6 @@ doblk(Blk *b, RMap *cur)
 	int t, x, r;
 	ulong rs;
 	Ins *i;
-	Phi *p;
 
 	if (rtype(b->jmp.arg) == RTmp)
 		b->jmp.arg = ralloc(cur, b->jmp.arg.val);
@@ -318,15 +331,17 @@ doblk(Blk *b, RMap *cur)
 			 	*/
 				t = i->arg[x].val;
 				if (r && !BGET(cur->b, r))
-				if (tmp[t].hint == -1)
-					tmp[t].hint = r;
+				if (*hint(t) == -1)
+					*hint(t) = r;
 				i->arg[x] = ralloc(cur, t);
 			}
 	}
-	b->in = cur->b;
-	for (p=b->phi; p; p=p->link)
-		if (rtype(p->to) == RTmp)
-			BCLR(b->in, p->to.val);
+}
+
+static int
+trcmp(const void *a, const void *b)
+{
+	return ((Trace *)b)->w - ((Trace *)a)->w;
 }
 
 /* register allocation
@@ -336,12 +351,14 @@ void
 rega(Fn *fn)
 {
 	int n, t, r, x;
+	ulong w;
 	Blk *b, *b1, *s, ***ps, *blist;
 	Ins *i;
 	RMap *end, *beg, cur;
 	Phi *p;
-	uint a;
+	uint u;
 	Ref src, dst;
+	Trace *tr;
 
 	regu = 0;
 	tmp = fn->tmp;
@@ -361,37 +378,82 @@ rega(Fn *fn)
 				tmp[i->to.val].hint = i->arg[0].val;
 		}
 
-	/* 2. assign registers following traces */
-	if (debug['R'])
-		fprintf(stderr, "> Register mappings:\n");
-
-	for (n=fn->nblk-1; n>=0; n--) {
+	/* 2. compute traces */
+	tr = alloc(fn->nblk * sizeof tr[0]);
+	for (n=0; n<fn->nblk; n++) {
 		b = fn->rpo[n];
+		b->visit = 0;
+		tr[n].b = b;
+		tr[n].w = b->loop;
+		for (u=0; u<b->npred; u++)
+			if (b->pred[u]->id < n)
+				tr[n].w += tr[b->pred[u]->id].w;
+	}
+	qsort(tr, fn->nblk, sizeof tr[0], trcmp);
+
+	/* 3. assign registers following traces */
+	if (debug['R'])
+		fprintf(stderr, "> Trace allocation:\n");
+	for (n=0; n<fn->nblk; n++) {
+		b = tr[n].b;
+		if (b->visit)
+			continue;
 		cur.n = 0;
 		cur.b = (Bits){{0}};
-		for (x=0; x<2; x++)
-			for (t=Tmp0; t<fn->ntmp; t++)
-				if (BGET(b->out, t))
-				if (!BGET(cur.b, t))
-				if (x == 1
-				|| ((r=tmp[t].hint) != -1 && !BGET(cur.b, r)))
-					ralloc(&cur, t);
-
-		end[n] = cur;
-		doblk(b, &cur);
-		beg[n] = cur;
-
-		if (debug['R']) {
+		if (debug['R'])
+			fprintf(stderr, "\t");
+		do {
+			if (debug['R'])
+				fprintf(stderr, " %s", b->name);
+			for (x=0; x<2; x++)
+				for (t=Tmp0; t<fn->ntmp; t++) {
+					assert(BGET(b->out, t) ||
+						!BGET(cur.b, t));
+					if (BGET(b->out, t))
+					if (!BGET(cur.b, t))
+					if (x==1 || (r=*hint(t)) != -1)
+					if (x==1 || !BGET(cur.b, r))
+						ralloc(&cur, t);
+				}
+			end[b->id] = cur;
+			doblk(b, &cur);
+			beg[b->id] = cur;
+			b->in = cur.b;
+			for (p=b->phi; p; p=p->link)
+				if (rtype(p->to) == RTmp) {
+					t = p->to.val;
+					BCLR(b->in, t);
+					rfree(&cur, t);
+				}
+			b->visit = 1;
+			for (s=0, w=0, u=0; u<b->npred; u++) {
+				b1 = b->pred[u];
+				if (b1->visit || b1->id >= b->id)
+					continue;
+				if (tr[b1->id].w > w) {
+					s = b1;
+					w = tr[b1->id].w;
+				}
+			}
+			b = s;
+		} while (b);
+		if (debug['R'])
+			fprintf(stderr, "\n");
+	}
+	if (debug['R'])  {
+		fprintf(stderr, "\n> Register mappings:\n");
+		for (n=0; n<fn->nblk; n++) {
+			b = fn->rpo[n];
 			fprintf(stderr, "\t%-10s beg", b->name);
 			mdump(&beg[n]);
 			fprintf(stderr, "\t           end");
 			mdump(&end[n]);
 		}
-	}
-	if (debug['R'])
 		fprintf(stderr, "\n");
+	}
+	free(tr);
 
-	/* 3. compose glue code */
+	/* 4. compose glue code */
 	blist = 0;
 	for (b=fn->start;; b=b->link) {
 		ps = (Blk**[3]){&b->s1, &b->s2, (Blk*[1]){0}};
@@ -406,9 +468,9 @@ rega(Fn *fn)
 						continue;
 					dst = TMP(r);
 				}
-				for (a=0; p->blk[a]!=b; a++)
-					assert(a+1 < p->narg);
-				src = p->arg[a];
+				for (u=0; p->blk[u]!=b; u++)
+					assert(u+1 < p->narg);
+				src = p->arg[u];
 				if (rtype(src) == RTmp)
 					src = rref(&end[b->id], src.val);
 				pmadd(src, dst, p->wide);