diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-08-20 17:23:41 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-15 23:01:32 -0400 |
commit | a45aceacdb60a7bfb80e87cc68172ce76ca27ad0 (patch) | |
tree | fbac4c36a1b48afbf3d96d4e6e39385917eac6bb /lisc | |
parent | 3b708f506f5b5b45b5cc22493595a31e7183b620 (diff) | |
download | roux-a45aceacdb60a7bfb80e87cc68172ce76ca27ad0.tar.gz |
work in progress on parallel moves
The old code was broken for sure, this one might be. I have to create a test bench for the dopm function. It would also test the parallel move lowering (pmgen and folks).
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/rega.c | 101 |
1 files changed, 49 insertions, 52 deletions
diff --git a/lisc/rega.c b/lisc/rega.c index 688e54c..f8cd3d4 100644 --- a/lisc/rega.c +++ b/lisc/rega.c @@ -207,61 +207,59 @@ isreg(Ref r) static Ins * dopm(Blk *b, Ins *i, RMap *m) { + RMap m0; int n, r, r1, t, nins; - Ref rt; Ins *i1, *ib, *ip, *ir; - npm = 0; + m0 = *m; i1 = i+1; - if (isreg(i->to)) - for (;; i--) { - r = RBASE(i->to.val); - rt = i->arg[0]; - assert(rtype(rt) == RTmp && rt.val >= Tmp0); - 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 = RBASE(i->arg[0].val); - r1 = req(i->to, R) ? -1 : rfind(m, i->to.val); - if (BGET(m->b, r) && r1 != r) { - for (n=0; m->r[n] != r; n++) - assert(n+1 < m->n); - t = m->t[n]; - rfree(m, t); - if (m->n == NReg-1) { - rfree(m, i->to.val); - radd(m, i->to.val, r); - radd(m, t, r1); - rt = reg(r1, i->to.val); - pmadd(i->arg[0], rt); - pmadd(rt, i->arg[0]); - } else { - BSET(m->b, r); - rt = ralloc(m, t); - BCLR(m->b, r); - pmadd(rt, i->arg[0]); - } + for (;; i--) { + r = RBASE(i->arg[0].val); + r1 = req(i->to, R) ? -1 : rfind(m, i->to.val); + if (!BGET(m->b, r)) { + /* r is not used by anybody, + * i->to could have no register */ + if (r1 != -1) + rfree(m, i->to.val); + radd(m, i->to.val, r); + } else if (r1 != r) { + /* r is used and not by i->to, + * i->to could have no register */ + for (n=0; m->r[n] != r; n++) + assert(n+1 < m->n); + t = m->t[n]; + rfree(m, t); + if (m->n == NReg-1) { + /* swap the two locations */ + assert(r1 != -1); + rfree(m, i->to.val); + radd(m, i->to.val, r); + radd(m, t, r1); + } else { + BSET(m->b, r); + ralloc(m, t); + BCLR(m->b, r); } - /* invariant: r is unmapped or contains to i->to */ - if (!req(i->to, R) && BGET(m->b, i->to.val)) { - rt = reg(rfree(m, i->to.val), i->to.val); - pmadd(i->arg[0], rt); - } - radd(m, r, r); - if (i == b->ins - || (i-1)->op != OCopy - || !isreg((i-1)->arg[0])) - break; - } - else - assert(!"no parallel move starting here"); + } /* else r is already allocated for i->to */ + if (i == b->ins + || (i-1)->op != OCopy + || !isreg((i-1)->arg[0])) + break; + } + assert(m0.n <= m->n); + for (npm=0, n=0; n<m->n; n++) { + t = m->t[n]; + r1 = m->r[n]; + r = rfind(&m0, t); + if (r != r1) + pmadd(reg(r1, t), reg(r, t)); + } + for (ip=i; ip<i1; ip++) { + if (!req(ip->to, R)) + rfree(m, ip->to.val); + r = RBASE(ip->arg[0].val); + radd(m, r, r); + } pmgen(); nins = curi-insb; ib = alloc((b->nins + nins - (i1-i)) * sizeof(Ins)); @@ -327,8 +325,7 @@ rega(Fn *fn) 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))) { + if (i->op == OCopy && isreg(i->arg[0])) { i = dopm(b, i, &cur); continue; } |