summary refs log tree commit diff
path: root/lisc/spill.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-08-13 16:10:54 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 23:01:31 -0400
commit5fc8104e00187335411e35ec951bef53562c8fcd (patch)
treeb4f26312a5eef7062c3aa8501a6a8f6efe77a675 /lisc/spill.c
parent78bf28f56e7dcdd89efba5c69bd90ed858658162 (diff)
downloadroux-5fc8104e00187335411e35ec951bef53562c8fcd.tar.gz
major lifting: get rid of RReg
I've been septic since I introduced it, this commit
proves that it costs more than it helps.  I've also fixed
a bad bug in rega() where I alloc'ed the wrong size for
internal arrays.  Enums now have names so I can use them
to cast in gdb to get the name corresponding to a constant.
Diffstat (limited to 'lisc/spill.c')
-rw-r--r--lisc/spill.c47
1 files changed, 10 insertions, 37 deletions
diff --git a/lisc/spill.c b/lisc/spill.c
index 6554316..ad461f0 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -34,7 +34,7 @@ tmpuse(Ref r, int use, int loop, Fn *fn)
 {
 	Tmp *t;
 
-	if (rtype(r) != RTmp)
+	if (rtype(r) != RTmp || r.val < Tmp0)
 		return;
 	t = &fn->tmp[r.val];
 	t->nuse += use;
@@ -77,7 +77,7 @@ fillcost(Fn *fn)
 		}
 	}
 	for (t=fn->tmp; t-fn->tmp < fn->ntmp; t++) {
-		t->cost = 0;
+		t->cost = t-fn->tmp < Tmp0 ? 1e6 : 0;
 		t->nuse = 0;
 		t->ndef = 0;
 	}
@@ -104,7 +104,7 @@ fillcost(Fn *fn)
 	}
 	if (debug['S']) {
 		fprintf(stderr, "\n> Spill costs:\n");
-		for (n=0; n<fn->ntmp; n++)
+		for (n=Tmp0; n<fn->ntmp; n++)
 			fprintf(stderr, "\t%-10s %d\n",
 				fn->tmp[n].name,
 				fn->tmp[n].cost);
@@ -145,8 +145,6 @@ static Bits *f;  /* temps to prioritize in registers (for tcmp1) */
 static Tmp *tmp; /* current temporaries (for tcmpX) */
 static int ntmp; /* current # of temps (for limit) */
 static uint ns;  /* current # of spill slots */
-static int nreg; /* # of registers available */
-static Bits br;  /* live registers */
 
 static int
 tcmp0(const void *pa, const void *pb)
@@ -168,6 +166,8 @@ slot(int t)
 {
 	int s;
 
+	if (t < Tmp0)
+		diag("spill: cannot spill register");
 	s = tmp[t].spill;
 	if (!s) {
 		s = ++ns;
@@ -237,24 +237,11 @@ setloc(Ref *pr, Bits *v, Bits *w)
 {
 	int t;
 
-	/* <arch>
-	 *   here we assume that the
-	 *   machine can always support
-	 *   instructions of the kind
-	 *   reg = op slot, slot
-	 *   if not, we need to add
-	 *   't' to 'w' before calling
-	 *   limit
-	 */
-	if (rtype(*pr) == RReg) {
-		nreg -= !BGET(br, pr->val);
-		BSET(br, pr->val);
-	}
 	if (rtype(*pr) != RTmp)
 		return 0;
 	t = pr->val;
 	BSET(*v, t);
-	if (limit(v, nreg, w) == t)
+	if (limit(v, NReg, w) == t)
 		/* if t was spilled by limit,
 		 * it was not live so we don't
 		 * have to reload it */
@@ -300,7 +287,6 @@ spill(Fn *fn)
 	for (n=fn->nblk-1; n>=0; n--) {
 		/* invariant: m>n => in,out of m updated */
 		b = fn->rpo[n];
-		assert(bcnt(&br) == 0);
 
 		/* 1. find temporaries in registers at
 		 * the end of the block (put them in v) */
@@ -345,32 +331,19 @@ spill(Fn *fn)
 		assert(bcnt(&v) <= NReg);
 
 		/* 2. process the block instructions */
-		nreg = NReg;
 		curi = &insb[NIns];
 		for (i=&b->ins[b->nins]; i!=b->ins;) {
-			assert(bcnt(&v) <= nreg);
+			assert(bcnt(&v) <= NReg);
 			i--;
 			s = 0;
-			switch (rtype(i->to)) {
-			default:
-				diag("spill: unhandled destination");
-			case RTmp:
+			if (!req(i->to, R)) {
+				assert(rtype(i->to) == RTmp);
 				j = i->to.val;
 				if (BGET(v, j))
 					BCLR(v, j);
 				else
-					limit(&v, nreg-1, &w);
+					limit(&v, NReg-1, &w);
 				s = tmp[j].spill;
-				break;
-			case RReg:
-				j = i->to.val;
-				if (BGET(br, j)) {
-					BCLR(br, j);
-					nreg++;
-				} else
-					limit(&v, nreg-1, &w);
-				break;
-			case -1:;
 			}
 			w = (Bits){{0}};
 			j = opdesc[i->op].nmem;