diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2017-05-16 11:33:41 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2017-05-16 11:33:41 -0400 |
commit | 425a2ed09c08222e1254d93dba24c7a50e7a08b9 (patch) | |
tree | 8637b9bcc9574e44e078994a4ea514289729e106 /live.c | |
parent | 51c46ba6914741cbca54d3351f8cf8d2689fd3dc (diff) | |
download | roux-425a2ed09c08222e1254d93dba24c7a50e7a08b9.tar.gz |
do not account for interferences in phi classes
Before this commit, I tried to make sure that two interfering temporaries never ended up in the same phi class. This was to make sure that their register hints were not counterproductively stepping on each other's toes. The idea is fine, but: * the implementation is clumsy because it mixes the orthogonal concepts of (i) interference and (ii) phi classes; * the hinting process in the register allocator is hard to understand because the disjoint-set data structure used for phi classes is cut in arbitrary places. After this commit, the phi classes *really* are phi classes represented with a proper disjoint-set data structure.
Diffstat (limited to 'live.c')
-rw-r--r-- | live.c | 52 |
1 files changed, 6 insertions, 46 deletions
diff --git a/live.c b/live.c index 6e63705..4198995 100644 --- a/live.c +++ b/live.c @@ -19,46 +19,13 @@ liveon(BSet *v, Blk *b, Blk *s) } } -static int -phitmp(int t, Tmp *tmp) -{ - int tp; - - tp = tmp[t].phi; - return tp ? tp : t; -} - -static void -phifix(int t1, int *phi, Tmp *tmp) -{ - int t, t2; - - /* detect temporaries arguments - * of the same phi node that - * interfere and separate them - */ - t = phitmp(t1, tmp); - t2 = phi[t]; - if (t2 && t2 != t1) { - if (t != t1) { - tmp[t1].phi = t1; - t = t1; - } else { - tmp[t2].phi = t2; - phi[t2] = t2; - } - } - phi[t] = t1; -} - static void -bset(Ref r, Blk *b, int *nlv, int *phi, Tmp *tmp) +bset(Ref r, Blk *b, int *nlv, Tmp *tmp) { if (rtype(r) != RTmp) return; bsset(b->gen, r.val); - phifix(r.val, phi, tmp); if (!bshas(b->in, r.val)) { nlv[KBASE(tmp[r.val].cls)]++; bsset(b->in, r.val); @@ -74,13 +41,11 @@ filllive(Fn *f) Blk *b; Ins *i; int k, t, m[2], n, chg, nlv[2]; - int *phi; BSet u[1], v[1]; Mem *ma; bsinit(u, f->ntmp); bsinit(v, f->ntmp); - phi = emalloc(f->ntmp * sizeof phi[0]); for (b=f->start; b; b=b->link) { bsinit(b->in, f->ntmp); bsinit(b->out, f->ntmp); @@ -102,21 +67,18 @@ Again: } chg |= !bsequal(b->out, u); - memset(phi, 0, f->ntmp * sizeof phi[0]); memset(nlv, 0, sizeof nlv); b->out->t[0] |= T.rglob; bscopy(b->in, b->out); - for (t=0; bsiter(b->in, &t); t++) { - phifix(t, phi, f->tmp); + for (t=0; bsiter(b->in, &t); t++) nlv[KBASE(f->tmp[t].cls)]++; - } if (rtype(b->jmp.arg) == RCall) { assert((int)bscount(b->in) == T.nrglob && nlv[0] == T.nrglob && nlv[1] == 0); b->in->t[0] |= T.retregs(b->jmp.arg, nlv); } else - bset(b->jmp.arg, b, nlv, phi, f->tmp); + bset(b->jmp.arg, b, nlv, f->tmp); for (k=0; k<2; k++) b->nlive[k] = nlv[k]; for (i=&b->ins[b->nins]; i!=b->ins;) { @@ -145,17 +107,16 @@ Again: nlv[KBASE(f->tmp[t].cls)]--; bsset(b->gen, t); bsclr(b->in, t); - phi[phitmp(t, f->tmp)] = 0; } for (k=0; k<2; k++) switch (rtype(i->arg[k])) { case RMem: ma = &f->mem[i->arg[k].val]; - bset(ma->base, b, nlv, phi, f->tmp); - bset(ma->index, b, nlv, phi, f->tmp); + bset(ma->base, b, nlv, f->tmp); + bset(ma->index, b, nlv, f->tmp); break; default: - bset(i->arg[k], b, nlv, phi, f->tmp); + bset(i->arg[k], b, nlv, f->tmp); break; } for (k=0; k<2; k++) @@ -167,7 +128,6 @@ Again: chg = 0; goto Again; } - free(phi); if (debug['L']) { fprintf(stderr, "\n> Liveness analysis:\n"); |