diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-21 11:29:22 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-21 11:53:00 +0100 |
commit | 0db06dad63e02b619671bfb3dd25fc92c0856319 (patch) | |
tree | 0a37b3bf581b4918516686a31f0ae2d002d140f2 /copy.c | |
parent | 674901b71834739cccf3f8665833dc125d1172b7 (diff) | |
download | roux-0db06dad63e02b619671bfb3dd25fc92c0856319.tar.gz |
recognize some phis as copies
The copy elimination pass is not complete. This patch improves things a bit, but I think we still have quite a bit of incompleteness. We now consistently mark phis with all arguments identical as copies. Previously, they were inconsistently eliminated by phisimpl(). An example where they were not eliminated is the following: @blk2 %a = phi @blk0 %x, @blk1 %x jnz ?, @blk3, @blk4 @blk3 %b = copy %x @blk4 %c = phi @blk2 %a, @blk3 %b In this example, neither %c nor %a were marked as copies of %x because, when phisimpl() is called, the copy information for %b is not available. The incompleteness is still present and can be observed by modifying the example above so that %a takes a copy of %x through a back-edge. Then, phisimpl()'s lack of copy information about %b will prevent optimization.
Diffstat (limited to 'copy.c')
-rw-r--r-- | copy.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/copy.c b/copy.c index 868d2ba..1f9e1f3 100644 --- a/copy.c +++ b/copy.c @@ -134,8 +134,8 @@ copy(Fn *fn) Phi *p, **pp; Ins *i; Blk *b; - uint n, a; - Ref *cpy, r; + uint n, a, eq; + Ref *cpy, r, r1; int t; bsinit(ts, fn->ntmp); @@ -150,13 +150,22 @@ copy(Fn *fn) assert(rtype(p->to) == RTmp); if (!req(cpy[p->to.val], R)) continue; + eq = 0; r = R; for (a=0; a<p->narg; a++) - if (p->blk[a]->id < n) - r = copyof(p->arg[a], cpy); + if (p->blk[a]->id < n) { + r1 = copyof(p->arg[a], cpy); + if (req(r, R) || req(r1, r)) + eq++; + r = r1; + } assert(!req(r, R)); - cpy[p->to.val] = p->to; - phisimpl(p, r, cpy, &stk, ts, as, fn); + if (eq == p->narg) + cpy[p->to.val] = r; + else { + cpy[p->to.val] = p->to; + phisimpl(p, r, cpy, &stk, ts, as, fn); + } } for (i=b->ins; i<&b->ins[b->nins]; i++) { assert(rtype(i->to) <= RTmp); |