commit 34fee80e690986175ba9417802fad69fb5b821db
parent 2e7d6b24eaa1314eb4fe663ef5dc529e461fb8ce
Author: Quentin Carbonneaux <quentin@c9x.me>
Date: Thu, 2 May 2019 20:57:26 +0200
detect ubiquitous simple copies
When lowering pointer arithmetic, it is
natural for a C frontend to generate
those instructions.
Diffstat:
M | copy.c | | | 36 | +++++++++++++++++++++++++++--------- |
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/copy.c b/copy.c
@@ -1,7 +1,15 @@
#include "all.h"
static int
-iscopy(Ins *i, Ref r, Tmp *tmp)
+iscon(Ref r, int64_t bits, Fn *fn)
+{
+ return rtype(r) == RCon
+ && fn->con[r.val].type == CBits
+ && fn->con[r.val].bits.i == bits;
+}
+
+static int
+iscopy(Ins *i, Ref r, Fn *fn)
{
static bits extcpy[] = {
[WFull] = 0,
@@ -15,15 +23,25 @@ iscopy(Ins *i, Ref r, Tmp *tmp)
bits b;
Tmp *t;
- if (i->op == Ocopy)
+ switch (i->op) {
+ case Ocopy:
return 1;
+ case Omul:
+ return iscon(i->arg[0], 1, fn) || iscon(i->arg[1], 1, fn);
+ case Odiv:
+ return iscon(i->arg[1], 1, fn);
+ case Oadd:
+ return iscon(i->arg[0], 0, fn) || iscon(i->arg[1], 0, fn);
+ default:
+ break;
+ }
if (!isext(i->op) || rtype(r) != RTmp)
return 0;
if (i->op == Oextsw || i->op == Oextuw)
if (i->cls == Kw)
return 1;
- t = &tmp[r.val];
+ t = &fn->tmp[r.val];
assert(KBASE(t->cls) == 0);
if (i->cls == Kl && t->cls == Kw)
return 0;
@@ -44,7 +62,7 @@ copyof(Ref r, Ref *cpy)
* and Efficient SSA Construction" by Braun M. et al.
*/
static void
-phisimpl(Phi *p, Ref r, Ref *cpy, Use ***pstk, BSet *ts, BSet *as, Tmp *tmp)
+phisimpl(Phi *p, Ref r, Ref *cpy, Use ***pstk, BSet *ts, BSet *as, Fn *fn)
{
Use **stk, *u, *u1;
uint nstk, a;
@@ -58,7 +76,7 @@ phisimpl(Phi *p, Ref r, Ref *cpy, Use ***pstk, BSet *ts, BSet *as, Tmp *tmp)
stk[0] = &(Use){.type = UPhi, .u.phi = p};
while (nstk) {
u = stk[--nstk];
- if (u->type == UIns && iscopy(u->u.ins, r, tmp)) {
+ if (u->type == UIns && iscopy(u->u.ins, r, fn)) {
p = &(Phi){.narg = 0};
t = u->u.ins->to.val;
}
@@ -79,8 +97,8 @@ phisimpl(Phi *p, Ref r, Ref *cpy, Use ***pstk, BSet *ts, BSet *as, Tmp *tmp)
return;
bsset(as, r1.val);
}
- u = tmp[t].use;
- u1 = &u[tmp[t].nuse];
+ u = fn->tmp[t].use;
+ u1 = &u[fn->tmp[t].nuse];
vgrow(pstk, nstk+(u1-u));
stk = *pstk;
for (; u<u1; u++)
@@ -130,14 +148,14 @@ copy(Fn *fn)
r = copyof(p->arg[a], cpy);
assert(!req(r, R));
cpy[p->to.val] = p->to;
- phisimpl(p, r, cpy, &stk, ts, as, fn->tmp);
+ phisimpl(p, r, cpy, &stk, ts, as, fn);
}
for (i=b->ins; i<&b->ins[b->nins]; i++) {
assert(rtype(i->to) <= RTmp);
if (!req(cpy[i->to.val], R))
continue;
r = copyof(i->arg[0], cpy);
- if (iscopy(i, r, fn->tmp))
+ if (iscopy(i, r, fn))
cpy[i->to.val] = r;
else
cpy[i->to.val] = i->to;