summary refs log tree commit diff
path: root/lisc/spill.c
diff options
context:
space:
mode:
Diffstat (limited to 'lisc/spill.c')
-rw-r--r--lisc/spill.c176
1 files changed, 90 insertions, 86 deletions
diff --git a/lisc/spill.c b/lisc/spill.c
index 0123edf..966f7aa 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -3,7 +3,7 @@
 static void
 loopmark(Blk *hd, Blk *b, Phi *p)
 {
-	int z, head;
+	int k, z, head;
 	uint n, a;
 
 	head = hd->id;
@@ -22,10 +22,9 @@ loopmark(Blk *hd, Blk *b, Phi *p)
 	 * loop headers */
 	for (z=0; z<BITS; z++)
 		hd->gen.t[z] |= b->gen.t[z];
-	if (b->nlive[0] > hd->nlive[0])
-		hd->nlive[0] = b->nlive[0];
-	if (b->nlive[1] > hd->nlive[1])
-		hd->nlive[1] = b->nlive[1];
+	for (k=0; k<2; k++)
+		if (b->nlive[k] > hd->nlive[k])
+			hd->nlive[k] = b->nlive[k];
 	for (n=0; n<b->npred; n++)
 		loopmark(hd, b->pred[n], b->phi);
 }
@@ -120,12 +119,13 @@ fillcost(Fn *fn)
 	}
 }
 
-static Bits *f;   /* temps to prioritize in registers (for tcmp1) */
+static Bits *fst; /* temps to prioritize in registers (for tcmp1) */
 static Tmp *tmp;  /* current temporaries (for tcmpX) */
 static int ntmp;  /* current # of temps (for limit) */
 static int locs;  /* stack size used by locals */
 static int slot4; /* next slot of 4 bytes */
 static int slot8; /* ditto, 8 bytes */
+static Bits mask[2]; /* class masks */
 
 static int
 tcmp0(const void *pa, const void *pb)
@@ -138,7 +138,7 @@ tcmp1(const void *pa, const void *pb)
 {
 	int c;
 
-	c = BGET(*f, *(int *)pb) - BGET(*f, *(int *)pa);
+	c = BGET(*fst, *(int *)pb) - BGET(*fst, *(int *)pa);
 	return c ? c : tcmp0(pa, pb);
 }
 
@@ -178,7 +178,7 @@ slot(int t)
 }
 
 static void
-limit(Bits *b, int k, Bits *fst)
+limit(Bits *b, int k, Bits *f)
 {
 	static int *tarr, maxt;
 	int i, t, nt;
@@ -198,10 +198,10 @@ limit(Bits *b, int k, Bits *fst)
 			tarr[i++] = t;
 		}
 	assert(i == nt);
-	if (!fst)
+	if (!f)
 		qsort(tarr, nt, sizeof tarr[0], tcmp0);
 	else {
-		f = fst;
+		fst = f;
 		qsort(tarr, nt, sizeof tarr[0], tcmp1);
 	}
 	for (i=0; i<k && i<nt; i++)
@@ -210,6 +210,36 @@ limit(Bits *b, int k, Bits *fst)
 		slot(tarr[i]);
 }
 
