6c, 8c: optimize away CMPL/CMPQ reg, $0 instruction in peephole pass

when the previous instruction sets the zero flag,
we can remove the CMPL/CMPQ instruction.
this removes compares for zero/non zero tests only.
it only looks at the previous non-nop instruction
to see if it sets our compare value register.
This commit is contained in:
cinap_lenrek 2014-03-29 19:44:04 +01:00
parent 91bed257fa
commit cde97a4d5f
2 changed files with 77 additions and 0 deletions

View file

@ -196,6 +196,53 @@ loop1:
p->from = zprog.from;
}
break;
case ACMPL:
case ACMPQ:
if(p->to.type != D_CONST || p->to.offset != 0 || regtyp(&p->from) == 0)
break;
if(p->link == P || (p->link->as != AJEQ && p->link->as != AJNE))
break;
r1 = uniqp(r);
while(r1 != R && r1->prog->as == ANOP)
r1 = uniqp(r1);
if(r1 == R || r1->prog->to.type != p->from.type)
break;
p1 = r1->prog;
switch(p1->as){
case AANDQ:
case AORQ:
case AXORQ:
case ANEGQ:
case AADDQ:
case AADCQ:
case ASUBQ:
case ASBBQ:
case ASHLQ:
case ASHRQ:
case ASALQ:
case ASARQ:
case AINCQ:
case ADECQ:
if(p->as != ACMPQ)
break;
case AANDL:
case AORL:
case AXORL:
case ANEGL:
case AADDL:
case AADCL:
case ASUBL:
case ASBBL:
case ASHLL:
case ASHRL:
case ASALL:
case ASARL:
case AINCL:
case ADECL:
excise(r);
}
break;
}
}
if(t)

View file

@ -137,6 +137,36 @@ loop1:
p->from = zprog.from;
}
break;
case ACMPL:
if(p->to.type != D_CONST || p->to.offset != 0 || regtyp(&p->from) == 0)
break;
if(p->link == P || (p->link->as != AJEQ && p->link->as != AJNE))
break;
r1 = uniqp(r);
while(r1 != R && r1->prog->as == ANOP)
r1 = uniqp(r1);
if(r1 == R || r1->prog->to.type != p->from.type)
break;
p1 = r1->prog;
switch(p1->as){
case AANDL:
case AORL:
case AXORL:
case ANEGL:
case AADDL:
case AADCL:
case ASUBL:
case ASBBL:
case ASHLL:
case ASHRL:
case ASALL:
case ASARL:
case AINCL:
case ADECL:
excise(r);
}
break;
}
}
if(t)