commit e65a615c903c96eaaad17a05e83d1d763cc21675
parent ad012e9d558138b61881156ab8b31e74cd759825
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Fri, 7 Aug 2015 16:01:07 -0400
jez becomes jnz, complete cmp+jmp contraction
Diffstat:
12 files changed, 77 insertions(+), 75 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -73,6 +73,20 @@ static char *ctoa[NCmp] = {
[Cne] = "ne",
};
+static int
+cneg(int cmp)
+{
+ switch (cmp) {
+ default: diag("cneg: unhandled comparison");
+ case Ceq: return Cne;
+ case Csle: return Csgt;
+ case Cslt: return Csge;
+ case Csgt: return Csle;
+ case Csge: return Cslt;
+ case Cne: return Ceq;
+ }
+}
+
static void
eref(Ref r, Fn *fn, FILE *f)
{
@@ -187,9 +201,9 @@ eins(Ins i, Fn *fn, FILE *f)
void
emitfn(Fn *fn, FILE *f)
{
- char *js;
Blk *b, *s;
Ins *i;
+ int c;
fprintf(f,
".text\n"
@@ -216,19 +230,19 @@ emitfn(Fn *fn, FILE *f)
if (b->s1 != b->link)
fprintf(f, "\tjmp .L%s\n", b->s1->name);
break;
- case JJez:
- if (b->s1 == b->link) {
- js = "jne";
- s = b->s2;
- } else if (b->s2 == b->link) {
- js = "je";
- s = b->s1;
- } else
- diag("emit: unhandled jump (1)");
- eop("cmp $0,", b->jmp.arg, R, fn, f);
- fprintf(f, "\t%s .L%s\n", js, s->name);
- break;
default:
+ c = b->jmp.type - JXJc;
+ if (0 <= c && c <= NCmp) {
+ if (b->link == b->s2) {
+ s = b->s1;
+ } else if (b->link == b->s1) {
+ c = cneg(c);
+ s = b->s2;
+ } else
+ diag("emit: unhandled jump (1)");
+ fprintf(f, "\tj%s .L%s\n", ctoa[c], s->name);
+ break;
+ }
diag("emit: unhandled jump (2)");
}
}
diff --git a/lisc/isel.c b/lisc/isel.c
@@ -40,20 +40,6 @@ newtmp(int type, Fn *fn)
}
static int
-cneg(int cmp)
-{
- switch (cmp) {
- default: diag("cneg: unhandled comparison");
- case Ceq: return Cne;
- case Csle: return Csgt;
- case Cslt: return Csge;
- case Csgt: return Csle;
- case Csge: return Cslt;
- case Cne: return Ceq;
- }
-}
-
-static int
islong(Ref r, Fn *fn)
{
return rtype(r) == RTmp && fn->tmp[r.val].type == TLong;
@@ -131,6 +117,8 @@ sel(Ins i, Fn *fn)
case OCopy:
emit(i.op, i.to, i.arg[0], i.arg[1]);
break;
+ case ONop:
+ break;
default:
if (OCmp <= i.op && i.op <= OCmp1) {
c = i.op - OCmp;
@@ -150,6 +138,9 @@ flagi(Ins *i0, Ins *i)
while (i>i0)
switch ((--i)->op) {
default:
+ return 0;
+ case OAdd: /* <arch> */
+ case OSub:
return i;
case OCopy:
case OStore:
@@ -158,51 +149,48 @@ flagi(Ins *i0, Ins *i)
return 0;
}
-static Ins *
+static void
seljmp(Blk *b, Fn *fn)
{
Ref r;
int c;
Ins *fi;
- fi = &b->ins[b->nins];
- if (b->jmp.type != JJez)
- return fi;
+ if (b->jmp.type != JJnz)
+ return;
r = b->jmp.arg;
b->jmp.arg = R;
assert(!req(r, R));
if (rtype(r) == RCon) {
b->jmp.type = JJmp;
- if (!req(r, CON_Z))
+ if (req(r, CON_Z))
b->s1 = b->s2;
b->s2 = 0;
- return fi;
+ return;
}
- fi = flagi(b->ins, fi);
+ fi = flagi(b->ins, &b->ins[b->nins]);
if (fi && req(fi->to, r)) {
- assert(1 == fn->tmp[r.val].nuse);
- if (fn->tmp[r.val].nuse == 1
- && OCmp <= fi->op && fi->op <= OCmp1) {
+ if (OCmp <= fi->op && fi->op <= OCmp1) {
c = fi->op - OCmp;
if (rtype(fi->arg[0]) == RCon)
c = COP(c);
- b->jmp.type = JXJc + cneg(c);
- selcmp(fi->arg, fn);
- return fi;
- }
- /* what if it is a comparison
- * that is used more than once?
- * !!!
- */
- b->jmp.type = JXJc + Ceq;
- return fi+1;
+ b->jmp.type = JXJc + c;
+ if (fn->tmp[r.val].nuse == 1) {
+ assert(fn->tmp[r.val].ndef==1);
+ selcmp(fi->arg, fn);
+ *fi = (Ins){ONop, R, {R, R}};
+ /* !!! use counts are invalid after that !!! */
+ return;
+ }
+ } else
+ b->jmp.type = JXJc + Cne;
+ } else {
+ if (islong(r, fn))
+ emit(OXCmpl, R, CON_Z, r);
+ else
+ emit(OXCmpw, R, CON_Z, r);
+ b->jmp.type = JXJc + Cne;
}
- if (islong(r, fn))
- emit(OXCmpl, R, CON_Z, r);
- else
- emit(OXCmpw, R, CON_Z, r);
- b->jmp.type = JXJc + Ceq;
- return &b->ins[b->nins];
}
/* instruction selection
@@ -217,8 +205,8 @@ isel(Fn *fn)
for (b=fn->start; b; b=b->link) {
curi = &insb[NIns];
- i = seljmp(b, fn);
- while (i>b->ins) {
+ seljmp(b, fn);
+ for (i=&b->ins[b->nins]; i>b->ins;) {
sel(*--i, fn);
}
nins = &insb[NIns] - curi;
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -146,7 +146,7 @@ enum {
JXXX,
JRet,
JJmp,
- JJez,
+ JJnz,
JXJc,
JXJc1 = JXJc + NCmp-1,
JLast
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -53,7 +53,7 @@ typedef enum {
TCsle,
TPhi,
TJmp,
- TJez,
+ TJnz,
TRet,
TW,
TL,
@@ -138,7 +138,7 @@ lex()
{ "csle", TCsle },
{ "phi", TPhi },
{ "jmp", TJmp },
- { "jez", TJez },
+ { "jnz", TJnz },
{ "ret", TRet },
{ "w", TW },
{ "l", TL },
@@ -396,11 +396,11 @@ parseline(PState ps)
case TJmp:
curb->jmp.type = JJmp;
goto Jump;
- case TJez:
- curb->jmp.type = JJez;
+ case TJnz:
+ curb->jmp.type = JJnz;
r = parseref();
if (req(r, R))
- err("invalid argument for jez jump");
+ err("invalid argument for jnz jump");
curb->jmp.arg = r;
expect(TComma);
Jump:
@@ -582,7 +582,7 @@ void
printfn(Fn *fn, FILE *f)
{
static char *jtoa[JLast] = {
- [JJez] = "jez",
+ [JJnz] = "jnz",
[JXJc+Ceq] = "xjeq",
[JXJc+Csle] = "xjsle",
[JXJc+Cslt] = "xjslt",
@@ -642,7 +642,7 @@ printfn(Fn *fn, FILE *f)
break;
default:
fprintf(f, "\t%s ", jtoa[b->jmp.type]);
- if (b->jmp.type == JJez) {
+ if (b->jmp.type == JJnz) {
printref(b->jmp.arg, fn, f);
fprintf(f, ", ");
}
diff --git a/lisc/test/alt.ssa b/lisc/test/alt.ssa
@@ -9,15 +9,15 @@
%alt =w phi @start 0, @left %alt1, @right %alt1
%cnt =w phi @start 100, @left %cnt, @right %cnt1
%alt1 =w sub 1, %alt
- jez %alt1, @left, @right
+ jnz %alt1, @right, @left
@left
%x =w phi @loop 10, @left %x1
%x1 =w sub %x, 1
%z =w copy %x
- jez %z, @loop, @left
+ jnz %z, @left, @loop
@right
%cnt1 =w sub %cnt, %ten
- jez %cnt1, @end, @loop
+ jnz %cnt1, @loop, @end
@end
%ret =w add %cnt, %dum
ret
diff --git a/lisc/test/cup.ssa b/lisc/test/cup.ssa
@@ -5,6 +5,6 @@
%n0 =l phi @start -1988, @loop %n1
%n1 =l add 1, %n0
%cmp =w csle 1991, %n1
- jez %cmp, @loop, @end
+ jnz %cmp, @end, @loop
@end
ret
diff --git a/lisc/test/eucl.ssa b/lisc/test/eucl.ssa
@@ -9,7 +9,7 @@
%a =w phi @start 380, @loop %r
%b =w phi @start 747, @loop %a
%r =w rem %b, %a
- jez %r, @end, @loop
+ jnz %r, @loop, @end
@end
ret
diff --git a/lisc/test/fix1.ssa b/lisc/test/fix1.ssa
@@ -1,7 +1,7 @@
@start
%x =w copy 1
@loop
- jez %x, @isz, @noz
+ jnz %x, @noz, @isz
@noz
%x =w copy 0
jmp @end
diff --git a/lisc/test/fix2.ssa b/lisc/test/fix2.ssa
@@ -1,10 +1,10 @@
@start
%x =w copy 1
@loop
- jez %x, @isz, @noz
+ jnz %x, @noz, @isz
@noz
%x =w copy 0
- jez %x, @end, @loop
+ jnz %x, @loop, @end
@isz
%x =w copy 1
jmp @loop
diff --git a/lisc/test/live.ssa b/lisc/test/live.ssa
@@ -8,7 +8,7 @@
@start
%b =w copy 0
%x =w copy 10
- jez 0, @left, @loop
+ jnz 0, @loop, @left
@left
jmp @inloop
@loop
diff --git a/lisc/test/loop.ssa b/lisc/test/loop.ssa
@@ -8,7 +8,7 @@
%n =w phi @start 0, @loop %n1
%n1 =w sub %n, 1
%s1 =w add %s, %n
- jez %n1, @end, @loop
+ jnz %n1, @loop, @end
@end
ret
diff --git a/lisc/test/rpo.ssa b/lisc/test/rpo.ssa
@@ -1,10 +1,10 @@
@start
jmp @foo
@baz
- jez 1, @end, @foo
+ jnz 1, @end, @foo
@bar
jmp @end
@foo
- jez 0, @bar, @baz
+ jnz 0, @bar, @baz
@end
ret