You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ap...@apache.org on 2006/12/27 15:58:38 UTC
svn commit: r490506 - in /harmony/enhanced/drlvm/trunk/vm:
jitrino/config/ia32/ jitrino/src/codegenerator/ia32/ jitrino/src/dynopt/
port/src/encoder/ia32_em64t/
Author: apetrenko
Date: Wed Dec 27 06:58:37 2006
New Revision: 490506
URL: http://svn.apache.org/viewvc?view=rev&rev=490506
Log:
Patch for HARMONY-2686 "[drlvm][jit][opt] Jitrino doesn't remove unnesassary conditional jumps after constants compare"
Added:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp (with props)
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf Wed Dec 27 06:58:37 2006
@@ -54,7 +54,7 @@
-XDjit.CD_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
-XDjit.CD_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
--XDjit.CD_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.CD_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XDjit.CD_OPT.path.dce1=cg_dce
-XDjit.CD_OPT.path.dce2=cg_dce
-XDjit.CD_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -69,6 +69,8 @@
-XDjit.CD_OPT.arg.codegen.dce1.early=yes
-XDjit.CD_OPT.arg.codegen.regalloc.bp_regalloc1.regs=ALL_GP
-XDjit.CD_OPT.arg.codegen.regalloc.bp_regalloc2.regs=ALL_XMM
+-XDjit.CD_OPT.arg.codegen.btr.insertCMOVs=no
+-XDjit.CD_OPT.arg.codegen.btr.removeConstCompare=yes
#system properties
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf Wed Dec 27 06:58:37 2006
@@ -25,7 +25,7 @@
-XDjit.CS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
-XDjit.CS_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
--XDjit.CS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.CS_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XDjit.CS_OPT.path.dce1=cg_dce
-XDjit.CS_OPT.path.dce2=cg_dce
-XDjit.CS_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -41,6 +41,9 @@
-XDjit.CS_OPT.arg.codegen.dce1.early=yes
-XDjit.CS_OPT.arg.codegen.regalloc.bp_regalloc1.regs=ALL_GP
-XDjit.CS_OPT.arg.codegen.regalloc.bp_regalloc2.regs=ALL_XMM
+
+-XDjit.CS_OPT.arg.codegen.btr.insertCMOVs=no
+-XDjit.CS_OPT.arg.codegen.btr.removeConstCompare=yes
#-XDjit.CS_OPT.arg.log.irdump.file=log/%jit%/%log%/%seqnb%_%class%.%method%.log
#-XDjit.CS_OPT.arg.log=ct,ir,irdump,all
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Wed Dec 27 06:58:37 2006
@@ -46,7 +46,7 @@
-XDjit.SD1_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
-XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,vp_instrument,edge_instrument,dessa,statprof,markglobals
--XDjit.SD1_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SD1_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XDjit.SD1_OPT.path.dce1=cg_dce
-XDjit.SD1_OPT.path.dce2=cg_dce
-XDjit.SD1_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -56,11 +56,13 @@
-XDjit.SD1_OPT.arg.codegen.dce1.early=yes
-XDjit.SD1_OPT.arg.codegen.regalloc.bp_regalloc1.regs=ALL_GP
-XDjit.SD1_OPT.arg.codegen.regalloc.bp_regalloc2.regs=ALL_XMM
+-XDjit.SD1_OPT.arg.codegen.btr.insertCMOVs=no
+-XDjit.SD1_OPT.arg.codegen.btr.removeConstCompare=yes
-XDjit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
-XDjit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,edge_annotate,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,statprof,markglobals
--XDjit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SD2_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XDjit.SD2_OPT.path.dce1=cg_dce
-XDjit.SD2_OPT.path.dce2=cg_dce
-XDjit.SD2_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -102,6 +104,8 @@
-XDjit.SD2_OPT.arg.codegen.dce1.early=yes
-XDjit.SD2_OPT.arg.codegen.regalloc.bp_regalloc1.regs=ALL_GP
-XDjit.SD2_OPT.arg.codegen.regalloc.bp_regalloc2.regs=ALL_XMM
+-XDjit.SD2_OPT.arg.codegen.btr.insertCMOVs=no
+-XDjit.SD2_OPT.arg.codegen.btr.removeConstCompare=yes
#system properties
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf Wed Dec 27 06:58:37 2006
@@ -25,7 +25,7 @@
-XDjit.SS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
-XDjit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,hvn,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,statprof,markglobals
--XDjit.SS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SS_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XDjit.SS_OPT.path.dce1=cg_dce
-XDjit.SS_OPT.path.dce2=cg_dce
-XDjit.SS_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -40,6 +40,8 @@
-XDjit.SS_OPT.arg.codegen.dce1.early=yes
-XDjit.SS_OPT.arg.codegen.regalloc.bp_regalloc1.regs=ALL_GP
-XDjit.SS_OPT.arg.codegen.regalloc.bp_regalloc2.regs=ALL_XMM
+-XDjit.SS_OPT.arg.codegen.btr.insertCMOVs=no
+-XDjit.SS_OPT.arg.codegen.btr.removeConstCompare=yes
#system properties
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp Wed Dec 27 06:58:37 2006
@@ -149,7 +149,7 @@
irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type, -1))->insertBefore(callInst);
irm->newInstEx(Mnemonic_BSR, 1, r1, arg)->insertBefore(callInst);
- irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2)->insertBefore(callInst);
+ irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r1, r2)->insertBefore(callInst);
irm->newInstEx(Mnemonic_SUB, 1, res, irm->newImmOpnd(i32Type, 31), r1)->insertBefore(callInst);
callInst->unlink();
@@ -168,7 +168,7 @@
irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type, 32))->insertBefore(callInst);
irm->newInstEx(Mnemonic_BSF, 1, r1, arg)->insertBefore(callInst);
- irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2)->insertBefore(callInst);
+ irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r1, r2)->insertBefore(callInst);
irm->newCopyPseudoInst(Mnemonic_MOV, res, r1)->insertBefore(callInst);
callInst->unlink();
@@ -219,7 +219,7 @@
//high_part_is_zero
hiZeroNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type, -1)));
hiZeroNode->appendInst(irm->newInstEx(Mnemonic_BSR, 1, r1, lwOpnd));
- hiZeroNode->appendInst(irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2));
+ hiZeroNode->appendInst(irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r1, r2));
hiZeroNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, res, irm->newImmOpnd(i32Type, 63), r1));
@@ -297,3 +297,4 @@
}
}} //namespace
+
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp?view=auto&rev=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp Wed Dec 27 06:58:37 2006
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Sidelnikov
+ * @version $Revision: 1.6 $
+ */
+#include "Ia32IRManager.h"
+
+namespace Jitrino
+{
+namespace Ia32 {
+//========================================================================================
+// class BranchTranslator
+//========================================================================================
+/**
+ * class BranchTranslator is implementation of replacing branching for a
+ * single loading of an operand with a conditional CMOVcc or SETcc
+ * instruction
+ * The algorithm takes one-pass over CFG.
+ *
+ * This transformer allows to reduce count of branches
+ *
+ * This transformer is recommended to be inserted before all optimizations
+ * because it unites basic blocks
+ *
+ * The algorithm works as follows:
+ *
+ * 1) Finds branch instruction which performs branch to basic blocks with
+ * only instructions MOV with the same def-operand.
+ *
+ * 2) If each of thus blocks has only one predecessor they and branch
+ * instruction is replaced with conditional instruction
+ *
+ * The implementation of this transformer is located Ia32BranchTrans.cpp.
+ */
+class BranchTranslator : public SessionAction {
+
+ void runImpl();
+};
+
+static ActionFactory<BranchTranslator> _btr("btr");
+
+Opnd * getMOVsChainSource(Opnd * opnd) {
+
+ if (opnd->getDefScope() == Opnd::DefScope_SemiTemporary)
+ return opnd;
+
+ Inst * instUp = opnd->getDefiningInst();
+ Inst * movInst = NULL;
+
+ for(;instUp!=NULL && instUp->getMnemonic() == Mnemonic_MOV;instUp = instUp->getOpnd(1)->getDefiningInst())
+ {
+ movInst = instUp;
+ }
+ if (movInst)
+ return movInst->getOpnd(1);
+ else
+ return opnd;
+}
+
+bool branchDirection (int64 v1, int64 v2, OpndSize sz,ConditionMnemonic mn) {
+ switch (sz) {
+ case OpndSize_8:
+ v1 = int64(int8(v1));
+ v2 = int64(int8(v2));
+ break;
+ case OpndSize_16:
+ v1 = int64(int16(v1));
+ v2 = int64(int16(v2));
+ break;
+ case OpndSize_32:
+ v1 = int64(int32(v1));
+ v2 = int64(int32(v2));
+ break;
+ default:
+ break;
+ }
+
+ bool branchDirection = false;
+ switch (mn) {
+ case ConditionMnemonic_E:
+ branchDirection = v1 == v2;
+ break;
+ case ConditionMnemonic_NE:
+ branchDirection = v1 != v2;
+ break;
+ case ConditionMnemonic_G:
+ branchDirection = v1 > v2;
+ break;
+ case ConditionMnemonic_GE:
+ branchDirection = v1>= v2;
+ break;
+ case ConditionMnemonic_L:
+ branchDirection = v1 < v2;
+ break;
+ case ConditionMnemonic_LE:
+ branchDirection = v1 <= v2;
+ break;
+ case ConditionMnemonic_AE:
+ branchDirection = (uint64)v1 >= (uint64)v2;
+ break;
+ case ConditionMnemonic_A:
+ branchDirection = (uint64)v1 > (uint64)v2;
+ break;
+ case ConditionMnemonic_BE:
+ branchDirection = (uint64)v1<= (uint64)v2;
+ break;
+ case ConditionMnemonic_B:
+ branchDirection = (uint64)v1 < (uint64)v2;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return branchDirection;
+}
+
+void
+BranchTranslator::runImpl()
+{
+ const Nodes& nodes = irManager->getFlowGraph()->getNodesPostOrder();
+ irManager->calculateOpndStatistics();
+
+ bool consts = false;
+ getArg("removeConstCompare", consts);
+
+ if (consts) {
+ StlMap<Node *, bool> loopHeaders(irManager->getMemoryManager());
+ LoopTree * lt = irManager->getFlowGraph()->getLoopTree();
+ for (Nodes::const_reverse_iterator it = nodes.rbegin(),end = nodes.rend();it!=end; ++it) {
+ Node* bb = *it;
+ if (lt->isLoopHeader(bb))
+ loopHeaders[bb] = true;
+ else
+ loopHeaders[bb] = false;
+ }
+
+ for (Nodes::const_reverse_iterator it = nodes.rbegin(),end = nodes.rend();it!=end; ++it) {
+ Node* bb = *it;
+ if (bb->isBlockNode()){
+ if(bb->isEmpty())
+ continue;
+
+ Inst * inst = (Inst *)bb->getLastInst();
+ //check is last instruction in basic block is a conditional branch instruction
+ if(inst && inst->hasKind(Inst::Kind_BranchInst)) {
+ //get successors of bb
+ if(bb->getOutEdges().size() == 1)
+ continue;
+
+ Node * trueBB = bb->getTrueEdge()->getTargetNode();
+ Node * falseBB = bb->getFalseEdge()->getTargetNode();
+
+ ConditionMnemonic condMnem = ConditionMnemonic(inst->getMnemonic() - getBaseConditionMnemonic(inst->getMnemonic()));
+
+ //****start check for constants comparison****
+
+ Inst * cmpInst = inst->getPrevInst();
+ if (cmpInst && cmpInst->getMnemonic() == Mnemonic_CMP) {
+ Inst::Opnds uses(cmpInst,Inst::OpndRole_Use|Inst::OpndRole_Explicit|Inst::OpndRole_Auxilary);
+ Opnd * cmpOp1 = cmpInst->getOpnd(uses.begin());
+ Opnd * cmpOp2 = cmpInst->getOpnd(uses.begin()+1);
+
+ if (cmpOp1->getDefScope() == Opnd::DefScope_Temporary) {
+ cmpOp1 = getMOVsChainSource(cmpOp1);
+ if (!cmpOp1->isPlacedIn(OpndKind_Imm)) {
+ for(Inst * copy = (Inst *)bb->getLastInst();copy!=NULL; copy=copy->getPrevInst()) {
+ Inst::Opnds opnds(copy, Inst::OpndRole_Def|Inst::OpndRole_ForIterator);
+ for (Inst::Opnds::iterator ito = opnds.begin(); ito != opnds.end(); ito = opnds.next(ito)){
+ Opnd * opnd = copy->getOpnd(ito);
+ if (opnd == cmpOp1 && copy->getMnemonic() == Mnemonic_MOV) {
+ cmpOp1 = copy->getOpnd(1);
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ if (cmpOp1->isPlacedIn(OpndKind_Imm)) {
+ cmpOp2 = getMOVsChainSource(cmpOp2);
+ if (cmpOp2->isPlacedIn(OpndKind_Imm)) {
+ //Two constants are operands of CMP inst
+ irManager->resolveRuntimeInfo(cmpOp1);
+ irManager->resolveRuntimeInfo(cmpOp2);
+ int64 v1 = cmpOp1->getImmValue();
+ int64 v2 = cmpOp2->getImmValue();
+ //remove "dead" edges
+ if (branchDirection(v1,v2,cmpOp1->getSize(),condMnem)) {
+ irManager->getFlowGraph()->removeEdge(bb->getFalseEdge());
+ } else {
+ irManager->getFlowGraph()->removeEdge(bb->getTrueEdge());
+ }
+ //remove CMP and Jcc instructions
+ inst->unlink();
+ cmpInst->unlink();
+ continue;
+ }
+ }
+ }
+ cmpOp1 = getMOVsChainSource(cmpOp1);
+ if (cmpOp1->getDefScope() == Opnd::DefScope_Variable) {
+ if(loopHeaders[bb])
+ continue;
+ cmpOp2 = getMOVsChainSource(cmpOp2);
+ if (cmpOp2->isPlacedIn(OpndKind_Imm) && bb->getInEdges().size()>1) {
+
+ const Edges& inEdges = bb->getInEdges();
+ StlMap<Edge *, Opnd *> defInsts(irManager->getMemoryManager());
+ Inst * nextInst = inst->getPrevInst();
+ int i = -1;
+ bool stopSearch = false;
+ Node * node = bb;
+
+ while (!stopSearch && i != (int)inEdges.size()) {
+ bool found = false;
+ for (Inst * prevInst=NULL; nextInst!=NULL && !found; nextInst=prevInst){
+ Inst::Opnds opnds(nextInst, Inst::OpndRole_Def|Inst::OpndRole_ForIterator);
+ if (i==-1 && nextInst != cmpInst && nextInst->getMnemonic() != Mnemonic_MOV) {
+ stopSearch = true;
+ break;
+ }
+ for (Inst::Opnds::iterator ito = opnds.begin(); ito != opnds.end(); ito = opnds.next(ito)){
+ Opnd * opnd = nextInst->getOpnd(ito);
+ if (opnd == cmpOp1) {
+ opnd = getMOVsChainSource(nextInst->getOpnd(1));
+ if(!opnd->isPlacedIn(OpndKind_Imm)) {
+ found=true;
+ break;
+ }
+ if (i==-1) {
+ stopSearch=true;
+ break;
+ }
+ defInsts[inEdges[i]] = opnd;
+ found = true;
+ }
+ }
+ prevInst=nextInst->getPrevInst();
+ }
+ const Edges& edges = node->getInEdges();
+ if (found || i == -1 || edges.size() > 1) {
+ i++;
+ if (i < (int)inEdges.size()) {
+ node = inEdges[i]->getSourceNode();
+ nextInst = (Inst *)node->getLastInst();
+ }
+ } else {
+ node = edges.front()->getSourceNode();
+ nextInst = (Inst*)node->getLastInst();
+ }
+ }
+ if (!stopSearch) {
+ for (StlMap<Edge *, Opnd *>::iterator eit = defInsts.begin(); eit != defInsts.end(); eit++) {
+ Edge * edge = eit->first;
+ Opnd * opnd = eit->second;
+ if (branchDirection(opnd->getImmValue(), cmpOp2->getImmValue(),cmpOp1->getSize(),condMnem)) {
+ irManager->getFlowGraph()->replaceEdgeTarget(edge, trueBB);
+ } else {
+ irManager->getFlowGraph()->replaceEdgeTarget(edge, falseBB);
+ }
+ for(Inst * copy = (Inst *)bb->getFirstInst();copy!=NULL; copy=copy->getNextInst()) {
+ if (copy != inst && copy !=cmpInst) {
+ Node * sourceBB = edge->getSourceNode();
+ Inst * lastInst = (Inst*)sourceBB->getLastInst();
+ Inst * newInst = copy->getKind() == Inst::Kind_I8PseudoInst?
+ irManager->newI8PseudoInst(Mnemonic_MOV,1,copy->getOpnd(0),copy->getOpnd(1)):
+ irManager->newCopyPseudoInst(Mnemonic_MOV,copy->getOpnd(0),copy->getOpnd(1));
+ if (lastInst->getKind()== Inst::Kind_BranchInst)
+ sourceBB->prependInst(newInst, lastInst);
+ else
+ sourceBB->appendInst(newInst);
+ }
+ }
+ }
+ }
+ }
+ } else if (cmpOp1->getDefScope() == Opnd::DefScope_SemiTemporary) {
+ //try to reduce ObjMonitorEnter pattern
+ const Edges& inEdges = bb->getInEdges();
+ if (inEdges.size() != 1)
+ continue;
+ Inst * defInst = cmpInst->getPrevInst();
+ bool stopSearch = false;
+ while (1) {
+ if (!defInst || (defInst->getPrevInst() == NULL && defInst->getNode() == bb)) {
+ defInst = (Inst*)inEdges.front()->getSourceNode()->getLastInst();
+ } else {
+ defInst = defInst->getPrevInst();
+ if (defInst == NULL)
+ break;
+ }
+ Inst::Opnds defs(defInst,Inst::OpndRole_Def|Inst::OpndRole_Explicit|Inst::OpndRole_Auxilary);
+ for (Inst::Opnds::iterator ito = defs.begin(); ito != defs.end(); ito = defs.next(ito)){
+ Opnd * opnd = defInst->getOpnd(ito);
+ if (opnd == cmpOp1) {
+ Mnemonic mnem = getBaseConditionMnemonic(defInst->getMnemonic());
+ ConditionMnemonic cm = ConditionMnemonic(defInst->getMnemonic()-mnem);
+ if (mnem == Mnemonic_SETcc && cmpOp2->isPlacedIn(OpndKind_Imm) && cmpOp2->getImmValue() == 0) {
+ if(cm == (inst->getMnemonic()- getBaseConditionMnemonic(inst->getMnemonic()))) {
+ defInst->unlink();
+ cmpInst->unlink();
+ inst->unlink();
+ bb->appendInst(irManager->newBranchInst((Mnemonic)(Mnemonic_Jcc+reverseConditionMnemonic(cm)),((BranchInst*)inst)->getTrueTarget(),((BranchInst*)inst)->getFalseTarget()));
+ stopSearch = true;
+ break;
+ }
+ } else {
+ stopSearch = true;
+ break;
+ }
+ }
+ }
+ Inst::Opnds flags(defInst,Inst::OpndRole_Def|Inst::OpndRole_Implicit);
+ if (stopSearch || (defInst->getOpnd(flags.begin())->getRegName() == RegName_EFLAGS)) break;
+ }
+ continue;
+ }
+ }
+ //****end check for constants comparison****
+ }
+ }
+ }
+ }
+
+ bool cmovs = false;
+ getArg("insertCMOVs", cmovs);
+
+ if (cmovs) {
+ for (Nodes::const_reverse_iterator it = nodes.rbegin(),end = nodes.rend();it!=end; ++it) {
+ Node* bb = *it;
+ if (bb->isBlockNode()){
+ if(bb->isEmpty())
+ continue;
+
+ Inst * inst = (Inst *)bb->getLastInst();
+ //check is last instruction in basic block is a conditional branch instruction
+ if(inst && inst->hasKind(Inst::Kind_BranchInst)) {
+ //get successors of bb
+ if(bb->getOutEdges().size() == 1)
+ continue;
+
+ Node * trueBB = bb->getTrueEdge()->getTargetNode();
+ Node * falseBB = bb->getFalseEdge()->getTargetNode();
+
+ ConditionMnemonic condMnem = ConditionMnemonic(inst->getMnemonic() - getBaseConditionMnemonic(inst->getMnemonic()));
+
+ //check is both successors have only instruction
+ Inst * trueInst = (Inst *)trueBB->getFirstInst();
+ Inst * falseInst = (Inst *)falseBB->getFirstInst();
+ if(trueBB && falseInst && trueBB->getInstCount() == 1 && falseBB->getInstCount() == 1 && trueInst->getMnemonic() == Mnemonic_MOV && falseInst->getMnemonic() == Mnemonic_MOV && trueInst->getOpnd(0) == falseInst->getOpnd(0) && trueInst->getOpnd(0)->getMemOpndKind() == MemOpndKind_Null) {
+ //check is bb is only predecessor for trueBB and falseBB
+ bool canBeRemoved = true;
+ Node * nextBB = trueBB->getOutEdges().front()->getTargetNode();
+ if (falseBB->getOutEdges().front()->getTargetNode() != nextBB)
+ canBeRemoved = false;
+
+ const Edges& tEdges = trueBB->getInEdges();
+ for (Edges::const_iterator edge = tEdges.begin(); edge != tEdges.end(); ++edge) {
+ Edge * e = *edge;
+ if (e->getSourceNode() != bb)
+ canBeRemoved = false;
+ }
+ const Edges& fEdges = falseBB->getInEdges();
+ for (Edges::const_iterator edge = fEdges.begin(); edge != fEdges.end(); ++edge) {
+ Edge * e = *edge;
+ if (e->getSourceNode() != bb)
+ canBeRemoved = false;
+ }
+ if (!canBeRemoved)
+ continue;
+
+ Opnd * tfOp= trueInst->getOpnd(0);
+ Opnd * tsOp= trueInst->getOpnd(1);
+ Opnd * fsOp= falseInst->getOpnd(1);
+ int64 v1 = tsOp->getImmValue();
+ int64 v2 = fsOp->getImmValue();
+ if (tsOp->isPlacedIn(OpndKind_Imm) &&
+ fsOp->isPlacedIn(OpndKind_Imm) &&
+ ((v1==0 && v2==1)|| (v1==1 && v2==0)))
+ {
+ bb->prependInst(irManager->newCopyPseudoInst(Mnemonic_MOV, tfOp, v1?fsOp:tsOp), inst);
+ bb->prependInst(irManager->newInstEx(Mnemonic(Mnemonic_SETcc+(v1?condMnem:reverseConditionMnemonic(condMnem))), 1, tfOp,tfOp),inst);
+ } else {
+ //insert loading of initial value for operand
+ bb->prependInst(irManager->newCopyPseudoInst(Mnemonic_MOV, tfOp, fsOp), inst);
+ if (tsOp->isPlacedIn(OpndKind_Imm)) {
+ Opnd * tempOpnd = irManager->newOpnd(tsOp->getType());
+ Inst * tempInst = irManager->newCopyPseudoInst(Mnemonic_MOV, tempOpnd, tsOp);
+ bb->prependInst(tempInst, inst);
+ tsOp = tempOpnd;
+ }
+ //insert conditional CMOVcc instruction
+ bb->prependInst(irManager->newInstEx(Mnemonic(Mnemonic_CMOVcc+condMnem), 1, tfOp,tfOp,tsOp),inst);
+ }
+ //link bb with successor of trueBB and falseBB
+ irManager->getFlowGraph()->replaceEdgeTarget(bb->getFalseEdge(), nextBB);
+ irManager->getFlowGraph()->removeEdge(bb->getTrueEdge());
+ inst->unlink();
+ irManager->getFlowGraph()->removeNode(falseBB);
+ irManager->getFlowGraph()->removeNode(trueBB);
+
+ }
+ }
+ }//end if BasicBlock
+ }//end for() by Nodes
+ }
+
+ irManager->getFlowGraph()->purgeEmptyNodes();
+ irManager->getFlowGraph()->purgeUnreachableNodes();
+}
+
+} //end namespace Ia32
+}
Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp Wed Dec 27 06:58:37 2006
@@ -467,9 +467,15 @@
Opnd* fromOpnd = NULL;
int32 offset = 0;
Mnemonic mn = inst->getMnemonic();
+
+ Mnemonic conditionalMnem = getBaseConditionMnemonic(mn);
+ if (conditionalMnem != Mnemonic_NULL)
+ mn = conditionalMnem;
+
switch (mn) {
case Mnemonic_XOR:
case Mnemonic_MOV:
+ case Mnemonic_CMOVcc:
assert(mn != Mnemonic_XOR || inst->getOpnd(useIndex1)==opnd);
fromOpnd = inst->getOpnd(useIndex1);
break;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp Wed Dec 27 06:58:37 2006
@@ -570,7 +570,6 @@
Node* sinkNode = subCFG->getReturnNode();
bbHMain->appendInst(irManager->newInst(Mnemonic_CMP, src1_2, src2_2));
- bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, sinkNode, bbLMain));
bbLMain->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));
@@ -588,7 +587,16 @@
}
bbLMain->appendInst(irManager->newBranchInst(mnem, bbDB, bbFT));
- subCFG->addEdge(bbHMain, sinkNode, 0.1);
+ if (condInst->getMnemonic() == Mnemonic_JZ) {
+ bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbFT, bbLMain));
+ subCFG->addEdge(bbHMain, bbFT, 0.1);
+ } else if (condInst->getMnemonic() == Mnemonic_JNZ) {
+ bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbDB, bbLMain));
+ subCFG->addEdge(bbHMain, bbDB, 0.1);
+ } else {
+ bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, sinkNode, bbLMain));
+ subCFG->addEdge(bbHMain, sinkNode, 0.1);
+ }
subCFG->addEdge(bbHMain, bbLMain, 0.9);
subCFG->addEdge(bbLMain, bbFT, 0.1);
subCFG->addEdge(bbLMain, bbDB, 0.9);
@@ -611,7 +619,7 @@
bbLMain->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));
- irManager->getFlowGraph()->splitNodeAtInstruction(condInst, false, true, NULL);
+ irManager->getFlowGraph()->splitNodeAtInstruction(condInst, true, true, NULL);
Mnemonic mnem = getBaseConditionMnemonic(condInst->getMnemonic());
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?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Wed Dec 27 06:58:37 2006
@@ -1009,7 +1009,7 @@
Opnd * srcOpnd=convert(src, dstType);
appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, (Opnd*)srcOpnd));
appendInsts(irManager.newInst(Mnemonic_NEG, dst));
- appendInsts(irManager.newInstEx(Mnemonic_CMOVL, 1, dst, (Opnd*)srcOpnd));
+ appendInsts(irManager.newInstEx(Mnemonic_CMOVL, 1, dst, dst, (Opnd*)srcOpnd));
break;
}
case NegOp::I8:
@@ -1219,10 +1219,10 @@
if (swapped)
cm=swapConditionMnemonic(cm);
appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
- appendInsts(irManager.newInstEx(getMnemonic(Mnemonic_SETcc, cm), 1, dst));
+ appendInsts(irManager.newInstEx(getMnemonic(Mnemonic_SETcc, cm), 1, dst,dst));
#ifndef _EM64T_
if (((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu))) {
- appendInsts(irManager.newInstEx(Mnemonic_CMOVP,1,dst,irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
+ appendInsts(irManager.newInstEx(Mnemonic_CMOVP,1,dst,dst,irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
}
#endif
return dst;
@@ -1238,7 +1238,7 @@
cmpToEflags(CompareOp::Eq, getCompareOpTypesFromCompareZeroOpTypes(opType), (Opnd*)src, NULL);
appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
- appendInsts(irManager.newInstEx(Mnemonic_CMOVZ, 1, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 1)));
+ appendInsts(irManager.newInstEx(Mnemonic_CMOVZ, 1, dst, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 1)));
return dst;
}
@@ -1251,7 +1251,7 @@
Opnd * dst=irManager.newOpnd(typeManager.getInt32Type());
cmpToEflags(CompareOp::Eq, getCompareOpTypesFromCompareZeroOpTypes(opType), (Opnd*)src, NULL);
appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
- appendInsts(irManager.newInstEx(Mnemonic_CMOVNZ, 1, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 1)));
+ appendInsts(irManager.newInstEx(Mnemonic_CMOVNZ, 1, dst, dst,irManager.newImmOpnd(typeManager.getInt32Type(), 1)));
return dst;
}
@@ -2809,15 +2809,15 @@
Opnd* ecxOpnd = irManager.getRegOpnd(RegName_ECX);
Opnd* memOpnd = irManager.newMemOpnd(opnds[0]->getType(), opnds[0]);
- appendInsts(irManager.newInst(Mnemonic_MOV, eaxOpnd, opnds[1]));
- appendInsts(irManager.newInst(Mnemonic_MOV, ecxOpnd, opnds[2]));
+ appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, eaxOpnd, opnds[1]));
+ appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, ecxOpnd, opnds[2]));
Inst* inst = irManager.newInst(Mnemonic_CMPXCHG, memOpnd, ecxOpnd, eaxOpnd);
inst->setPrefix(InstPrefix_LOCK);
appendInsts(inst);
//save the result
- appendInsts(irManager.newInst(Mnemonic_MOV, dstOpnd, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
+ appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dstOpnd, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
appendInsts(irManager.newInst(Mnemonic_SETZ, dstOpnd));
break;
}
@@ -3138,7 +3138,7 @@
Opnd * dst=irManager.newOpnd(type);
cmpToEflags(CompareOp::Eq, CompareOp::Ref, (Opnd*)instanceOfResult, NULL);
appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
- appendInsts(irManager.newInstEx(Mnemonic_CMOVZ, 1, dst, (Opnd*)obj));
+ appendInsts(irManager.newInstEx(Mnemonic_CMOVZ, 1, dst, dst, (Opnd*)obj));
return dst;
}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp Wed Dec 27 06:58:37 2006
@@ -99,7 +99,7 @@
Log::out() << std::endl;
}
} else {
- assert(0);
+ continue;
}
VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, &md);
uint64 callInstId = (uint64)lastInst->getId();
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?view=diff&rev=490506&r1=490505&r2=490506
==============================================================================
--- 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 Wed Dec 27 06:58:37 2006
@@ -478,11 +478,11 @@
END_MNEMONIC()
#define DEFINE_CMOVcc_MNEMONIC( cc ) \
- BEGIN_MNEMONIC(CMOV##cc, MF_USES_FLAGS|MF_CONDITIONAL, D_U ) \
+ BEGIN_MNEMONIC(CMOV##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU_U ) \
BEGIN_OPCODES() \
- {OpcodeInfo::all, {Size16, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r16, r_m16}, D_U }, \
- {OpcodeInfo::all, {0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r32, r_m32}, D_U }, \
- {OpcodeInfo::em64t, {REX_W, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r64, r_m64}, D_U }, \
+ {OpcodeInfo::all, {Size16, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r16, r_m16}, DU_U }, \
+ {OpcodeInfo::all, {0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r32, r_m32}, DU_U }, \
+ {OpcodeInfo::em64t, {REX_W, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r64, r_m64}, DU_U }, \
END_OPCODES() \
END_MNEMONIC()
@@ -1108,9 +1108,9 @@
END_MNEMONIC()
#define DEFINE_SETcc_MNEMONIC( cc ) \
- BEGIN_MNEMONIC(SET##cc, MF_USES_FLAGS|MF_CONDITIONAL, D) \
+ BEGIN_MNEMONIC(SET##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU) \
BEGIN_OPCODES() \
- {OpcodeInfo::all, {0x0F, 0x90 + ConditionMnemonic_##cc}, {r_m8}, D }, \
+ {OpcodeInfo::all, {0x0F, 0x90 + ConditionMnemonic_##cc}, {r_m8}, DU }, \
END_OPCODES() \
END_MNEMONIC()