diff options
-rw-r--r-- | lisc/lisc.h | 6 | ||||
-rw-r--r-- | lisc/rega.c | 26 | ||||
-rw-r--r-- | lisc/spill.c | 26 | ||||
-rw-r--r-- | lisc/util.c | 21 |
4 files changed, 68 insertions, 11 deletions
diff --git a/lisc/lisc.h b/lisc/lisc.h index 0912b1f..35113ff 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -246,7 +246,10 @@ struct Tmp { uint cost; short slot; short wide; - int hint; + struct { + int r; + ulong m; + } hint; int phi; }; @@ -335,6 +338,7 @@ void idup(Ins **, Ins *, ulong); Ins *icpy(Ins *, Ins *, ulong); void *vnew(ulong, size_t); void vgrow(void *, ulong); +int phicls(int, Tmp *); Ref newtmp(char *, Fn *); Ref getcon(int64_t, Fn *); void addcon(Con *, Con *); diff --git a/lisc/rega.c b/lisc/rega.c index 8d1bb1a..a55a871 100644 --- a/lisc/rega.c +++ b/lisc/rega.c @@ -25,10 +25,7 @@ static int cpm, npm; /* capacity and size of pm */ static int * hint(int t) { - if (tmp[t].phi) - return &tmp[tmp[t].phi].hint; - else - return &tmp[t].hint; + return &tmp[phicls(t, tmp)].hint.r; } static int @@ -75,6 +72,7 @@ radd(RMap *m, int t, int r) static Ref ralloc(RMap *m, int t) { + ulong regs; int r; if (t < Tmp0) { @@ -87,10 +85,16 @@ ralloc(RMap *m, int t) return TMP(r); } r = *hint(t); - if (r == -1 || BGET(m->b, r)) - for (r=RAX; BGET(m->b, r); r++) - if (r+1 == RAX+NReg) - diag("rega: no more regs"); + if (r == -1 || BGET(m->b, r)) { + regs = tmp[phicls(t, tmp)].hint.m; + regs |= m->b.t[0]; + for (r=RAX; r<RAX+NReg && (regs & BIT(r)); r++) + ; + if (r == RAX+NReg) + for (r=RAX; BGET(m->b, r); r++) + if (r+1 == RAX+NReg) + diag("rega: no more regs"); + } radd(m, t, r); if (*hint(t) == -1) *hint(t) = r; @@ -323,6 +327,10 @@ doblk(Blk *b, RMap *cur) i = dopm(b, i, cur); continue; } + if (isreg(i->to)) + if (rtype(i->arg[0]) == RTmp) + if (*hint(i->arg[0].val) == -1) + *hint(i->arg[0].val) = i->to.val; /* fall through */ default: if (!req(i->to, R)) { @@ -377,7 +385,7 @@ rega(Fn *fn) end = alloc(fn->nblk * sizeof end[0]); beg = alloc(fn->nblk * sizeof beg[0]); for (t=Tmp0; t<fn->ntmp; t++) - tmp[t].hint = -1; + *hint(t) = -1; for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++) if (i->op != OCopy || !isreg(i->arg[0])) break; diff --git a/lisc/spill.c b/lisc/spill.c index 662df3f..b0dcd1b 100644 --- a/lisc/spill.c +++ b/lisc/spill.c @@ -211,6 +211,16 @@ limit(Bits *b, int k, Bits *fst) } static void +sethint(Bits *u, ulong r) +{ + int t; + + for (t=Tmp0; t<ntmp; t++) + if (BGET(*u, t)) + tmp[phicls(t, tmp)].hint.m |= r; +} + +static void reloads(Bits *u, Bits *v) { int t; @@ -223,8 +233,10 @@ reloads(Bits *u, Bits *v) static Ins * dopm(Blk *b, Ins *i, Bits *v) { + int n; Bits u; Ins *i1; + ulong r; /* consecutive moves from * registers need to handled @@ -244,9 +256,15 @@ dopm(Blk *b, Ins *i, Bits *v) if (i > b->ins && (i-1)->op == OCall) { v->t[0] &= ~calldef(*(i-1), 0); limit(v, NReg - NRSave, 0); + r = 0; + for (n=0; n<NRSave; n++) + r |= BIT(rsave[n]); v->t[0] |= calluse(*(i-1), 0); - } else + } else { limit(v, NReg, 0); + r = v->t[0]; + } + sethint(v, r); reloads(&u, v); do emiti(*--i1); @@ -276,6 +294,7 @@ spill(Fn *fn) int j, s; Phi *p; Mem *ma; + ulong r; tmp = fn->tmp; ntmp = fn->ntmp; @@ -342,6 +361,7 @@ spill(Fn *fn) /* 2. process the block instructions */ curi = &insb[NIns]; + r = 0; for (i=&b->ins[b->nins]; i!=b->ins;) { assert(bcnt(&v) <= NReg); i--; @@ -400,11 +420,15 @@ spill(Fn *fn) i->arg[m] = slot(t); } } + r = v.t[0] & (BIT(Tmp0)-1); + if (r) + sethint(&v, r); reloads(&u, &v); if (s != -1) store(i->to, s); emiti(*i); } + assert(!r || b==fn->start); for (p=b->phi; p; p=p->link) { assert(rtype(p->to) == RTmp); diff --git a/lisc/util.c b/lisc/util.c index 993a3d7..7d03053 100644 --- a/lisc/util.c +++ b/lisc/util.c @@ -166,6 +166,27 @@ vgrow(void *vp, ulong len) *(Vec **)vp = v1; } +int +phicls(int t, Tmp *tmp /*, int c*/) +{ + if (tmp[t].phi) + return tmp[t].phi; + return t; +#if 0 + int t1; + + t1 = tmp[t].phi; + if (!t1) + t1 = t; + if (t != t1) { + t1 = phitmp(t1, tmp, c); + if (c) + tmp[t].phi = t1; + } + return t1; +#endif +} + Ref newtmp(char *prfx, Fn *fn) { |