diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-07-29 16:10:37 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-15 23:01:29 -0400 |
commit | 33b0d919e82bced689de12ba10546e5db33a090c (patch) | |
tree | af85222f29946d1ec6dfed2b534e6bdecce17e16 /lisc | |
parent | bd0a00e555cd9653f51a4b42dfe893ebb5e67d0c (diff) | |
download | roux-33b0d919e82bced689de12ba10546e5db33a090c.tar.gz |
add support for in-block reg. contraints
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/rega.c | 121 |
1 files changed, 89 insertions, 32 deletions
diff --git a/lisc/rega.c b/lisc/rega.c index b1731b8..a003563 100644 --- a/lisc/rega.c +++ b/lisc/rega.c @@ -45,10 +45,11 @@ rref(RMap *m, int t) static void radd(RMap *m, int t, int r) { - assert(m->n <= NReg); - assert(sym[t].type == STmp && "invalid allocation"); + assert(sym[t].type == STmp && "invalid symbol"); + assert(RAX <= r && r < RAX + NReg && "invalid register"); assert(!BGET(m->bt, t) && "temp has mapping"); assert(!BGET(m->br, r) && "reg already allocated"); + assert(m->n <= NReg && "too many mappings"); BSET(m->bt, t); BSET(m->br, r); m->t[m->n] = t; @@ -56,26 +57,24 @@ radd(RMap *m, int t, int r) m->n++; } -static int +static Ref ralloc(RMap *m, int t) { int r; - assert(m->n <= NReg || "oops, too few regs"); if (BGET(m->bt, t)) { r = rfind(m, t); assert(r > 0); - return r; + } else { + r = sym[t].hint; + if (r == -1 || BGET(m->br, r)) + for (r=RAX; BGET(m->br, r); r++) + ; + radd(m, t, r); + if (sym[t].hint == -1) + sym[t].hint = r; } - r = sym[t].hint; - if (r == -1 || BGET(m->br, r)) - for (r=RAX; r<NReg; r++) - if (!BGET(m->br, r)) - break; - radd(m, t, r); - if (sym[t].hint == -1) - sym[t].hint = r; - return r; + return SYM(r); } static int @@ -83,10 +82,15 @@ rfree(RMap *m, int t) { int i, r; + if (sym[t].type == SReg) { + assert(BGET(m->br, t)); + BCLR(m->br, t); + return t; + } if (!BGET(m->bt, t)) return 0; for (i=0; m->t[i] != t; i++) - assert(i+1 < NReg); + assert(i+1 < m->n); r = m->r[i]; BCLR(m->bt, t); BCLR(m->br, r); @@ -184,10 +188,64 @@ pmgen() } static Ins * -dopm(Blk *b, Ins *i) +dopm(Blk *b, Ins *i, RMap *m) { - diag("not implemented"); - return 0; + int n, r, t, nins; + Ref rt; + Ins *i1, *ib, *ip, *ir; + + npm = 0; + i1 = i+1; + if (isreg(i->to)) + for (;; i--) { + r = i->to.val; + rt = i->arg[0]; + assert(rtype(rt) == RSym); + rfree(m, r); + rt = ralloc(m, rt.val); + pmadd(rt, i->to); + if (i==b->ins + || (i-1)->op!=OCopy + || !isreg((i-1)->to)) + break; + } + else if (isreg(i->arg[0])) + for (;; i--) { + r = i->arg[0].val; + if (req(i->to, R)) { + if (BGET(m->br, r)) { + for (n=0; m->r[n] != r; n++) + assert(n+1 < m->n); + t = m->t[n]; + rfree(m, t); + BSET(m->br, r); + rt = ralloc(m, t); + pmadd(rt, i->arg[0]); + } + } else if (BGET(m->bt, i->to.val)) { + rt = SYM(rfree(m, i->to.val)); + pmadd(i->arg[0], rt); + } + BSET(m->br, r); + if (i==b->ins + || (i-1)->op!=OCopy + || !isreg((i-1)->arg[0])) + break; + } + else + assert(!"no parallel move starting here"); + pmgen(); + nins = curi-insb; + ib = alloc((b->nins + nins - (i1-i)) * sizeof(Ins)); + memcpy(ip = ib, b->ins, (i - b->ins) * sizeof(Ins)); + ip += i - b->ins; + memcpy(ir = ip, insb, nins * sizeof(Ins)); + ip += nins; + memcpy(ip, i1, (&b->ins[b->nins] - i1) * sizeof(Ins)); + b->nins += nins - (i1-i); + free(b->ins); + b->ins = ib; + return ir; } /* register allocation @@ -205,6 +263,9 @@ rega(Fn *fn) Ref src, dst; sym = fn->sym; + end = alloc(fn->ntmp * sizeof end[0]); + beg = alloc(fn->ntmp * sizeof beg[0]); + /* 1. gross hinting setup */ for (t=Tmp0; t<fn->ntmp; t++) sym[t].hint = -1; @@ -224,8 +285,6 @@ rega(Fn *fn) } /* 2. assign registers backwards */ - end = alloc(fn->ntmp * sizeof end[0]); - beg = alloc(fn->ntmp * sizeof beg[0]); if (debug['R']) fprintf(stderr, "> Register mappings:\n"); for (n=fn->nblk-1; n>=0; n--) { @@ -255,17 +314,13 @@ rega(Fn *fn) ralloc(&cur, t); /* process instructions */ end[n] = cur; - if (debug['R']) { - fprintf(stderr, "\t%-10s end", b->name); - mdump(&cur); - } if (rtype(b->jmp.arg) == RSym) - b->jmp.arg = SYM(ralloc(&cur, b->jmp.arg.val)); + b->jmp.arg = ralloc(&cur, b->jmp.arg.val); for (i=&b->ins[b->nins]; i!=b->ins;) { i--; if (i->op == OCopy /* par. moves are special */ && (isreg(i->arg[0]) || isreg(i->to))) { - i = dopm(b, i); + i = dopm(b, i, &cur); continue; } if (!req(i->to, R)) { @@ -286,7 +341,7 @@ rega(Fn *fn) t = i->arg[0].val; if (sym[t].hint == -1 && r) sym[t].hint = r; - i->arg[0] = SYM(ralloc(&cur, t)); + i->arg[0] = ralloc(&cur, t); } if (rtype(i->arg[1]) == RSym) { /* <arch> @@ -298,20 +353,22 @@ rega(Fn *fn) if (!opdesc[i->op].commut && r) BSET(cur.br, r); t = i->arg[1].val; - i->arg[1] = SYM(ralloc(&cur, t)); + i->arg[1] = ralloc(&cur, t); if (!opdesc[i->op].commut && r) BCLR(cur.br, r); } } - if (debug['R']) { - fprintf(stderr, "\t beg"); - mdump(&cur); - } b->in = cur.bt; for (p=b->phi; p; p=p->link) if (rtype(p->to) == RSym) BCLR(b->in, p->to.val); beg[n] = cur; + if (debug['R']) { + fprintf(stderr, "\t%-10s beg", b->name); + mdump(&beg[n]); + fprintf(stderr, "\t end"); + mdump(&end[n]); + } } if (debug['R']) fprintf(stderr, "\n"); |