summaryrefslogtreecommitdiff
path: root/lisc
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-26 18:49:14 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-30 13:20:42 -0400
commit56203de6df7e8ed7f05dc3db061ef30d955cb795 (patch)
tree4c6882cba3858f04621db8704a7526a4957e3bcf /lisc
parent65c35372fd282d8176686834026f748763e613df (diff)
downloadroux-56203de6df7e8ed7f05dc3db061ef30d955cb795.tar.gz
wip on regalloc new heuristics
I thought that many parallel copies generated can be avoided if temporaries are in their hint register at the beginning of blocks with multiple predecessors. To get more benefit, I suspect that we could use a copy-propagating peephole pass.
Diffstat (limited to 'lisc')
-rw-r--r--lisc/rega.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/lisc/rega.c b/lisc/rega.c
index 5173ecc..d368977 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -360,9 +360,9 @@ doblk(Blk *b, RMap *cur)
void
rega(Fn *fn)
{
- int n, t, r, x;
+ int j, n, t, r, r1, x;
Blk *b, *b1, *s, ***ps, *blist;
- RMap *end, *beg, cur;
+ RMap *end, *beg, cur, old;
Ins *i;
Phi *p;
uint u;
@@ -401,14 +401,36 @@ rega(Fn *fn)
}
end[n] = cur;
doblk(b, &cur);
- beg[n] = cur;
b->in = cur.b;
for (p=b->phi; p; p=p->link)
- if (rtype(p->to) == RTmp) {
- t = p->to.val;
- BCLR(b->in, t);
- /* rfree(&cur, t); */
+ if (rtype(p->to) == RTmp)
+ BCLR(b->in, p->to.val);
+ if (b->npred > 1) {
+ /* attempt to satisfy hints
+ * when it's simple and we have
+ * multiple predecessors
+ */
+ old = cur;
+ curi = insb;
+ for (j=0; j<old.n; j++) {
+ t = old.t[j];
+ r = *hint(t);
+ r1 = rfind(&cur, t);
+ if (r != -1 && r != r1)
+ if (!BGET(cur.b, r)) {
+ rfree(&cur, t);
+ radd(&cur, t, r);
+ *curi++ = (Ins){OCopy, tmp[t].wide, TMP(r1), {TMP(r)}};
+ }
+ }
+ if ((j = curi - insb)) {
+ b->nins += j;
+ i = alloc(b->nins * sizeof(Ins));
+ icpy(icpy(i, insb, j), b->ins, b->nins-j);
+ b->ins = i;
}
+ }
+ beg[n] = cur;
}
if (debug['R']) {
fprintf(stderr, "\n> Register mappings:\n");