diff options
Diffstat (limited to 'lisc/live.c')
-rw-r--r-- | lisc/live.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/lisc/live.c b/lisc/live.c index 5a08363..7449d84 100644 --- a/lisc/live.c +++ b/lisc/live.c @@ -1,12 +1,24 @@ #include "lisc.h" static void -bset(Ref r, Blk *b, int *nlv) +bset(Ref r, Blk *b, Bits *rb, int *nlv) { - if (rtype(r) == RSym && !BGET(b->in, r.val)) { - ++*nlv; - BSET(b->in, r.val); + Bits *bs; + + switch (rtype(r)) { + case RSym: + bs = &b->in; BSET(b->gen, r.val); + break; + case RReg: + bs = rb; + break; + default: + diag("live: unhandled reference"); + } + if (!BGET(*bs, r.val)) { + ++*nlv; + BSET(*bs, r.val); } } @@ -21,9 +33,9 @@ filllive(Fn *f) Phi *p; int z, n, chg, nlv; uint a; - Bits tb; + Bits tb, rb; - assert(f->ntmp <= NBit*BITS); + assert(f->nsym <= NBit*BITS); for (b=f->start; b; b=b->link) { b->in = (Bits){{0}}; b->out = (Bits){{0}}; @@ -44,17 +56,25 @@ Again: chg |= memcmp(&b->out, &tb, sizeof(Bits)); b->in = b->out; + rb = (Bits){{0}}; nlv = bcnt(&b->in); - bset(b->jmp.arg, b, &nlv); + bset(b->jmp.arg, b, &rb, &nlv); b->nlive = nlv; for (i=&b->ins[b->nins]; i!=b->ins;) { i--; - if (!req(i->to, R)) { + switch (rtype(i->to)) { + case RSym: nlv -= BGET(b->in, i->to.val); BCLR(b->in, i->to.val); + break; + case RReg: + nlv -= BGET(rb, i->to.val); + BCLR(rb, i->to.val); + default: + diag("live: unhandled destination"); } - bset(i->arg[0], b, &nlv); - bset(i->arg[1], b, &nlv); + bset(i->arg[0], b, &rb, &nlv); + bset(i->arg[1], b, &rb, &nlv); if (nlv > b->nlive) b->nlive = nlv; } |