nixify
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user