You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/02/02 12:34:44 UTC
svn commit: r502582 -
/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp
Author: varlax
Date: Fri Feb 2 03:34:37 2007
New Revision: 502582
URL: http://svn.apache.org/viewvc?view=rev&rev=502582
Log:
Applied HARMONY-2984 [drlvm][jit] More peephole optimizations implemented: IMUL and AND+CMP->TEST
Tested on SUSE10@x86, SUSE9@x86_64
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp?view=diff&rev=502582&r1=502581&r2=502582
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp Fri Feb 2 03:34:37 2007
@@ -88,6 +88,7 @@
Changed handleInst_HelperCall(Inst* inst, const Opnd::RuntimeInfo* ri);
Changed handleInst_Convert_F2I_D2I(Inst* inst);
Changed handleInst_ALU(Inst* inst);
+ Changed handleInst_MUL(Inst* inst);
Changed handleInst_SSEMov(Inst* inst);
Changed handleInst_SSEXor(Inst* inst);
//
@@ -100,6 +101,7 @@
void PeepHoleOpt::runImpl(void)
{
setIRManager(irManager);
+ irManager->calculateOpndStatistics();
m_bHadAnyChange = false;
// organize an infinity loop and keep spinning till we have any change.
// thought have a safety counter to prevent a really infinity in case
@@ -192,6 +194,9 @@
case Mnemonic_CMP:
case Mnemonic_TEST:
return handleInst_ALU(inst);
+ case Mnemonic_IMUL:
+ case Mnemonic_MUL:
+ return handleInst_MUL(inst);
case Mnemonic_MOVSS:
case Mnemonic_MOVSD:
return handleInst_SSEMov(inst);
@@ -376,6 +381,79 @@
return Changed_Node;
}
+static int getMinBit(uint32 val) {
+ uint32 currentVal = val;
+ int i=0;
+ do {
+ if ((currentVal & 1)) {
+ return i;
+ }
+ currentVal = currentVal >> 1;
+ } while (++i<32);
+ return i;
+}
+
+static int getMaxBit(uint32 val) {
+ uint32 currentVal = val;
+ int i=31;
+ do {
+ if ((currentVal & (1<<31))) {
+ return i;
+ }
+ currentVal = currentVal << 1;
+ } while (--i>=0);
+ return i;
+}
+
+PeepHoleOpt::Changed PeepHoleOpt::handleInst_MUL(Inst* inst) {
+ assert(inst->getMnemonic()==Mnemonic_IMUL || inst->getMnemonic()==Mnemonic_MUL);
+ if (inst->getForm() == Inst::Form_Native) {
+ return Changed_Nothing;
+ }
+ Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ Opnd* dst = inst->getOpnd(defs.begin());
+ if (defs.next(defs.begin())!=defs.end()) {
+ return Changed_Nothing;
+ }
+ Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Opnd* src1= inst->getOpnd(uses.begin());
+ Opnd* src2= inst->getOpnd(uses.next(uses.begin()));
+ assert(src1!=NULL && src2!=NULL && dst!=NULL);
+ if (isImm(src1)) {
+ Opnd* tmp = src1; src1 = src2; src2 = tmp;
+ }
+ if (isImm(src2) && irManager->getTypeSize(src2->getType()) <=32) {
+ int immVal = (int)src2->getImmValue();
+ if (immVal == 0) {
+ if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 0"<<std::endl;
+ irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src2)->insertAfter(inst);
+ inst->unlink();
+ return Changed_Inst;
+ } else if (immVal == 1) {
+ if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 1"<<std::endl;
+ irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src1)->insertAfter(inst);
+ inst->unlink();
+ return Changed_Inst;
+ } else if (immVal == 2) {
+ if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 2"<<std::endl;
+ irManager->newInstEx(Mnemonic_ADD, 1, dst, src1, src1)->insertAfter(inst);
+ inst->unlink();
+ return Changed_Inst;
+ } else {
+ int minBit=getMinBit(immVal);
+ int maxBit=getMaxBit(immVal);
+ if (minBit == maxBit) {
+ assert(minBit>=2);
+ if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 2^"<<minBit<<std::endl;
+ Type* int32Type = irManager->getTypeManager().getUInt32Type();
+ irManager->newInstEx(Mnemonic_SHL, 1, dst, src1, irManager->newImmOpnd(int32Type, minBit))->insertAfter(inst);
+ inst->unlink();
+ return Changed_Inst;
+ }
+ }
+ }
+ return Changed_Nothing;
+}
PeepHoleOpt::Changed PeepHoleOpt::handleInst_ALU(Inst* inst)
{
@@ -393,6 +471,42 @@
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());
+ 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;
+ }
+ 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"<<inst->getId()<<" replacing AND with TEST"<<std::endl;
+ irManager->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;