summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-07-22 03:00:03 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 23:01:28 -0400
commita6168e6ed5eaf6b9fa8834d0b3c52e34952999fd (patch)
treee01201d3cc0508f45c094bf89e73fe49db0a9752 /lisc
parent3538e769a7f4ee2591cc4961aef9f35a02ae20a9 (diff)
downloadroux-a6168e6ed5eaf6b9fa8834d0b3c52e34952999fd.tar.gz
attempt more correct loop marking
Diffstat (limited to 'lisc')
-rw-r--r--lisc/lisc.h3
-rw-r--r--lisc/main.c1
-rw-r--r--lisc/spill.c63
3 files changed, 38 insertions, 29 deletions
diff --git a/lisc/lisc.h b/lisc/lisc.h
index f44a0ab..1446f48 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -128,13 +128,14 @@ struct Blk {
 	Blk *s2;
 	Blk *link;
 
+	int id;
+	int visit;
 	Blk **pred;
 	uint npred;
 	Bits in, out, gen;
 	int nlive;
 	int loop;
 	char name[NString];
-	int id;
 };
 
 struct Sym {
diff --git a/lisc/main.c b/lisc/main.c
index ce0bc82..d1e21eb 100644
--- a/lisc/main.c
+++ b/lisc/main.c
@@ -76,6 +76,7 @@ main(int ac, char *av[])
 
 		fprintf(stderr, "[Testing Spilling]\n");
 		fillrpo(fn);
+		fillpreds(fn);
 		filllive(fn);
 		fillcost(fn);
 		fprintf(stderr, "> Spill costs:\n");
diff --git a/lisc/spill.c b/lisc/spill.c
index 4961139..3e4ad10 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -2,6 +2,21 @@
 
 
 static void
+loopmark(Blk **rpo, int head, int n)
+{
+	uint p;
+	Blk *b;
+
+	b = rpo[n];
+	if (n <= head || b->visit == head)
+		return;
+	b->visit = head;
+	b->loop *= 10;
+	for (p=0; p<b->npred; p++)
+		loopmark(rpo, head, b->pred[p]->id);
+}
+
+static void
 symuse(Ref r, int use, int loop, Fn *fn)
 {
 	Sym *s;
@@ -20,7 +35,7 @@ symuse(Ref r, int use, int loop, Fn *fn)
 
 /* evaluate spill costs of temporaries,
  * this also fills usage information
- * requires rpo
+ * requires rpo, preds
  */
 void
 fillcost(Fn *fn)
@@ -32,27 +47,17 @@ fillcost(Fn *fn)
 	Sym *s;
 	Phi *p;
 
-	/* todo, have somewhat proper loop
-	 * detection for example on this
-	 * cfg, it's bogus:
-	 * +> loop <+
-	 * |   /\   |
-	 * +- a  b -+
-	 *    |  |
-	 *     \/
-	 *     end
-	 */
-	for (b=fn->start; b; b=b->link)
+	for (b=fn->start; b; b=b->link) {
 		b->loop = 1;
-	for (n=fn->nblk-1; n>=0; n--) {
+		b->visit = -1;
+	}
+	for (n=0; n<fn->nblk; n++) {
 		b = fn->rpo[n];
-		m = n;
-		if (b->s1 && b->s1->id < m)
-			m = b->s1->id;
-		if (b->s2 && b->s2->id < m)
-			m = b->s2->id;
-		for (; m<n; m++)
-			fn->rpo[m]->loop *= 10;
+		for (a=0; a<b->npred; a++) {
+			m = b->pred[a]->id;
+			if (m >= n)
+				loopmark(fn->rpo, n, m);
+		}
 	}
 	for (s=fn->sym; s-fn->sym < fn->ntmp; s++) {
 		s->cost = 0;
@@ -75,7 +80,7 @@ fillcost(Fn *fn)
 		for (i=b->ins; i-b->ins < b->nins; i++) {
 			symuse(i->to, 0, n, fn);
 			symuse(i->arg[0], 1, n, fn);
-			symuse(i->arg[0], 1, n, fn);
+			symuse(i->arg[1], 1, n, fn);
 		}
 		symuse(b->jmp.arg, 1, n, fn);
 	}
@@ -164,7 +169,7 @@ limit(Bits *b, int k, Bits *fst)
 }
 
 static int
-lscan(Bits *use, Blk **rpo, int n0, int n1)
+loopscan(Bits *use, Blk **rpo, int hd, int n)
 {
 	int z, pl;
 	Blk *b;
@@ -183,20 +188,20 @@ lscan(Bits *use, Blk **rpo, int n0, int n1)
 
 	pl = 0;
 	*use = (Bits){{0}};
-	for (; n0<n1; n0++) {
-		b = rpo[n0];
+	for (; hd<=n; hd++) {
+		b = rpo[hd];
 		if (b->nlive > pl)
 			pl = b->nlive;
 		for (z=0; z<BITS; z++)
 			use->t[z] |= b->gen.t[z];
 	}
 	for (z=0; z<BITS; z++)
-		use->t[z] &= rpo[n1]->out.t[z];
+		use->t[z] &= rpo[n]->out.t[z];
 	return pl;
 }
 
 /* spill code insertion
- * requires spill costs and rpo
+ * requires spill costs, rpo, liveness
  *
  * Note: this will replace liveness
  * information (in, out) with temporaries
@@ -230,7 +235,8 @@ spill(Fn *fn)
 		 * the end of the block (put them in v) */
 		s1 = b->s1;
 		s2 = b->s2;
-		k = NReg - !req(b->jmp.arg, R);
+		// k = NReg - !req(b->jmp.arg, R);
+		k = 4 - !req(b->jmp.arg, R);
 		if (!s1) {
 			assert(!s2);
 			v = (Bits){{0}};
@@ -239,7 +245,7 @@ spill(Fn *fn)
 			hd = s1;
 			if (s2 && s2->id <= hd->id)
 				hd = s2;
-			pl = lscan(&v, fn->rpo, hd->id, n);
+			pl = loopscan(&v, fn->rpo, hd->id, n);
 			j = bcnt(&v);
 			if (j < k) {
 				w = b->out;
@@ -268,6 +274,7 @@ spill(Fn *fn)
 			v = limit(&v, k, &w);
 		}
 		assert(bcnt(&v) <= k);
+		b->out = v;
 
 		/* 2. process the block instructions */
 		curi = &insb[NIns];