You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/12/01 13:10:52 UTC
svn commit: r600101 - in /harmony/enhanced/drlvm/trunk/vm:
jitrino/src/codegenerator/ jitrino/src/codegenerator/ia32/
jitrino/src/optimizer/ jitrino/src/translator/java/
port/src/encoder/ia32_em64t/
Author: mfursov
Date: Sat Dec 1 04:10:50 2007
New Revision: 600101
URL: http://svn.apache.org/viewvc?rev=600101&view=rev
Log:
Final features for JIT component for M4 (couldn't commit them in time - had connection issues)
Fix for HARMONY-5123 [drlvm][jit] More peephole optimizations for Jitrino.OPT compiler
Fix for HARMONY-4884 [drlvm][jit] VMMagic Address prefetch support in Jitrino.OPT compiler
Fix for HARMONY-5171 [drlvm][jit][opt] Allocation prefetch helpers - commit contains JIT part only
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Sat Dec 1 04:10:50 2007
@@ -164,6 +164,8 @@
class JitHelperCallOp {
public:
enum Id {
+ Prefetch,
+ Memset0,
InitializeArray,
FillArrayWithConst,
SaveThisState,
@@ -462,7 +464,7 @@
virtual void copyValueObj(Type* objType, CG_OpndHandle *dstAddr, CG_OpndHandle *srcAddr) = 0;
virtual CG_OpndHandle* copy(CG_OpndHandle *src) = 0;
virtual CG_OpndHandle* catchException(Type * exceptionType) = 0;
- virtual void prefetch(CG_OpndHandle* refSrc, uint32 offset, int hints) = 0;
+ virtual void prefetch(CG_OpndHandle *addr) = 0;
virtual void pseudoInst() = 0;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h Sat Dec 1 04:10:50 2007
@@ -750,6 +750,7 @@
m==Mnemonic_MOVS16 ||
m==Mnemonic_MOVS32 ||
m==Mnemonic_MOVS64 ||
+ m==Mnemonic_STOS ||
m==Mnemonic_STD ||
m==Mnemonic_CLD ||
m==Mnemonic_POPFD ||
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Sat Dec 1 04:10:50 2007
@@ -2640,6 +2640,58 @@
{
Opnd * dstOpnd=createResultOpnd(retType);
switch(callId) {
+ case Prefetch:
+ {
+ assert (numArgs == 3);
+ Opnd* address = (Opnd*) args[0];
+ Opnd* distance = (Opnd*) args[1];
+ Opnd* stride = (Opnd*) args[2];
+
+ assert (distance->isPlacedIn(OpndKind_Imm) && stride->isPlacedIn(OpndKind_Imm));
+ int dist = distance->getImmValue();
+ int strd = stride->getImmValue();
+
+ for (int i=0; i< dist; i+=strd)
+ {
+ Opnd* prefAddress = irManager.newMemOpnd(typeManager.getInt8Type(), address, 0, 0, irManager.newImmOpnd(typeManager.getInt32Type(), i));
+ Inst* inst = irManager.newInst(Mnemonic_PREFETCH, prefAddress);
+ appendInsts(inst);
+ }
+ break;
+ }
+
+ case Memset0:
+ {
+ assert(numArgs == 2);
+ Opnd** opnds = (Opnd**)args;
+ Opnd *addr = opnds[0];
+ Opnd *size = opnds[1];
+
+ RegName counterRegName = RegName_ECX;
+ RegName dstRegName = RegName_EDI;
+ RegName zeroRegName = RegName_EAX;
+
+ // prepare counter
+ Type* int32Type = typeManager.getInt32Type();
+ Opnd* counter = irManager.newRegOpnd(int32Type,counterRegName);
+ copyOpnd(counter,size);
+ appendInsts(irManager.newInst(Mnemonic_SHR, counter, irManager.newImmOpnd(int32Type,2)));
+
+ // prepare dst
+ Opnd* dst = irManager.newRegOpnd(int32Type,dstRegName);
+ copyOpnd(dst, addr);
+
+ // prepare zero
+ Opnd* eax = irManager.newRegOpnd(int32Type,zeroRegName);
+ //appendInsts(irManager.newInst(Mnemonic_XOR, eax, eax));
+ Opnd* zero = irManager.newImmOpnd(int32Type,0);
+ appendInsts(irManager.newInst(Mnemonic_MOV, eax, zero));
+
+ Inst* storeInst = irManager.newInst(Mnemonic_STOS, dst, counter, eax);
+ storeInst->setPrefix(InstPrefix_REP);
+ appendInsts(storeInst);
+ break;
+ }
case InitializeArray:
assert(numArgs == 4);
appendInsts(irManager.newInternalRuntimeHelperCallInst("initialize_array", numArgs, (Opnd**)args, dstOpnd));
@@ -3096,10 +3148,13 @@
//_______________________________________________________________________________________________________________
-// Prefetch a cache line from [base + offset]
+// Prefetch a cache line from [addr]
-void InstCodeSelector::prefetch(CG_OpndHandle* base, uint32 offset, int hints)
+void InstCodeSelector::prefetch(CG_OpndHandle *addr)
{
+ Opnd *mem = irManager.newMemOpnd(typeManager.getInt8Type(), (Opnd*) addr, 0, 0, 0);
+ Inst* inst = irManager.newInst(Mnemonic_PREFETCH, mem);
+ appendInsts(inst);
}
//_______________________________________________________________________________________________________________
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h Sat Dec 1 04:10:50 2007
@@ -260,7 +260,7 @@
void initType(Type* type);
CG_OpndHandle* catchException(Type * exceptionType);
CG_OpndHandle* copy(CG_OpndHandle *src);
- void prefetch(CG_OpndHandle *src, uint32 offset, int hints);
+ void prefetch(CG_OpndHandle *addr);
void pseudoInst();
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?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp Sat Dec 1 04:10:50 2007
@@ -23,7 +23,6 @@
namespace Jitrino {
namespace Ia32 {
-
class PeepHoleOpt;
static const char* help =
"Performs simple local (per-BB) or per-Inst optimizations.\n"
@@ -84,6 +83,7 @@
//
//
//
+ Changed handleInst_MOV(Inst* inst);
Changed handleInst_Call(Inst* inst);
Changed handleInst_HelperCall(Inst* inst, const Opnd::RuntimeInfo* ri);
Changed handleInst_Convert_F2I_D2I(Inst* inst);
@@ -92,6 +92,8 @@
Changed handleInst_SSEMov(Inst* inst);
Changed handleInst_SSEXor(Inst* inst);
Changed handleInst_CMP(Inst* inst);
+ Changed handleInst_SETcc(Inst* inst);
+
//
// Helpers
//
@@ -180,16 +182,20 @@
{
PeepHoleOpt::Changed temp;
- if (inst->hasKind(Inst::Kind_PseudoInst)) {
+ if (inst->hasKind(Inst::Kind_PseudoInst) && inst->getKind() != Inst::Kind_CopyPseudoInst) {
return Changed_Nothing;
}
Mnemonic mnemonic = inst->getMnemonic();
switch(mnemonic) {
+ case Mnemonic_MOV:
+ return handleInst_MOV(inst);
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:
@@ -203,6 +209,11 @@
} else {
return temp;
}
+ case Mnemonic_SETG:
+ case Mnemonic_SETE:
+ case Mnemonic_SETNE:
+ case Mnemonic_SETL:
+ return handleInst_SETcc(inst);
case Mnemonic_IMUL:
case Mnemonic_MUL:
return handleInst_MUL(inst);
@@ -414,6 +425,167 @@
return i;
}
+PeepHoleOpt::Changed PeepHoleOpt::handleInst_MOV(Inst* inst)
+{
+ Node* node = inst->getNode();
+ if (((BasicBlock*)node)->getLayoutSucc() == NULL)
+ {
+ Inst *next = inst->getNextInst();
+
+ Node *currNode = node;
+ while (next == NULL || next->getKind() == Inst::Kind_MethodEndPseudoInst || next->getMnemonic() == Mnemonic_JMP)
+ {
+ if (next == NULL)
+ {
+ currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode();
+ if (currNode->getKind() == Node::Kind_Exit)
+ return Changed_Nothing;
+ next = (Inst*) currNode->getFirstInst();
+ }
+ else
+ next = next->getNextInst();
+ }
+
+ Inst *jump = next->getNextInst();
+
+
+ bool step1 = true;
+ currNode = node;
+ while (currNode != next->getNode())
+ {
+ currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode();
+ if (currNode->getInDegree()!=1)
+ {
+ step1 = false;
+ break;
+ }
+ }
+
+ // step1:
+ // ---------------------------------------------
+ // MOV opnd, opnd2 MOV opnd3, opnd2
+ // MOV opnd3, opnd ->
+ // ---------------------------------------------
+ // nb: applicable if opnd will not be used further
+ if (step1 && next->getMnemonic() == Mnemonic_MOV)
+ {
+ Opnd *movopnd1, *movopnd2, *nextmovopnd1, *nextmovopnd2;
+ if (inst->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ movopnd1 = inst->getOpnd(0);
+ movopnd2 = inst->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds movuses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds movdefs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ movopnd1 = inst->getOpnd(movdefs.begin());
+ movopnd2 = inst->getOpnd(movuses.begin());
+ }
+ if (next->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ nextmovopnd1 = next->getOpnd(0);
+ nextmovopnd2 = next->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds nextmovuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds nextmovdefs(next, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ nextmovopnd1 = next->getOpnd(nextmovdefs.begin());
+ nextmovopnd2 = next->getOpnd(nextmovuses.begin());
+ }
+ if (movopnd1->getId() == nextmovopnd2->getId() &&
+ !isMem(movopnd2) && !isMem(nextmovopnd1) &&
+ !isMem(movopnd1)
+ )
+ {
+ BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount());
+ irManager->updateLivenessInfo();
+ irManager->getLiveAtExit(next->getNode(), ls);
+ for (Inst* i = (Inst*)next->getNode()->getLastInst(); i!=next; i = i->getPrevInst()) {
+ irManager->updateLiveness(i, ls);
+ }
+ bool dstNotUsed = !ls.getBit(movopnd1->getId());
+ if (dstNotUsed)
+ {
+ irManager->newInst(Mnemonic_MOV, nextmovopnd1, movopnd2)->insertAfter(inst);
+ inst->unlink();
+ next->unlink();
+ return Changed_Node;
+ }
+ }
+ }
+
+ // step2:
+ // --------------------------------------------------------------
+ // MOV opnd, 0/1 Jmp smwh/BB1 Jmp smwh/BB1
+ // CMP opnd, 0 -> CMP opnd, 0 v
+ // Jcc smwh Jcc smwh
+ // BB1: BB1:
+ // --------------------------------------------------------------
+ // nb: applicable if opnd will not be used further
+ if (next->getMnemonic() == Mnemonic_CMP && jump!= NULL && (jump->getMnemonic() == Mnemonic_JE ||
+ jump->getMnemonic() == Mnemonic_JNE))
+ {
+ Opnd *movopnd1, *movopnd2;
+ if (inst->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ movopnd1 = inst->getOpnd(0);
+ movopnd2 = inst->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds movuses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds movdefs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ movopnd1 = inst->getOpnd(movdefs.begin());
+ movopnd2 = inst->getOpnd(movuses.begin());
+ }
+ Inst::Opnds cmpuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Opnd* cmpopnd1 = next->getOpnd(cmpuses.begin());
+ Opnd* cmpopnd2 = next->getOpnd(cmpuses.next(cmpuses.begin()));
+
+ if (isImm(movopnd2) && (movopnd2->getImmValue() == 0 || movopnd2->getImmValue() == 1) &&
+ movopnd1->getId() == cmpopnd1->getId() &&
+ isImm(cmpopnd2) && cmpopnd2->getImmValue() == 0)
+ {
+ BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount());
+ irManager->updateLivenessInfo();
+ irManager->getLiveAtExit(jump->getNode(), ls);
+ bool opndNotUsed = !ls.getBit(movopnd1->getId());
+ if (opndNotUsed)
+ {
+ ControlFlowGraph* cfg = irManager->getFlowGraph();
+ Node* destination = ((BranchInst*)jump)->getTrueTarget();
+ if ((jump->getMnemonic() == Mnemonic_JNE || movopnd2->getImmValue() == 1) && !(jump->getMnemonic() == Mnemonic_JNE && movopnd2->getImmValue() == 1))
+ {
+ destination = ((BranchInst*)jump)->getFalseTarget();
+ }
+ if (node->getId() != next->getNode()->getId())
+ {
+ inst->unlink();
+ Edge *outEdge = node->getOutEdge(Edge::Kind_Unconditional);
+ cfg->replaceEdgeTarget(outEdge, destination, true);
+ cfg->purgeUnreachableNodes(); // previous successor may become unreachable
+ }
+ else
+ {
+ cfg->removeEdge(node->getOutEdge(Edge::Kind_True));
+ cfg->removeEdge(node->getOutEdge(Edge::Kind_False));
+ cfg->addEdge(node, destination);
+ inst->unlink();
+ next->unlink();
+ jump->unlink();
+ }
+
+ return Changed_Node;
+ }
+ }
+ }
+ }
+ return Changed_Nothing;
+}
+
+
PeepHoleOpt::Changed PeepHoleOpt::handleInst_CMP(Inst* inst) {
assert(inst->getMnemonic()==Mnemonic_CMP);
@@ -499,70 +671,267 @@
// 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) {
+ if (mnemonic == Mnemonic_AND)
+ {
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;
- }
+
+ Opnd *newopnd2;
+ // test can work only with operands having equal sizes
+ if (isImm(src2) && src2->getSize() != src1->getSize())
+ newopnd2 = irManager->newImmOpnd(src1->getType(), src2->getImmValue());
+ else
+ newopnd2 = src2;
+ if (!isMem(dst) && !isMem(src1) && !isMem(src2))
+ {
+ BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount());
+ irManager->updateLivenessInfo();
+ irManager->getLiveAtExit(inst->getNode(), ls);
+ for (Inst* i = (Inst*)inst->getNode()->getLastInst(); i!=inst; i = i->getPrevInst()) {
+ irManager->updateLiveness(i, ls);
}
- 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();
- }
+ bool dstNotUsed = !ls.getBit(dst->getId());
+ if (dstNotUsed)
+ {
+ // what: AND opnd1, opnd2 => TEST opnd1, opnd2
+ // nb: applicable if opnd1 will not be used further
+
+ if (inst->getForm() == Inst::Form_Extended)
+ irManager->newInstEx(Mnemonic_TEST, 0, src1, newopnd2)->insertAfter(inst);
+ else
+ irManager->newInst(Mnemonic_TEST, src1, newopnd2)->insertAfter(inst);
inst->unlink();
return Changed_Inst;
}
}
}
+ return Changed_Nothing;
+}
-
- // 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;
- }
+PeepHoleOpt::Changed PeepHoleOpt::handleInst_SETcc(Inst* inst)
+{
+ if (((BasicBlock*)inst->getNode())->getLayoutSucc() == NULL)
+ {
+ Mnemonic mn = inst->getMnemonic();
+
+ Inst* prev = inst->getPrevInst();
+ Inst *next = inst->getNextInst();
- return Changed_Nothing;
+ Node *currNode = inst->getNode();
+ while (next == NULL || next->getKind() == Inst::Kind_MethodEndPseudoInst || next->getMnemonic() == Mnemonic_JMP)
+ {
+ if (next == NULL)
+ {
+ currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode();
+ if (currNode->getKind() == Node::Kind_Exit)
+ return Changed_Nothing;
+ next = (Inst*) currNode->getFirstInst();
+ }
+ else
+ next = next->getNextInst();
+ }
+
+ Inst *next2 = next->getNextInst();
+
+ bool step1 = true;
+ currNode = inst->getNode();
+ while (currNode != next->getNode())
+ {
+ currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode();
+ if (currNode->getInDegree()!=1)
+ {
+ step1 = false;
+ break;
+ }
+ }
+
+ // step1:
+ // ------------------------------------------
+ // MOV opnd, 0 MOV opnd2, 0
+ // SETcc opnd -> SETcc opnd2
+ // MOV opnd2, opnd
+ // ------------------------------------------
+ // nb: applicable if opnd will not be used further
+ if (step1 && prev!= NULL && prev->getMnemonic() == Mnemonic_MOV &&
+ next!= NULL && next->getMnemonic() == Mnemonic_MOV)
+ {
+ Opnd *prevopnd1, *prevopnd2, *nextopnd1, *nextopnd2, *setopnd;
+ if (prev->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ prevopnd1 = prev->getOpnd(0);
+ prevopnd2 = prev->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds prevuses(prev, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds prevdefs(prev, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ prevopnd1 = prev->getOpnd(prevdefs.begin());
+ prevopnd2 = prev->getOpnd(prevuses.begin());
+ }
+ if (next->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ nextopnd1 = next->getOpnd(0);
+ nextopnd2 = next->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds nextuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds nextdefs(next, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ nextopnd1 = next->getOpnd(nextdefs.begin());
+ nextopnd2 = next->getOpnd(nextuses.begin());
+ }
+ Inst::Opnds setdefs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ setopnd = inst->getOpnd(setdefs.begin());
+
+ if (isReg(nextopnd1) &&
+ prevopnd1->getId() == setopnd->getId() &&
+ setopnd->getId() == nextopnd2->getId() &&
+ isImm(prevopnd2) && prevopnd2->getImmValue() == 0
+ )
+ {
+ BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount());
+ irManager->updateLivenessInfo();
+ irManager->getLiveAtExit(next->getNode(), ls);
+ for (Inst* i = (Inst*)next->getNode()->getLastInst(); i!=next; i = i->getPrevInst()) {
+ irManager->updateLiveness(i, ls);
+ }
+ bool opndNotUsed = !ls.getBit(setopnd->getId());
+ if (opndNotUsed)
+ {
+ if (nextopnd1->getRegName() != RegName_Null &&
+ Constraint::getAliasRegName(nextopnd1->getRegName(), OpndSize_8) == RegName_Null)
+ {
+ nextopnd1->assignRegName(setopnd->getRegName());
+ }
+ irManager->newInst(Mnemonic_MOV, nextopnd1, prevopnd2)->insertBefore(inst);
+ irManager->newInst(mn, nextopnd1)->insertBefore(inst);
+ prev->unlink();
+ inst->unlink();
+ next->unlink();
+ return Changed_Node;
+ }
+ }
+ }
+
+ // step2:
+ // --------------------------------------------------------------
+ // MOV opnd, 0 Jcc smwh Jcc smwh
+ // SETcc opnd -> BB1: v BB1:
+ // CMP opnd, 0 ...
+ // Jcc smwh CMP opnd, 0
+ // BB1: Jcc smwh
+ // --------------------------------------------------------------
+ // nb: applicable if opnd will not be used further
+ // nb: conditions of new jumps are calculated from conditions of old jump and set instructions
+ if (prev!= NULL && prev->getMnemonic() == Mnemonic_MOV &&
+ next!= NULL && (next->getMnemonic() == Mnemonic_CMP || next->getMnemonic() == Mnemonic_TEST) &&
+ next2!= NULL && (next2->getMnemonic() == Mnemonic_JG || next2->getMnemonic() == Mnemonic_JE || next2->getMnemonic() == Mnemonic_JNE) )
+ {
+ Opnd* movopnd1;
+ Opnd* movopnd2;
+ if (prev->getKind() == Inst::Kind_CopyPseudoInst)
+ {
+ movopnd1 = prev->getOpnd(0);
+ movopnd2 = prev->getOpnd(1);
+ }
+ else
+ {
+ Inst::Opnds movuses(prev, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Inst::Opnds movdefs(prev, Inst::OpndRole_Explicit|Inst::OpndRole_Def);
+ movopnd1 = prev->getOpnd(movdefs.begin());
+ movopnd2 = prev->getOpnd(movuses.begin());
+ }
+ Inst::Opnds cmpuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use);
+ Opnd* cmpopnd1 = next->getOpnd(cmpuses.begin());
+ Opnd* cmpopnd2 = next->getOpnd(cmpuses.next(cmpuses.begin()));
+
+ if (
+ isImm(movopnd2) && movopnd2->getImmValue() == 0 &&
+ movopnd1->getId() == cmpopnd1->getId() &&
+ //case CMP:
+ (next->getMnemonic() != Mnemonic_CMP || isImm(cmpopnd2) && cmpopnd2->getImmValue() == 0) &&
+ //case TEST:
+ (next->getMnemonic() != Mnemonic_TEST || cmpopnd1->getId() == cmpopnd2->getId())
+ )
+ {
+ BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount());
+ irManager->updateLivenessInfo();
+ irManager->getLiveAtExit(next2->getNode(), ls);
+ bool opndNotUsed = !ls.getBit(movopnd1->getId());
+ if (opndNotUsed)
+ {
+ BranchInst* br = (BranchInst*) next2;
+
+ Mnemonic newjumpmn = Mnemonic_JZ;
+ if (next2->getMnemonic() == Mnemonic_JE)
+ {
+ switch (mn)
+ {
+ case Mnemonic_SETG:
+ newjumpmn = Mnemonic_JLE; break;
+ case Mnemonic_SETE:
+ newjumpmn = Mnemonic_JNE; break;
+ case Mnemonic_SETL:
+ newjumpmn = Mnemonic_JGE; break;
+ case Mnemonic_SETNE:
+ newjumpmn = Mnemonic_JE; break;
+ default:
+ assert(0); break;
+ }
+ }
+ else
+ {
+ switch (mn)
+ {
+ case Mnemonic_SETG:
+ newjumpmn = Mnemonic_JG; break;
+ case Mnemonic_SETE:
+ newjumpmn = Mnemonic_JE; break;
+ case Mnemonic_SETL:
+ newjumpmn = Mnemonic_JL; break;
+ case Mnemonic_SETNE:
+ newjumpmn = Mnemonic_JNE; break;
+ default:
+ assert(0); break;
+ }
+ }
+
+ if (inst->getNode()->getId() != next->getNode()->getId())
+ {
+ ControlFlowGraph* cfg = irManager->getFlowGraph();
+ cfg->removeEdge(inst->getNode()->getOutEdge(Edge::Kind_Unconditional));
+
+ double trueEdgeProb = next2->getNode()->getOutEdge(Edge::Kind_True)->getEdgeProb();
+ double falseEdgeProb = next2->getNode()->getOutEdge(Edge::Kind_False)->getEdgeProb();
+ cfg->addEdge(inst->getNode(), br->getTrueTarget(), trueEdgeProb);
+ cfg->addEdge(inst->getNode(), br->getFalseTarget(), falseEdgeProb);
+ irManager->newBranchInst(newjumpmn, br->getTrueTarget(), br->getFalseTarget())->insertAfter(inst);
+ prev->unlink();
+ inst->unlink();
+ cfg->purgeUnreachableNodes();
+ }
+ else
+ {
+ irManager->newBranchInst(newjumpmn, br->getTrueTarget(), br->getFalseTarget())->insertAfter(next2);
+ prev->unlink();
+ inst->unlink();
+ next->unlink();
+ next2->unlink();
+ }
+ return Changed_Node;
+ }// endif opndNotUsed
+ }
+ }
+ }
+ return Changed_Nothing;
}
PeepHoleOpt::Changed PeepHoleOpt::handleInst_SSEMov(Inst* inst)
@@ -677,3 +1046,4 @@
}
}}; // ~namespace Jitrino::Ia32
+
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Sat Dec 1 04:10:50 2007
@@ -403,6 +403,8 @@
JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) {
switch(callId) {
+ case Prefetch: return JitHelperCallOp::Prefetch;
+ case Memset0: return JitHelperCallOp::Memset0;
case InitializeArray: return JitHelperCallOp::InitializeArray;
case SaveThisState: return JitHelperCallOp::SaveThisState;
case ReadThisState: return JitHelperCallOp::ReadThisState;
@@ -1914,23 +1916,9 @@
break;
case Op_Prefetch:
{
- assert(inst->getNumSrcOperands() == 3);
- Opnd* src1 = inst->getSrc(0);
- Opnd* src2 = inst->getSrc(1);
- Opnd* src3 = inst->getSrc(2);
- assert(src3->getInst()->isConst());
- uint32 hints = src3->getInst()->asConstInst()->getValue().i4;
- CG_OpndHandle * src1Handle = getCGInst(src1);
- uint32 offset = 0;
- if (src2->getInst()->isConst()) {
- offset = src2->getInst()->asConstInst()->getValue().i4;
- } else {
- // Generate an add instruction to add offset to src1
- assert(src2->getType()->isInt4());
- src1Handle = instructionCallback.addRef(RefArithmeticOp::I4,
- src1Handle,getCGInst(src2));
- }
- instructionCallback.prefetch(src1Handle, offset, hints);
+ assert(inst->getNumSrcOperands() == 1);
+ Opnd* addr= inst->getSrc(0);
+ instructionCallback.prefetch(getCGInst(addr));
}
break;
case Op_TauPoint:
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp Sat Dec 1 04:10:50 2007
@@ -1236,12 +1236,9 @@
appendInst(instFactory->makeLeave(label));
}
-Opnd*
-IRBuilder::genPrefetch(Opnd *base, Opnd *offset, Opnd *hints) {
- Opnd *dst = createOpnd(typeManager->getVoidType());
- appendInst(instFactory->makePrefetch(propagateCopy(base), propagateCopy(offset),
- propagateCopy(hints)));
- return dst;
+void
+IRBuilder::genPrefetch(Opnd *addr) {
+ appendInst(instFactory->makePrefetch(propagateCopy(addr)));
}
Opnd* IRBuilder::createTypeOpnd(ObjectType* type) {
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h Sat Dec 1 04:10:50 2007
@@ -374,7 +374,7 @@
Opnd* genTauAnd(Opnd *src1, Opnd *src2);
// UNUSED GEN
- Opnd* genPrefetch(Opnd* base, Opnd *offset, Opnd *hints);
+ void genPrefetch(Opnd *addr); // prefetch
Opnd* genCopy(Opnd* src);
Opnd* genTauPi(Opnd* src, Opnd *tau, PiCondition *cond);
// compressed reference instructions
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Sat Dec 1 04:10:50 2007
@@ -464,6 +464,10 @@
switch(code) {
case 'd':
switch(jitHelperId) {
+ case Prefetch:
+ os << "Prefetch"; break;
+ case Memset0:
+ os << "Memset0"; break;
case InitializeArray:
os << "InitializeArray"; break;
case SaveThisState:
@@ -1973,11 +1977,8 @@
Inst* InstFactory::makeEndCatch() {
return makeInst(Op_EndCatch, Modifier(), Type::Void, OpndManager::getNullOpnd());
}
-
-Inst* InstFactory::makePrefetch(Opnd *base, Opnd* offset, Opnd *hints) {
- return makeMultiSrcInst(Op_Prefetch, Modifier(), Type::Void,
- OpndManager::getNullOpnd(),
- base, offset, hints);
+Inst* InstFactory::makePrefetch(Opnd* addr) {
+ return makeInst(Op_Prefetch, Modifier(), Type::Void, OpndManager::getNullOpnd(), addr);
}
Inst*
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h Sat Dec 1 04:10:50 2007
@@ -1274,7 +1274,7 @@
// profile counter increment
Inst* makeIncCounter(uint32 val);
- Inst* makePrefetch(Opnd *base, Opnd *offset, Opnd *hints);
+ Inst* makePrefetch(Opnd* addr); // prefetch
// compressed references
Inst* makeUncompressRef(Opnd* dst, Opnd* compref);
@@ -2039,4 +2039,5 @@
} //namespace Jitrino
#endif // _INST_H_
+
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp Sat Dec 1 04:10:50 2007
@@ -209,7 +209,7 @@
// Profile instrumentation instructions
{ Op_IncCounter, true, MB::None, MK::None, "inccounter", "inccounter(%d)", }, // Increment a profile counter by 1
- { Op_Prefetch, true, MB::StoreOrSync, MK::None, "prefetch", "prefetch %0,%1,%2", },
+ { Op_Prefetch, true, MB::StoreOrSync, MK::None, "prefetch", "prefetch %0 ", }, //StoreOrSync
// Compressed Pointer instructions
{ Op_UncompressRef, false, MB::Movable, MK::None, "uncmpref", "uncmpref %s -) %l", },
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Sat Dec 1 04:10:50 2007
@@ -270,6 +270,8 @@
};
enum JitHelperCallId {
+ Prefetch,
+ Memset0,
InitializeArray,
FillArrayWithConst,
SaveThisState, //todo: replace with GetTLS + offset sequence
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Sat Dec 1 04:10:50 2007
@@ -407,6 +407,8 @@
case Op_JitHelperCall: // calljithelper
if (method_ea_level == 0) {
switch(inst->asJitHelperCallInst()->getJitHelperId()) {
+ case Prefetch:
+ case Memset0:
case InitializeArray:
case FillArrayWithConst:
case SaveThisState:
@@ -615,13 +617,13 @@
case Op_TauVirtualCall: // callvirt
case Op_IndirectCall: // calli
-
+
case Op_TauStRef:
case Op_TauStField:
case Op_TauStElem:
+ case Op_Prefetch:
case Op_TauStStatic:
case Op_Copy:
-
case Op_Box:
break;
@@ -3753,7 +3755,7 @@
os_sc << " null ";
os_sc << std::endl;
} else {
- printCnGNode(stnode,os_sc); os_sc << std::endl;
+ printCnGNode(stnode,os_sc); os_sc << std::endl;
}
}
}
@@ -3853,7 +3855,7 @@
if ((*it)->nodeType == NT_OBJECT
&& getOutEscaped(*it) == 0 && !((*it)->nInst->getOpcode()==Op_LdRef)) {
if ((*it)->nInst->getNode() == NULL && getEscState(*it)==NO_ESCAPE) {
- continue; // already scalarized
+ continue; // already scalarized
}
ob_ref_type = (*it)->nodeRefType; // object ref type
if (ob_ref_type != NR_REF) {
@@ -3889,7 +3891,7 @@
os_sc << " null ";
os_sc << std::endl;
} else {
- printCnGNode(stnode,os_sc); os_sc << std::endl;
+ printCnGNode(stnode,os_sc); os_sc << std::endl;
}
}
@@ -5545,17 +5547,17 @@
EscAnalyzer::CnGNode*
EscAnalyzer::getLObj(CnGNode* vval) {
- CnGNode* n = vval;
- while (n->nodeType != NT_LDOBJ) {
- if (n->nodeType!=NT_VARVAL)
- return NULL;
- if (n->outEdges == NULL)
- return NULL;
- if ((n->outEdges)->size()!=1)
- return NULL;
- n=(n->outEdges)->front()->cngNodeTo;
- }
- return n;
+ CnGNode* n = vval;
+ while (n->nodeType != NT_LDOBJ) {
+ if (n->nodeType!=NT_VARVAL)
+ return NULL;
+ if (n->outEdges == NULL)
+ return NULL;
+ if ((n->outEdges)->size()!=1)
+ return NULL;
+ n=(n->outEdges)->front()->cngNodeTo;
+ }
+ return n;
} //getLObj(CnGNode* vval)
@@ -5879,4 +5881,6 @@
}
} //namespace Jitrino
+
+
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp Sat Dec 1 04:10:50 2007
@@ -581,7 +581,7 @@
copy = _instFactory.makeCopy(dst, src);
} else {
Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
- copy = _instFactory.makeConv(mod, dst->getType()->tag, dst, src);
+ copy = _instFactory.makeConvUnmanaged(mod, dst->getType()->tag, dst, src);
}
copy->insertBefore(inst);
inst->unlink();
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Sat Dec 1 04:10:50 2007
@@ -661,6 +661,8 @@
JitHelperCallInst *jitcalli = i->asJitHelperCallInst();
JitHelperCallId callId = jitcalli->getJitHelperId();
switch (callId) {
+ case Prefetch:
+ case Memset0:
case InitializeArray:
case SaveThisState:
case ReadThisState:
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp Sat Dec 1 04:10:50 2007
@@ -1724,6 +1724,10 @@
}
pushOpnd(irBuilder.genNewObjWithResolve(methodToCompile.getParentType()->asObjectType(), constPoolIndex));
} else {
+#ifdef _DEBUG
+ const char* typeName = type->getName();
+ assert(!VMMagicUtils::isVMMagicClass(typeName));
+#endif
pushOpnd(irBuilder.genNewObj(type));
}
}
@@ -3337,6 +3341,16 @@
}
//
+ // prefetch
+ //
+ if (!strcmp(mname, "prefetch"))
+ {
+ Opnd* prefetchingAddress = arg0;
+ irBuilder.genPrefetch(prefetchingAddress);
+ return true;
+ }
+
+ //
// fromXXX, toXXX - static creation from something
//
if (!strcmp(mname, "fromLong")
@@ -3576,6 +3590,20 @@
if (!strcmp(mname,"writeBarrier")) {
assert(numArgs == 3);
irBuilder.genVMHelperCall(VM_RT_GC_HEAP_WRITE_REF, resType, numArgs, srcOpnds);
+ return true;
+ }
+
+ if (!strcmp(mname, "memset0"))
+ {
+ assert(numArgs == 2);
+ irBuilder.genJitHelperCall(Memset0, resType, numArgs, srcOpnds);
+ return true;
+ }
+
+ if (!strcmp(mname, "prefetch"))
+ {
+ assert(numArgs == 3);
+ irBuilder.genJitHelperCall(Prefetch, resType, numArgs, srcOpnds);
return true;
}
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h Sat Dec 1 04:10:50 2007
@@ -551,6 +551,7 @@
Mnemonic_NOP, // No Operation
Mnemonic_NOT, // One's Complement Negation
Mnemonic_OR, // Logical Inclusive OR
+Mnemonic_PREFETCH, // prefetch
#ifdef _HAVE_MMX_
Mnemonic_PADDQ, // Add Packed Quadword Integers
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?rev=600101&r1=600100&r2=600101&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Sat Dec 1 04:10:50 2007
@@ -1183,6 +1183,12 @@
END_OPCODES()
END_MNEMONIC()
+BEGIN_MNEMONIC(PREFETCH, MF_NONE, U)
+BEGIN_OPCODES()
+{OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U },
+END_OPCODES()
+END_MNEMONIC()
+
BEGIN_MNEMONIC(PUSH, MF_NONE, U )
BEGIN_OPCODES()
{OpcodeInfo::all, {Size16, 0xFF, _6}, {r_m16}, U },
@@ -1414,10 +1420,10 @@
END_OPCODES()
END_MNEMONIC()
-BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, U_U)
+BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U)
BEGIN_OPCODES()
- {OpcodeInfo::all, {0xAB}, {EDI, EAX}, U_U },
- {OpcodeInfo::em64t, {REX_W, 0xAB}, {RDI, RAX}, U_U },
+ {OpcodeInfo::all, {0xAB}, {EDI, ECX, EAX}, DU_DU_U },
+ {OpcodeInfo::em64t, {REX_W, 0xAB}, {RDI, RCX, RAX}, DU_DU_U },
END_OPCODES()
END_MNEMONIC()