+static int
+nreg(int k)
+{
+	switch (k) {
+	default:
+		diag("spill: nreg defaulted");
+	case 0:
+		return NIReg;
+	case 1:
+		return NFReg;
+	}
+}
+
+static void
+limit2(Bits *b, Bits *fst)
+{
+	Bits u, t;
+	int k, z;
+
+	t = *b;
+	BZERO(*b);
+	for (k=0; k<2; k++) {
+		for (z=0; z<BITS; z++)
+			u.t[z] = t.t[z] & mask[k].t[z];
+		limit(&u, nreg(k), fst);
+		for (z=0; z<BITS; z++)
+			b->t[z] |= u.t[z];
+	}
+}
+
 static void
 sethint(Bits *u, ulong r)
 {
@@ -320,8 +350,8 @@ void
 spill(Fn *fn)
 {
 	Blk *b, *s1, *s2, *hd, **bp;
-	int n, z, l, t, k, nr, lvarg[2];
-	Bits u, v[2], w, mask[2];
+	int n, z, l, t, k, lvarg[2];
+	Bits u, v, w;
 	Ins *i;
 	int j, s;
 	Phi *p;
@@ -330,19 +360,20 @@ spill(Fn *fn)
 
 	tmp = fn->tmp;
 	ntmp = fn->ntmp;
+	assert(ntmp < NBit*BITS);
 	locs = fn->slot;
 	slot4 = 0;
 	slot8 = 0;
-	assert(ntmp < NBit*BITS);
-
 	BZERO(mask[0]);
 	BZERO(mask[1]);
-	for (t=Tmp0; t<ntmp; t++)
-		BSET(mask[KBASE(tmp[t].cls)], t);
-	for (t=0; t < NIReg; t++)         /* could use the .cls of regs */
-		BSET(mask[0], RAX + t);
-	for (t=0; t < NFReg; t++)
-		BSET(mask[1], XMM0 + t);
+	for (t=0; t<ntmp; t++) {
+		k = 0;
+		if (t >= XMM0 && t < XMM0 + NFReg)
+			k = 1;
+		else if (t >= Tmp0)
+			k = KBASE(tmp[t].cls);
+		BSET(mask[k], t);
+	}
 
 	for (bp=&fn->rpo[fn->nblk-1]; bp!=fn->rpo;) {
 		b = *--bp;
@@ -360,67 +391,60 @@ spill(Fn *fn)
 		if (s2 && s2->id <= n)
 		if (!hd || s2->id >= hd->id)
 			hd = s2;
-		for (k=0; k<2; k++) {
-			nr = k == 0 ? NIReg : NFReg;
-			if (hd) {
-				/* back-edge */
+		if (hd) {
+			/* back-edge */
+			BZERO(v);
+			for (k=0; k<2; k++) {
+				n = nreg(k);
 				for (z=0; z<BITS; z++) {
-					v[k].t[z] = b->out.t[z]
+					u.t[z] = b->out.t[z]
 						& hd->gen.t[z]
 						& mask[k].t[z];
 					w.t[z] = b->out.t[z]
 						& ~hd->gen.t[z]
 						& mask[k].t[z];
 				}
-				j = bcnt(&v[k]);
-				if (j < nr) {
+				if (bcnt(&u) < n) {
 					j = bcnt(&w);   /* live through */
 					l = hd->nlive[k];
-					limit(&w, nr - (l - j), 0);
+					limit(&w, n - (l - j), 0);
 					for (z=0; z<BITS; z++)
-						v[k].t[z] |= w.t[z];
+						u.t[z] |= w.t[z];
 				} else
-					limit(&v[k], nr, 0);
-			} else if (s1) {
-				w = liveon(b, s1);
-				v[k] = w;
-				if (s2) {
-					u = liveon(b, s2);
-					for (z=0; z<BITS; z++) {
-						v[k].t[z] |= u.t[z];
-						v[k].t[z] &= mask[k].t[z];
-						w.t[z] &= u.t[z];
-					}
+					limit(&u, n, 0);
+				for (z=0; z<BITS; z++)
+					v.t[z] |= u.t[z];
+			}
+		} else if (s1) {
+			v = liveon(b, s1);
+			if (s2) {
+				w = liveon(b, s2);
+				for (z=0; z<BITS; z++) {
+					r = v.t[z];
+					v.t[z] |= w.t[z];
+					w.t[z] &= r;
 				}
-				limit(&v[k], nr, &w);
 			}
+			limit2(&v, &w);
 		}
-		BZERO(b->out);
-		for (z=0; z<BITS; z++)
-			for (k=0; k<2; k++)
-				b->out.t[z] |= v[k].t[z];
+		b->out = v;
 
 		/* 2. process the block instructions */
 		curi = &insb[NIns];
 		r = 0;
 		for (i=&b->ins[b->nins]; i!=b->ins;) {
-			assert(bcnt(&v[0]) <= NIReg);
-			assert(bcnt(&v[1]) <= NFReg);
 			i--;
 			if (regcpy(i)) {
-				//                               LATER
-				// i = dopm(b, i, &v);
-				//                               LATER
+				i = dopm(b, i, &v);
 				continue;
 			}
 			s = -1;
 			if (!req(i->to, R)) {
 				assert(rtype(i->to) == RTmp);
 				t = i->to.val;
-				if (!BGET(v[0], t) && !BGET(v[1], t))
+				if (!BGET(v, t))
 					diag("obvious dead code in isel");
-				BCLR(v[0], t);
-				BCLR(v[1], t);
+				BCLR(v, t);
 				s = tmp[t].slot;
 			}
 			BZERO(w);
@@ -433,40 +457,28 @@ spill(Fn *fn)
 					t = i->arg[n].val;
 					m = &fn->mem[t & AMask];
 					if (rtype(m->base) == RTmp) {
-						BSET(v[0], m->base.val);
+						BSET(v, m->base.val);
 						BSET(w, m->base.val);
 					}
 					if (rtype(m->index) == RTmp) {
-						BSET(v[0], m->index.val);
+						BSET(v, m->index.val);
 						BSET(w, m->index.val);
 					}
 					break;
 				case RTmp:
 					t = i->arg[n].val;
-					lvarg[n] = BGET(v[0], t) || BGET(v[1], t);
-					k = KBASE(tmp[t].cls);
-					BSET(v[k], t);
+					lvarg[n] = BGET(v, t);
+					BSET(v, t);
 					if (j-- <= 0)
 						BSET(w, t);
 					break;
 				}
-			BZERO(u);
-			for (z=0; z<BITS; z++)
-				for (k=0; k<2; k++)
-					u.t[z] |= v[k].t[z];
-			limit(&v[0], NIReg, &w);
-			limit(&v[1], NFReg, &w);
-
-
-
-
-
-
+			u = v;
+			limit2(&v, &w);
 			for (n=0; n<2; n++)
 				if (rtype(i->arg[n]) == RTmp) {
 					t = i->arg[n].val;
-					if (!BGET(v[0], t)
-					&&  !BGET(v[1], t)) {
+					if (!BGET(v, t)) {
 						/* do not reload if the
 						 * the temporary was dead
 						 */
@@ -475,14 +487,10 @@ spill(Fn *fn)
 						i->arg[n] = slot(t);
 					}
 				}
-			r = 0;
-			for (k=0; k<2; k++)
-				r |= v[k].t[0] & (BIT(Tmp0)-1);
+			r = v.t[0] & (BIT(Tmp0)-1);
 			if (r)
-				for (k=0; k<2; k++)
-					sethint(&v[k], r);
-			for (k=0; k<2; k++)
-				reloads(&u, &v[k]);
+				sethint(&v, r);
+			reloads(&u, &v);
 			store(i->to, s);
 			emiti(*i);
 		}
@@ -491,17 +499,13 @@ spill(Fn *fn)
 		for (p=b->phi; p; p=p->link) {
 			assert(rtype(p->to) == RTmp);
 			t = p->to.val;
-			if (BGET(v[0], t) || BGET(v[1], t)) {
-				BCLR(v[0], t);
-				BCLR(v[1], t);
+			if (BGET(v, t)) {
+				BCLR(v, t);
 				store(p->to, tmp[t].slot);
 			} else
 				p->to = slot(p->to.val);
 		}
-		BZERO(b->in);
-		for (z=0; z<BITS; z++)
-			for (k=0; k<2; k++)
-				b->in.t[z] |= v[k].t[z];
+		b->in = v;
 		b->nins = &insb[NIns] - curi;
 		idup(&b->ins, curi, b->nins);
 	}