diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2017-03-29 00:16:46 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2017-03-29 00:16:46 -0400 |
commit | 81e2fdacc536dab7ad3c1e1da313b80f5ae935b7 (patch) | |
tree | 91768d923da523502211c3c0b130351580852abb | |
parent | 02408ffd8f95a4334212e1d64de987f9192cb4d5 (diff) | |
download | roux-81e2fdacc536dab7ad3c1e1da313b80f5ae935b7.tar.gz |
improve global registers handling
The register allocation now has stricter assertions about global registers. The stricter assertions required changes in the spiller: We now correctly indicate to the register allocator what registers are used by "ret" instructions.
-rw-r--r-- | rega.c | 12 | ||||
-rw-r--r-- | spill.c | 16 |
2 files changed, 18 insertions, 10 deletions
diff --git a/rega.c b/rega.c index 9f02a63..3d83327 100644 --- a/rega.c +++ b/rega.c @@ -135,6 +135,7 @@ rfree(RMap *m, int t) { int i, r; + assert(t >= Tmp0 || !(BIT(t) & RGLOB)); if (!bshas(m->b, t)) return -1; for (i=0; m->t[i] != t; i++) @@ -145,6 +146,7 @@ rfree(RMap *m, int t) m->n--; memmove(&m->t[i], &m->t[i+1], (m->n-i) * sizeof m->t[0]); memmove(&m->r[i], &m->r[i+1], (m->n-i) * sizeof m->r[0]); + assert(t >= Tmp0 || t == r); return r; } @@ -385,13 +387,15 @@ doblk(Blk *b, RMap *cur) default: if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); - r = rfree(cur, i->to.val); - if (r == -1 && !isreg(i->to)) { + r = i->to.val; + if (r >= Tmp0 || !(BIT(r) & RGLOB)) + r = rfree(cur, r); + if (r == -1) { + assert(!isreg(i->to)); *i = (Ins){.op = Onop}; continue; } - if (i->to.val >= Tmp0) - i->to = TMP(r); + i->to = TMP(r); } break; } diff --git a/spill.c b/spill.c index 5e2b9ec..0872fd5 100644 --- a/spill.c +++ b/spill.c @@ -298,7 +298,8 @@ void spill(Fn *fn) { Blk *b, *s1, *s2, *hd, **bp; - int j, n, l, t, k, lvarg[2]; + int j, l, t, k, lvarg[2]; + uint n; BSet u[1], v[1], w[1]; Ins *i; Phi *p; @@ -340,7 +341,6 @@ spill(Fn *fn) if (s2 && s2->id <= b->id) if (!hd || s2->id >= hd->id) hd = s2; - r = 0; if (hd) { /* back-edge */ bszero(v); @@ -352,8 +352,8 @@ spill(Fn *fn) bscopy(w, u); bsinter(u, hd->gen); bsdiff(w, hd->gen); - if ((int)bscount(u) < n) { /* fixme */ - j = bscount(w); /* live through */ + if (bscount(u) < n) { + j = bscount(w); /* live through */ l = hd->nlive[k]; limit(w, n - (l - j), 0); bsunion(u, w); @@ -370,14 +370,18 @@ spill(Fn *fn) bsunion(v, u); } limit2(v, 0, 0, w); - } else + } else { bscopy(v, b->out); + if (rtype(b->jmp.arg) == RCall) + v->t[0] |= retregs(b->jmp.arg, 0); + } for (t=Tmp0; bsiter(b->out, &t); t++) if (!bshas(v, t)) slot(t); bscopy(b->out, v); /* 2. process the block instructions */ + r = v->t[0] & (BIT(Tmp0)-1); curi = &insb[NIns]; for (i=&b->ins[b->nins]; i!=b->ins;) { i--; @@ -449,7 +453,7 @@ spill(Fn *fn) if (r) sethint(v, r); } - assert(!(r & ~RGLOB) || b==fn->start); + assert(r == RGLOB || b == fn->start); for (p=b->phi; p; p=p->link) { assert(rtype(p->to) == RTmp); |