diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-08-08 00:18:31 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-15 23:01:30 -0400 |
commit | 1721fe43137e54e05a62663235a5a8cebb7f4761 (patch) | |
tree | 3c8f9ea661ebced5787b0b701ce1f630e4750ade | |
parent | 83131357f7a15ee28208e41b1503937df34b99ba (diff) | |
download | roux-1721fe43137e54e05a62663235a5a8cebb7f4761.tar.gz |
fix a bug in setloc
The way we detected if limit had spilled a variable was incorrect. This is because two consecutive calls to limit could require a spill of the same variable. Instead, we now use a return value from limit. Note that this is still not so ideal. Indeed, it works properly only when limit spills one value only, if not, we should return a bitset. In the current use scheme of limit, this invariant is true but ideally we would like to call limit with *all arguments added at once*, not one after the other.
-rw-r--r-- | lisc/spill.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/lisc/spill.c b/lisc/spill.c index 7361b11..ca7d962 100644 --- a/lisc/spill.c +++ b/lisc/spill.c @@ -184,16 +184,15 @@ emit(short op, Ref to, Ref arg0, Ref arg1) *--curi = (Ins){op, to, {arg0, arg1}}; } -static Bits +static int limit(Bits *b, int k, Bits *fst) { static int *tarr, maxt; int i, t, nt; - Bits res; nt = bcnt(b); if (nt <= k) - return *b; + return 0; if (nt > maxt) { free(tarr); tarr = alloc(nt * sizeof tarr[0]); @@ -201,8 +200,10 @@ limit(Bits *b, int k, Bits *fst) } i = 0; for (t=0; t<ntmp; t++) - if (BGET(*b, t)) + if (BGET(*b, t)) { + BCLR(*b, t); tarr[i++] = t; + } assert(i == nt); if (!fst) qsort(tarr, nt, sizeof tarr[0], tcmp0); @@ -210,15 +211,16 @@ limit(Bits *b, int k, Bits *fst) f = fst; qsort(tarr, nt, sizeof tarr[0], tcmp1); } - res = (Bits){{0}}; for (i=0; i<k && i<nt; i++) - BSET(res, tarr[i]); + BSET(*b, tarr[i]); for (; i<nt; i++) { slot(tarr[i]); - if (curi) + if (curi) { emit(OLoad, TMP(tarr[i]), slot(tarr[i]), R); + t = tarr[i]; + } } - return res; + return t; } static void @@ -243,9 +245,7 @@ setloc(Ref *pr, Bits *v, Bits *w) return; t = pr->val; BSET(*v, t); - *v = limit(v, nreg, w); - if (curi->op == OLoad) - if (curi->to.val == 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 */ @@ -313,11 +313,11 @@ spill(Fn *fn) for (z=0; z<BITS; z++) w.t[z] &= ~v.t[z]; j = bcnt(&w); /* live through */ - w = limit(&w, NReg - (l - j), 0); + limit(&w, NReg - (l - j), 0); for (z=0; z<BITS; z++) v.t[z] |= w.t[z]; } else if (j > NReg) - v = limit(&v, NReg, 0); + limit(&v, NReg, 0); } else if (s1) { v = s1->in; w = s1->in; @@ -327,7 +327,7 @@ spill(Fn *fn) w.t[z] &= s2->in.t[z]; } assert(bcnt(&w) <= NReg); - v = limit(&v, NReg, &w); + limit(&v, NReg, &w); } b->out = v; assert(bcnt(&v) <= NReg); @@ -347,7 +347,7 @@ spill(Fn *fn) if (BGET(v, j)) BCLR(v, j); else - v = limit(&v, nreg-1, &w); + limit(&v, nreg-1, &w); s = tmp[j].spill; break; case RReg: @@ -356,13 +356,13 @@ spill(Fn *fn) BCLR(br, j); nreg++; } else - v = limit(&v, nreg-1, &w); + limit(&v, nreg-1, &w); break; case -1:; } w = (Bits){{0}}; - setloc(&i->arg[1], &v, &w); setloc(&i->arg[0], &v, &w); + setloc(&i->arg[1], &v, &w); if (s) emit(OStore, R, i->to, SLOT(s)); emit(i->op, i->to, i->arg[0], i->arg[1]); |