| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #include "all.h"
- enum {
- MaxIns = 2,
- MaxPhis = 2,
- };
- static int
- okbranch(Blk *b)
- {
- Ins *i;
- int n;
- n = 0;
- for (i=b->ins; i<&b->ins[b->nins]; i++)
- if (i->op != Odbgloc) {
- if (pinned(i))
- return 0;
- if (i->op != Onop)
- n++;
- }
- return n <= MaxIns;
- }
- static int
- okjoin(Blk *b)
- {
- Phi *p;
- int n;
- n = 0;
- for (p=b->phi; p; p=p->link) {
- if (KBASE(p->cls) != 0)
- return 0;
- n++;
- }
- return n <= MaxPhis;
- }
- static int
- okgraph(Blk *ifb, Blk *thenb, Blk *elseb, Blk *joinb)
- {
- if (joinb->npred != 2 || !okjoin(joinb))
- return 0;
- assert(thenb != elseb);
- if (thenb != ifb && !okbranch(thenb))
- return 0;
- if (elseb != ifb && !okbranch(elseb))
- return 0;
- return 1;
- }
- static void
- convert(Blk *ifb, Blk *thenb, Blk *elseb, Blk *joinb)
- {
- Ins *ins, sel;
- Phi *p;
- uint nins;
- ins = vnew(0, sizeof ins[0], PHeap);
- nins = 0;
- addbins(&ins, &nins, ifb);
- if (thenb != ifb)
- addbins(&ins, &nins, thenb);
- if (elseb != ifb)
- addbins(&ins, &nins, elseb);
- assert(joinb->npred == 2);
- if (joinb->phi) {
- sel = (Ins){
- .op = Osel0, .cls = Kw,
- .arg = {ifb->jmp.arg},
- };
- addins(&ins, &nins, &sel);
- }
- sel = (Ins){.op = Osel1};
- for (p=joinb->phi; p; p=p->link) {
- sel.to = p->to;
- sel.cls = p->cls;
- sel.arg[0] = phiarg(p, thenb);
- sel.arg[1] = phiarg(p, elseb);
- addins(&ins, &nins, &sel);
- }
- idup(ifb, ins, nins);
- ifb->jmp.type = Jjmp;
- ifb->jmp.arg = R;
- ifb->s1 = joinb;
- ifb->s2 = 0;
- joinb->npred = 1;
- joinb->pred[0] = ifb;
- joinb->phi = 0;
- vfree(ins);
- }
- /* eliminate if-then[-else] graphlets
- * using sel instructions
- * needs rpo pred use; breaks cfg use
- */
- void
- ifconvert(Fn *fn)
- {
- Blk *ifb, *thenb, *elseb, *joinb;
- if (debug['K'])
- fputs("\n> If-conversion:\n", stderr);
- for (ifb=fn->start; ifb; ifb=ifb->link)
- if (ifgraph(ifb, &thenb, &elseb, &joinb))
- if (okgraph(ifb, thenb, elseb, joinb)) {
- if (debug['K'])
- fprintf(stderr,
- " @%s -> @%s, @%s -> @%s\n",
- ifb->name, thenb->name, elseb->name,
- joinb->name);
- convert(ifb, thenb, elseb, joinb);
- }
- if (debug['K']) {
- fprintf(stderr, "\n> After if-conversion:\n");
- printfn(fn, stderr);
- }
- }
|