diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2019-05-02 20:57:26 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2019-05-02 20:57:26 +0200 |
commit | 34fee80e690986175ba9417802fad69fb5b821db (patch) | |
tree | 6b5a8676b7bef7c080588fadff1c282ed969d14a /copy.c | |
parent | 2e7d6b24eaa1314eb4fe663ef5dc529e461fb8ce (diff) | |
download | roux-34fee80e690986175ba9417802fad69fb5b821db.tar.gz |
detect ubiquitous simple copies
When lowering pointer arithmetic, it is natural for a C frontend to generate those instructions.
Diffstat (limited to 'copy.c')
-rw-r--r-- | copy.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/copy.c b/copy.c index b92c5f4..8354929 100644 --- 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; |