Index: vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (revision 592179) +++ vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (working copy) @@ -23,7 +23,6 @@ namespace Jitrino { namespace Ia32 { - class PeepHoleOpt; static const char* help = "Performs simple local (per-BB) or per-Inst optimizations.\n" @@ -92,6 +91,7 @@ Changed handleInst_SSEMov(Inst* inst); Changed handleInst_SSEXor(Inst* inst); Changed handleInst_CMP(Inst* inst); + // // Helpers // @@ -189,7 +189,9 @@ case Mnemonic_CALL: return handleInst_Call(inst); case Mnemonic_ADD: + case Mnemonic_ADC: case Mnemonic_SUB: + case Mnemonic_SBB: case Mnemonic_NOT: case Mnemonic_AND: case Mnemonic_OR: @@ -499,69 +501,41 @@ // Only these mnemonics have the majestic name of ALUs. assert(mnemonic == Mnemonic_ADD || mnemonic == Mnemonic_SUB || + mnemonic == Mnemonic_ADC || mnemonic == Mnemonic_SBB || mnemonic == Mnemonic_OR || mnemonic == Mnemonic_XOR || - mnemonic == Mnemonic_AND || + mnemonic == Mnemonic_AND || mnemonic == Mnemonic_CMP || mnemonic == Mnemonic_TEST); - - if (mnemonic == Mnemonic_AND && inst->getForm() == Inst::Form_Extended) { - Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); - Opnd* dst = inst->getOpnd(defs.begin()); + if (mnemonic != Mnemonic_TEST) + { Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); - Opnd* src1= inst->getOpnd(uses.begin()); - Opnd* src2= inst->getOpnd(uses.next(uses.begin())); - if (!isImm(src2) && isImm(src1)) { - Opnd* tmp = src1; src1 = src2; src2 = tmp; + Opnd* left = inst->getOpnd(uses.begin()); + Opnd* right= inst->getOpnd(uses.next(uses.begin())); + Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); + Opnd* res = inst->getOpnd(defs.begin()); + + if (isImm32(right) && fitsImm8(right)) { + // what: OPERATION opnd1, imm32 => OPERATION opnd1, imm8 + //why: shorter instruction + //nb: applicable for all ALUs, but TEST + + right = convertImmToImm8(right); + Inst* newi; + if (inst->getForm() == Inst::Form_Extended) + { + if (mnemonic == Mnemonic_CMP) + newi = irManager->newInstEx(mnemonic, 0, left, right); + else + newi = irManager->newInstEx(mnemonic, 1, res, left, right); + } + else + newi = irManager->newInst(mnemonic, left, right); + + newi->insertAfter(inst); + inst->unlink(); + return Changed_Inst; } - if (isImm32(src2)) { - Inst* nextInst = inst->getNextInst(); - bool dstIsNotUsed = dst->getRefCount() == 1; - bool removeNextInst = false; - if (dst->getRefCount()==2 && nextInst!=NULL && nextInst->getMnemonic() == Mnemonic_CMP) { - Inst::Opnds cmp_uses(nextInst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); - Opnd* cmp_src1= nextInst->getOpnd(cmp_uses.begin()); - Opnd* cmp_src2= nextInst->getOpnd(cmp_uses.next(cmp_uses.begin())); - if (cmp_src1 == dst && isImm(cmp_src2) && cmp_src2->getImmValue() == 0) { - removeNextInst = true; - dstIsNotUsed = true; - } - } - if (dstIsNotUsed) { - if (Log::isEnabled()) Log::out()<<"I"<getId()<<" replacing AND with TEST"<newInst(Mnemonic_TEST, src1, src2)->insertBefore(inst); - if (removeNextInst) { - nextInst->unlink(); - } - inst->unlink(); - return Changed_Inst; - } - } } - - - // Only process simple variants: ALU opcodes that either define flags - //and use 2 operands, or simply use 2 operands - unsigned leftIndex = 0; - if (isReg(inst->getOpnd(leftIndex), RegName_EFLAGS)) { - ++leftIndex; - } - - const unsigned rightIndex = leftIndex + 1; - - Opnd* left = inst->getOpnd(leftIndex); - Opnd* right = inst->getOpnd(rightIndex); - - if (mnemonic != Mnemonic_TEST && - isReg(left) && isImm32(right) && fitsImm8(right)) { - /* what: OPERATION reg, imm32 => OPERATION reg, imm8 - why: shorter instruction - nb: applicable for all ALUs, but TEST - */ - right = convertImmToImm8(right); - replaceOpnd(inst, rightIndex, right); - return Changed_Opnd; - } - return Changed_Nothing; } @@ -677,3 +651,4 @@ } }}; // ~namespace Jitrino::Ia32 +