diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-26 18:49:14 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-30 13:20:42 -0400 |
commit | 56203de6df7e8ed7f05dc3db061ef30d955cb795 (patch) | |
tree | 4c6882cba3858f04621db8704a7526a4957e3bcf | |
parent | 65c35372fd282d8176686834026f748763e613df (diff) | |
download | roux-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.
-rw-r--r-- | lisc/rega.c | 36 |
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"); |