diff options
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/spill.c | 159 |
1 files changed, 87 insertions, 72 deletions
diff --git a/lisc/spill.c b/lisc/spill.c index 7f967e4..08d3004 100644 --- a/lisc/spill.c +++ b/lisc/spill.c @@ -22,8 +22,10 @@ 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 > hd->nlive) - hd->nlive = b->nlive; + 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 (n=0; n<b->npred; n++) loopmark(hd, b->pred[n], b->phi); } @@ -77,7 +79,8 @@ fillcost(Fn *fn) } if (hd && debug['S']) { fprintf(stderr, "\t%-10s", b->name); - fprintf(stderr, " (% 3d) ", b->nlive); + fprintf(stderr, " (% 3d ", b->nlive[0]); + fprintf(stderr, "% 3d) ", b->nlive[1]); dumpts(&b->gen, fn->tmp, stderr); } } @@ -155,7 +158,7 @@ slot(int t) * * invariant: slot4 <= slot8 */ - if (tmp[t].wide) { + if (KWIDE(tmp[t].cls)) { s = slot8; if (slot4 == slot8) slot4 += 2; @@ -175,15 +178,6 @@ slot(int t) } static void -store(Ref r, int s) -{ - if (tmp[r.val].wide) - emit(OStorel, 0, R, r, SLOT(s)); - else - emit(OStorew, 0, R, r, SLOT(s)); -} - -static void limit(Bits *b, int k, Bits *fst) { static int *tarr, maxt; @@ -229,23 +223,48 @@ sethint(Bits *u, ulong r) static void reloads(Bits *u, Bits *v) { - int t; + /* fixme, oooh really... */ + static int kload[] = { + [Kw] = OLoadsw, [Kl] = OLoadl, + [Ks] = OLoads, [Kd] = OLoadd + }; + int t, k; for (t=Tmp0; t<ntmp; t++) - if (BGET(*u, t) && !BGET(*v, t)) - emit(OLoad, tmp[t].wide, TMP(t), slot(t), R); + if (BGET(*u, t) && !BGET(*v, t)) { + k = tmp[t].cls; + emit(kload[k], k, TMP(t), slot(t), R); + } +} + +static void +store(Ref r, int s) +{ + static int kstore[] = { + [Kw] = OStorew, [Kl] = OStorel, + [Ks] = OStores, [Kd] = OStored, + }; + + if (s != -1) + emit(kstore[tmp[r.val].cls], 0, R, r, SLOT(s)); +} + +static int +regcpy(Ins *i) +{ + return i->op == OCopy && isreg(i->arg[0]); } static Ins * dopm(Blk *b, Ins *i, Bits *v) { - int n, s, t; + int n, t; Bits u; Ins *i1; ulong r; /* consecutive copies from - * registers need to handled + * registers need to be handled * as one large instruction * * fixme: there is an assumption @@ -261,14 +280,10 @@ dopm(Blk *b, Ins *i, Bits *v) if (!req(i->to, R)) if (BGET(*v, t)) { BCLR(*v, t); - s = tmp[t].slot; - if (s != -1) - store(i->to, s); + store(i->to, tmp[t].slot); } BSET(*v, i->arg[0].val); - } while (i != b->ins && - (i-1)->op == OCopy && - isreg((i-1)->arg[0])); + } while (i != b->ins && regcpy(i-1)); u = *v; if (i != b->ins && (i-1)->op == OCall) { v->t[0] &= ~calldef(*(i-1), 0); @@ -305,8 +320,8 @@ void spill(Fn *fn) { Blk *b, *s1, *s2, *hd; - int n, m, z, l, t, lvarg[2]; - Bits u, v, w; + int n, m, z, l, t, k, nr, lvarg[2]; + Bits u, v[2], w, mask[2]; Ins *i; int j, s; Phi *p; @@ -320,18 +335,14 @@ spill(Fn *fn) slot8 = 0; assert(ntmp < NBit*BITS); - for (b=fn->start; b; b=b->link) { - for (p=b->phi; p; p=p->link) - tmp[p->to.val].wide = p->wide; - for (i=b->ins; i-b->ins < b->nins; i++) - if (rtype(i->to) == RTmp) - /* Note: this only works because - * all OCmp operations were eliminated - * indeed, the wide bit of those refer - * to the size of the operands - */ - tmp[i->to.val].wide = i->wide; - } + 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 (n=fn->nblk-1; n>=0; n--) { /* invariant: m>n => in,out of m updated */ @@ -342,44 +353,51 @@ spill(Fn *fn) curi = 0; s1 = b->s1; s2 = b->s2; - BZERO(v); hd = 0; if (s1 && s1->id <= n) hd = s1; if (s2 && s2->id <= n) if (!hd || s2->id >= hd->id) hd = s2; - if (hd) { - /* back-edge */ - l = hd->nlive; - for (z=0; z<BITS; z++) - v.t[z] = hd->gen.t[z] & b->out.t[z]; - j = bcnt(&v); - if (j < NReg) { - w = b->out; - for (z=0; z<BITS; z++) - w.t[z] &= ~v.t[z]; - j = bcnt(&w); /* live through */ - limit(&w, NReg - (l - j), 0); - for (z=0; z<BITS; z++) - v.t[z] |= w.t[z]; - } else if (j > NReg) - limit(&v, NReg, 0); - } else if (s1) { - v = liveon(b, s1); - w = v; - if (s2) { - u = liveon(b, s2); + for (k=0; k<2; k++) { + nr = k == 0 ? NIReg : NFReg; + if (hd) { + /* back-edge */ for (z=0; z<BITS; z++) { - v.t[z] |= u.t[z]; - w.t[z] &= u.t[z]; + v[k].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) { + j = bcnt(&w); /* live through */ + l = hd->nlive[k]; + limit(&w, nr - (l - j), 0); + for (z=0; z<BITS; z++) + v[k].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(&v[k], nr, &w); } - assert(bcnt(&w) <= NReg); - limit(&v, NReg, &w); } - b->out = v; - assert(bcnt(&v) <= NReg); + BZERO(b->out); + for (z=0; z<BITS; z++) + for (k=0; k<2; k++) + b->out.t[z] |= v[k].t[z]; /* 2. process the block instructions */ curi = &insb[NIns]; @@ -387,7 +405,7 @@ spill(Fn *fn) for (i=&b->ins[b->nins]; i!=b->ins;) { assert(bcnt(&v) <= NReg); i--; - if (i->op == OCopy && isreg(i->arg[0])) { + if (regcpy(i)) { i = dopm(b, i, &v); continue; } @@ -448,8 +466,7 @@ spill(Fn *fn) if (r) sethint(&v, r); reloads(&u, &v); - if (s != -1) - store(i->to, s); + store(i->to, s); emiti(*i); } assert(!r || b==fn->start); @@ -459,9 +476,7 @@ spill(Fn *fn) t = p->to.val; if (BGET(v, t)) { BCLR(v, t); - s = tmp[t].slot; - if (s != -1) - store(p->to, s); + store(p->to, tmp[t].slot); } else p->to = slot(p->to.val); } |