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/07/20 11:40:10 UTC
svn commit: r557942 [1/2] - in /harmony/enhanced/drlvm/trunk/vm:
jitrino/config/ia32/ jitrino/src/codegenerator/
jitrino/src/codegenerator/ia32/ jitrino/src/codegenerator/ipf/include/
jitrino/src/optimizer/ jitrino/src/shared/ vmcore/src/jit/
Author: mfursov
Date: Fri Jul 20 02:40:02 2007
New Revision: 557942
URL: http://svn.apache.org/viewvc?view=rev&rev=557942
Log:
Loop unrolling optimization is integrated and added into IA32 configs (HARMONY-3076)
+
HARMONY-4025 and HARMONY-4026 - adding 'unsafe' markup for TC
HARMONY-2533 - minor cleanup of unused and deprecated opcodes in HIR
Added:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/loop_unroll.cpp
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/CodeGenIntfc.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp
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/ipf/include/IpfCodeSelector.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.h
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/Loop.cpp
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/codelowerer.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/reassociate.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/jit_runtime_support.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=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf Fri Jul 20 02:40:02 2007
@@ -53,7 +53,7 @@
-XX:jit.CD_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XX:jit.CD_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
+-XX:jit.CD_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof,markglobals
-XX:jit.CD_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XX:jit.CD_OPT.path.dce1=cg_dce
-XX:jit.CD_OPT.path.dce2=cg_dce
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=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf Fri Jul 20 02:40:02 2007
@@ -24,7 +24,7 @@
-XX:jit.CS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XX:jit.CS_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,escape,dce,uce,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
+-XX:jit.CS_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,escape,dce,uce,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof,markglobals
-XX:jit.CS_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XX:jit.CS_OPT.path.dce1=cg_dce
-XX:jit.CS_OPT.path.dce2=cg_dce
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=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Fri Jul 20 02:40:02 2007
@@ -71,7 +71,7 @@
-XX:jit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,lazyexc,so2-,simplify,dce,uce,escape,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
+-XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,lazyexc,so2-,simplify,dce,uce,escape,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
-XX:jit.SD2_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XX:jit.SD2_OPT.path.dce1=cg_dce
-XX:jit.SD2_OPT.path.dce2=cg_dce
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=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf Fri Jul 20 02:40:02 2007
@@ -24,7 +24,7 @@
-XX:jit.SS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XX:jit.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,classic_abcd,dce,uce,gcm,dessa,statprof,markglobals
+-XX:jit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,statprof,hvn,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,statprof,markglobals
-XX:jit.SS_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
-XX:jit.SS_OPT.path.dce1=cg_dce
-XX:jit.SS_OPT.path.dce2=cg_dce
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Fri Jul 20 02:40:02 2007
@@ -190,7 +190,6 @@
virtual CG_OpndHandle* sub(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0;
virtual CG_OpndHandle* subRef(RefArithmeticOp::Types,CG_OpndHandle* refSrc, CG_OpndHandle* intSrc) = 0;
virtual CG_OpndHandle* diffRef(bool ovf, CG_OpndHandle* ref1,CG_OpndHandle* ref2) = 0;
- virtual CG_OpndHandle* scaledDiffRef(CG_OpndHandle*, CG_OpndHandle*, Type*, Type*) = 0;
virtual CG_OpndHandle* mul(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0;
virtual CG_OpndHandle* tau_div(DivOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2,
CG_OpndHandle *tauSrc1NonZero) = 0;
@@ -222,7 +221,6 @@
// END PRED DEPRECATED
// result is a predicate
- virtual CG_OpndHandle* pred_cmp(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0;
virtual CG_OpndHandle* pred_czero(CompareZeroOp::Types,CG_OpndHandle* src) = 0;
virtual CG_OpndHandle* pred_cnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0;
@@ -231,8 +229,6 @@
virtual void bzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0;
virtual void bnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0;
// END PRED DEPRECATED
-
- virtual void pred_btrue(CG_OpndHandle* src1) = 0;
virtual void jump() = 0;
virtual void tableSwitch(CG_OpndHandle* src, uint32 nTargets) = 0;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp Fri Jul 20 02:40:02 2007
@@ -220,7 +220,7 @@
// CFG for inlining
Node* bbpCFGController = bbp.getBBPSubCFGController(originalTargetId,sourceDispatchId);
if (bbpCFGController) { // just retarget the edge
- fg->replaceEdgeTarget(edge, bbpCFGController);
+ fg->replaceEdgeTarget(edge, bbpCFGController, true);
} else { // we need a new bbpCFG
ControlFlowGraph* bbpCFG = bbp.createBBPSubCFG(*irManager, tlsBaseReg);
@@ -293,7 +293,7 @@
Edge* other = otherEdges[otherIdx];
if (other->getTargetNode() != loopHeader)
break;
- fg->replaceEdgeTarget(other, bbpFlagAddrBlock);
+ fg->replaceEdgeTarget(other, bbpFlagAddrBlock, true);
}
assert(loopHeader->isBlockNode());
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=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Fri Jul 20 02:40:02 2007
@@ -671,49 +671,6 @@
return sub(ArithmeticOp::I4, ref1, ref2);
}
-//_______________________________________________________________________________________________________________
-// Subtract reference from reference and scale down by element type.
-
-CG_OpndHandle* InstCodeSelector::scaledDiffRef(CG_OpndHandle* ref1,
- CG_OpndHandle* ref2,
- Type* type1,
- Type* type2)
-{
- Opnd* r1 = (Opnd*)ref1;
- Type * elemRefType = r1->getType();
-
-#ifdef _DEBUG
- Opnd* r2 = (Opnd*)ref2;
- assert( elemRefType->isManagedPtr() && elemRefType==r2->getType() );
-#endif
- Type * elemType = ((PtrType *)elemRefType)->getPointedToType();
-
- uint32 size = getByteSize(irManager.getTypeSize(elemType));
- assert(size > 0);
- uint32 shift;
- switch(size) {
- case 1:
- shift = 0;
- break;
- case 2:
- shift = 1;
- break;
- case 4:
- shift = 2;
- break;
- default:
- assert(0);
- return NULL;
- }
-
- Opnd *dstOpnd = (Opnd *)diffRef(false, ref1, ref2);
-
- if(shift == 0) {
- return dstOpnd;
- } else {
- return shr(IntegerOp::I4,dstOpnd,irManager.newImmOpnd(typeManager.getUInt8Type(),shift));
- }
-}
//_______________________________________________________________________________________________________________
// Multiply numeric values
@@ -3139,13 +3096,6 @@
return getTauUnsafe();
}
-//_______________________________________________________________________________________________________________
-// result is a predicate
-CG_OpndHandle* InstCodeSelector::pred_cmp(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2)
-{
- ICS_ASSERT(0);
- return 0;
-}
//_______________________________________________________________________________________________________________
CG_OpndHandle* InstCodeSelector::pred_czero(CompareZeroOp::Types,CG_OpndHandle* src)
@@ -3161,11 +3111,6 @@
return 0;
}
-//_______________________________________________________________________________________________________________
-void InstCodeSelector::pred_btrue(CG_OpndHandle* src1)
-{
- ICS_ASSERT(0);
-}
// END new tau instructions
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h Fri Jul 20 02:40:02 2007
@@ -65,10 +65,8 @@
virtual CG_OpndHandle* tauSafe(); // operation is always safe
// result is a predicate
- virtual CG_OpndHandle* pred_cmp(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
virtual CG_OpndHandle* pred_czero(CompareZeroOp::Types,CG_OpndHandle* src);
virtual CG_OpndHandle* pred_cnzero(CompareZeroOp::Types,CG_OpndHandle* src);
- virtual void pred_btrue(CG_OpndHandle* src1);
// END new tau instructions
//
@@ -80,7 +78,6 @@
CG_OpndHandle* sub(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
CG_OpndHandle* subRef(RefArithmeticOp::Types,CG_OpndHandle* refSrc, CG_OpndHandle* intSrc);
CG_OpndHandle* diffRef(bool ovf, CG_OpndHandle* ref1,CG_OpndHandle* ref2);
- CG_OpndHandle* scaledDiffRef(CG_OpndHandle* ref1,CG_OpndHandle* ref2, Type*, Type*);
CG_OpndHandle* mul(ArithmeticOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
CG_OpndHandle* tau_div(DivOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2,CG_OpndHandle *tauSrc1NonZero);
CG_OpndHandle* tau_rem(DivOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2,CG_OpndHandle *tauSrc2NonZero);
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h Fri Jul 20 02:40:02 2007
@@ -126,7 +126,6 @@
CG_OpndHandle *addRef(RefArithmeticOp::Types, CG_OpndHandle*, CG_OpndHandle*);
CG_OpndHandle *subRef(RefArithmeticOp::Types, CG_OpndHandle*, CG_OpndHandle*);
CG_OpndHandle *diffRef(bool, CG_OpndHandle*, CG_OpndHandle*);
- CG_OpndHandle *scaledDiffRef(CG_OpndHandle*,CG_OpndHandle*, Type*, Type*);
CG_OpndHandle *tau_div(DivOp::Types, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*);
CG_OpndHandle *tau_rem(DivOp::Types, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*);
@@ -278,7 +277,6 @@
CG_OpndHandle *tau_callvirt(uint32, CG_OpndHandle**, Type*, MethodDesc*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("tau_callvirt") }
CG_OpndHandle *select(CompareOp::Types, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("select") }
CG_OpndHandle *cmp3(CompareOp::Operators,CompareOp::Types, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("cmp3") }
- CG_OpndHandle *pred_cmp(CompareOp::Operators,CompareOp::Types, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("pred_cmp") }
CG_OpndHandle *tau_optimisticBalancedMonitorEnter(CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("tau_optimisticBalancedMonitorEnter") }
CG_OpndHandle *addOffsetPlusHeapbase(Type*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("addOffsetPlusHeapbase") }
CG_OpndHandle *tau_ldField(Type*, CG_OpndHandle*, Type::Tag, FieldDesc*, bool, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_C("tau_ldField") }
@@ -291,7 +289,6 @@
void initValueObj(Type*, CG_OpndHandle*) { NOT_IMPLEMENTED_V("initValueObj") }
void copyValueObj(Type*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_V("copyValueObj") }
void prefetch(CG_OpndHandle*, uint32, int) { NOT_IMPLEMENTED_V("prefetch") }
- void pred_btrue(CG_OpndHandle*) { NOT_IMPLEMENTED_V("pred_btrue") }
void jump() { NOT_IMPLEMENTED_V("jump") }
void throwLazyException(uint32, CG_OpndHandle**, MethodDesc*) { NOT_IMPLEMENTED_V("throwLazyException") }
void tau_stStatic(CG_OpndHandle*, FieldDesc*, Type::Tag, bool, CG_OpndHandle*) { NOT_IMPLEMENTED_V("tau_stStatic") }
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Fri Jul 20 02:40:02 2007
@@ -1285,16 +1285,6 @@
getCGInst(inst->getSrc(1)));
}
break;
- // subtract 2 reference to yield difference as # of elements
- case Op_ScaledDiffRef:
- {
- assert(inst->getNumSrcOperands() == 2);
- cgInst = instructionCallback.scaledDiffRef(getCGInst(inst->getSrc(0)),
- getCGInst(inst->getSrc(1)),
- (Type *)inst->getSrc(0)->getType(),
- (Type *)inst->getSrc(1)->getType());
- }
- break;
case Op_UncompressRef:
{
assert(inst->getNumSrcOperands() == 1);
@@ -1996,35 +1986,6 @@
case Op_TauIsNonNull:
{
cgInst = instructionCallback.tauPoint();
- }
- break;
- case Op_PredCmp:
- {
- if (inst->getNumSrcOperands() == 2) {
- // binary comparison
- CompareOp::Operators cmpOp = mapToComparisonOp(inst);
- CompareOp::Types opType = mapToCompareOpType(inst);
- cgInst = instructionCallback.pred_cmp(cmpOp, opType,
- getCGInst(inst->getSrc(0)),
- getCGInst(inst->getSrc(1)));
- } else {
- assert(inst->getNumSrcOperands() == 1);
- // unary comparison against zero
- if (inst->getComparisonModifier() == Cmp_Zero) {
- cgInst = instructionCallback.pred_czero(mapToCompareZeroOpType(inst),
- getCGInst(inst->getSrc(0)));
- } else {
- // Nonzero
- cgInst = instructionCallback.pred_cnzero(mapToCompareZeroOpType(inst),
- getCGInst(inst->getSrc(0)));
- }
- }
- }
- break;
- case Op_PredBranch:
- {
- assert(inst->getNumSrcOperands() == 1);
- instructionCallback.pred_btrue(getCGInst(inst->getSrc(0)));
}
break;
default:
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp Fri Jul 20 02:40:02 2007
@@ -41,30 +41,6 @@
namespace Jitrino {
-class NodeRenameTable : public HashTable<Node,Node> {
-public:
- typedef HashTableIter<Node, Node> Iter;
-
- NodeRenameTable(MemoryManager& mm,uint32 size) :
- HashTable<Node,Node>(mm,size) {}
- Node *getMapping(Node *node) {
- return (Node*)lookup(node);
- }
- void setMapping(Node *node, Node *to) {
- insert(node,to);
- }
-
-protected:
- virtual bool keyEquals(Node* key1,Node* key2) const {
- return key1 == key2;
- }
- virtual uint32 getKeyHashCode(Node* key) const {
- // return hash of address bits
- return ((uint32)(((POINTER_SIZE_INT)key) >> sizeof(void*)));
- }
-};
-
-
void
FlowGraph::foldBranch(ControlFlowGraph& fg, BranchInst* br, bool isTaken)
{
@@ -127,7 +103,7 @@
Node* copy = duplicateRegion(irm, tail, region, defUses);
// Specialize for pred.
- Edge* edge = fg.replaceEdgeTarget(pred->findTargetEdge(tail), copy);
+ Edge* edge = fg.replaceEdgeTarget(pred->findTargetEdge(tail), copy, true);
copy->setExecCount(pred->getExecCount()*edge->getEdgeProb());
if(copy->getExecCount() < tail->getExecCount()) {
tail->setExecCount(tail->getExecCount() - copy->getExecCount());
@@ -260,8 +236,8 @@
Node* succ = node->getUnconditionalEdge()->getTargetNode();
Edge* succEdge = node->findTargetEdge(succ);
stBlock->setExecCount(node->getExecCount()*succEdge->getEdgeProb());
- fg.replaceEdgeTarget(succEdge, stBlock);
- fg.replaceEdgeTarget(newNode->findTargetEdge(succ), stBlock);
+ fg.replaceEdgeTarget(succEdge, stBlock, true);
+ fg.replaceEdgeTarget(newNode->findTargetEdge(succ), stBlock, true);
fg.addEdge(stBlock, succ)->setEdgeProb(1.0);
defUses->addUses(stVar);
nodesInRegion->resize(stBlock->getId()+1);
@@ -325,7 +301,7 @@
if(succ != entry && nodesInRegion.getBit(succ->getId())) {
Node* newSucc = _duplicateRegion(irm, succ, entry, nodesInRegion, defUses, nodeRenameTable, opndRenameTable);
assert(newSucc != NULL);
- fg.replaceEdgeTarget(newNode->findTargetEdge(succ), newSucc);
+ fg.replaceEdgeTarget(newNode->findTargetEdge(succ), newSucc, true);
}
}
@@ -333,7 +309,7 @@
}
-static Node* _duplicateRegion(IRManager& irm, Node* entry, StlBitVector& nodesInRegion, DefUseBuilder& defUses, NodeRenameTable& nodeRenameTable, OpndRenameTable& opndRenameTable, double newEntryFreq) {
+Node* FlowGraph::duplicateRegion(IRManager& irm, Node* entry, StlBitVector& nodesInRegion, DefUseBuilder& defUses, NodeRenameTable& nodeRenameTable, OpndRenameTable& opndRenameTable, double newEntryFreq) {
Node* newEntry = _duplicateRegion(irm, entry, entry, nodesInRegion, &defUses, &nodeRenameTable, &opndRenameTable);
if(newEntryFreq == 0) {
return newEntry;
@@ -356,7 +332,7 @@
// prepare the hashtable for the operand rename translation
OpndRenameTable *opndRenameTable = new (dupMemManager) OpndRenameTable(dupMemManager,10);
NodeRenameTable *nodeRenameTable = new (dupMemManager) NodeRenameTable(dupMemManager,10);
- return _duplicateRegion(irm, entry, nodesInRegion, defUses, *nodeRenameTable, *opndRenameTable, newEntryFreq);
+ return duplicateRegion(irm, entry, nodesInRegion, defUses, *nodeRenameTable, *opndRenameTable, newEntryFreq);
}
void FlowGraph::renameOperandsInNode(Node *node, OpndRenameTable *renameTable) {
@@ -614,7 +590,7 @@
OpndRenameTable *opndRenameTable = new (inlineManager) OpndRenameTable(inlineManager,10);
NodeRenameTable *nodeRenameTable = new (inlineManager) NodeRenameTable(inlineManager,10);
- Node* newEntry = _duplicateRegion(*irManager, entryJSR, nodesInJSR, defUses, *nodeRenameTable, *opndRenameTable, 0);
+ Node* newEntry = FlowGraph::duplicateRegion(*irManager, entryJSR, nodesInJSR, defUses, *nodeRenameTable, *opndRenameTable, 0);
fg.removeEdge(block,retTarget);
fg.removeEdge(block,entryJSR);
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.h?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.h Fri Jul 20 02:40:02 2007
@@ -69,6 +69,8 @@
static Node* tailDuplicate(IRManager& irm, Node* pred, Node* tail, DefUseBuilder& defUses);
static Node* duplicateRegion(IRManager& irm, Node* entry, StlBitVector& nodesInRegion, DefUseBuilder& defUses, double newEntryFreq=0.0);
+ static Node* duplicateRegion(IRManager& irm, Node* entry, StlBitVector& nodesInRegion, DefUseBuilder& defUses, NodeRenameTable& nodeRenameTable, OpndRenameTable& opndRenameTable, double newEntryFreq = 0.0);
+
static void renameOperandsInNode(Node *node, OpndRenameTable *renameTable);
@@ -83,6 +85,21 @@
static void printDotFile(ControlFlowGraph& cfg, MethodDesc& methodDesc,const char *suffix);
+};
+
+class NodeRenameTable : public HashTable<Node,Node> {
+public:
+ typedef HashTableIter<Node, Node> Iter;
+
+ NodeRenameTable(MemoryManager& mm,uint32 size):HashTable<Node,Node>(mm,size) {}
+ Node *getMapping(Node *node) { return (Node*)lookup(node); }
+ void setMapping(Node *node, Node *to) { insert(node,to); }
+
+protected:
+ virtual bool keyEquals(Node* key1,Node* key2) const { return key1 == key2; }
+
+ // return hash of address bits
+ virtual uint32 getKeyHashCode(Node* key) const { return ((uint32)(((POINTER_SIZE_INT)key) >> sizeof(void*))); }
};
} //namespace Jitrino
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp Fri Jul 20 02:40:02 2007
@@ -1061,34 +1061,6 @@
return dst;
}
-// Comparison with predicate result
-Opnd*
-IRBuilder::genPredCmp(Type* dstType,
- Type::Tag instType, // source type for inst
- ComparisonModifier mod,
- Opnd* src1,
- Opnd* src2) {
- src1 = propagateCopy(src1);
- src2 = propagateCopy(src2);
-
- Operation operation(Op_PredCmp, instType, mod);
- uint32 hashcode = operation.encodeForHashing();
- Opnd* dst = lookupHash(hashcode, src1, src2);
- if (dst) return dst;
-
- if (irBuilderFlags.doSimplify) {
- dst = simplifier->simplifyPredCmp(dstType, instType, mod, src1, src2);
- }
- if (!dst) {
- // result of comparison is always a 32-bit int
- dst = createOpnd(dstType);
- Inst *i = instFactory->makePredCmp(mod, instType, dst, src1, src2);
- appendInst(i);
- }
- insertHash(hashcode, src1, src2, dst->getInst());
- return dst;
-}
-
// Comparison
Opnd*
IRBuilder::genCmp(Type* dstType,
@@ -1189,19 +1161,6 @@
appendInst(instFactory->makeBranch(mod, instType, src, label));
}
-void
-IRBuilder::genPredBranch(LabelInst* label,
- Opnd* src) {
- src = propagateCopy(src);
- if (irBuilderFlags.doSimplify) {
- if (simplifier->simplifyPredBranch(label, src)) {
- // simplified branch was emitted;
- return;
- }
- }
- appendInst(instFactory->makePredBranch(src, label));
-}
-
void
IRBuilder::genJump(LabelInst* label) {
@@ -2360,18 +2319,6 @@
return dst;
}
-Opnd*
-IRBuilder::genScaledDiffRef(Opnd* src1, Opnd* src2) {
- src1 = propagateCopy(src1);
- src2 = propagateCopy(src2);
- Opnd* dst = lookupHash(Op_ScaledDiffRef, src1, src2);
- if (dst) return dst;
-
- dst = createOpnd(typeManager->getInt32Type());
- appendInst(instFactory->makeScaledDiffRef(dst, src1, src2));
- insertHash(Op_ScaledDiffRef, src1, src2, dst->getInst());
- return dst;
-}
Opnd*
IRBuilder::genUncompressRef(Opnd *compref)
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h Fri Jul 20 02:40:02 2007
@@ -376,7 +376,6 @@
Opnd* genPrefetch(Opnd* base, Opnd *offset, Opnd *hints);
Opnd* genCopy(Opnd* src);
Opnd* genTauPi(Opnd* src, Opnd *tau, PiCondition *cond);
- Opnd* genScaledDiffRef(Opnd* src1, Opnd* src2);
// compressed reference instructions
Opnd* genLdFieldOffset(FieldDesc* fieldDesc);
Opnd* genLdArrayBaseOffset(Type *elemType);
@@ -396,12 +395,6 @@
private:
void readFlagsFromCommandLine(SessionAction* argSource, const char* argPrefix);
-
- // RECURSIVE GEN
- // additional gen methods used only recursively
- Opnd* genPredCmp(Type *dstType, Type::Tag instType, ComparisonModifier mod,
- Opnd *src1, Opnd *src2);
- void genPredBranch(LabelInst* label, Opnd *src);
private:
//
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Fri Jul 20 02:40:02 2007
@@ -2227,12 +2227,6 @@
}
//
-Inst* InstFactory::makeScaledDiffRef(Opnd* dst, Opnd* src1, Opnd *src2) {
- return makeInst(Op_ScaledDiffRef, Modifier(), dst->getType()->tag, dst,
- src1, src2);
-}
-
-//
Inst* InstFactory::makeUncompressRef(Opnd* dst, Opnd* compref)
{
return makeInst(Op_UncompressRef, Modifier(), dst->getType()->tag,
@@ -2664,14 +2658,6 @@
Type::Tau, dst, src);
}
-Inst* InstFactory::makePredCmp(ComparisonModifier mod, Type::Tag type, Opnd *dst,
- Opnd *src1, Opnd *src2) {
- return makeInst(Op_PredCmp, mod, type, dst, src1, src2);
-}
-
-Inst* InstFactory::makePredBranch(Opnd *predSrc, LabelInst* labelInst) {
- return makeBranchInst(Op_PredBranch, predSrc, labelInst);
-}
//-----------------------------------------------------------------------------
// InstOptimizer methods
@@ -2749,7 +2735,6 @@
case Op_TauArrayLen: return caseTauArrayLen(inst);
case Op_LdArrayBaseAddr: return caseLdArrayBaseAddr(inst);
case Op_AddScaledIndex: return caseAddScaledIndex(inst);
- case Op_ScaledDiffRef: return caseScaledDiffRef(inst);
case Op_StVar: return caseStVar(inst);
case Op_TauStInd: return caseTauStInd(inst);
case Op_TauStField: return caseTauStField(inst);
@@ -2826,8 +2811,6 @@
case Op_TauHasType: return caseTauHasType(inst->asTypeInst());
case Op_TauHasExactType: return caseTauHasExactType(inst->asTypeInst());
case Op_TauIsNonNull: return caseTauIsNonNull(inst);
- case Op_PredCmp: return casePredCmp(inst);
- case Op_PredBranch: return casePredBranch(inst->asBranchInst());
default:
::std::cerr << "Unknown opcode! " << inst->getOpcode() << " : "
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h Fri Jul 20 02:40:02 2007
@@ -1193,7 +1193,6 @@
Opnd *tauBaseIsArray);
Inst* makeLdArrayBaseAddr(Type* type, Opnd* dst, Opnd* array);
Inst* makeAddScaledIndex(Opnd* dst, Opnd* base, Opnd* index);
- Inst* makeScaledDiffRef(Opnd* dst, Opnd* src1, Opnd *src2);
Inst* makeStVar(VarOpnd* var, Opnd* src);
Inst* makeStVar(SsaVarOpnd* var, Opnd* src);
Inst* makeTauStInd(Modifier, Type::Tag, Opnd* src, Opnd* ptr, Opnd *tauNonNullBase,
@@ -1297,9 +1296,7 @@
Inst* makeTauHasType(Opnd *taudst, Opnd* src, Type* type);
Inst* makeTauHasExactType(Opnd *taudst, Opnd* src, Type* type);
Inst* makeTauIsNonNull(Opnd *taudst, Opnd* src);
- Inst* makePredCmp(ComparisonModifier mod, Type::Tag type, Opnd* dst, Opnd* src1, Opnd* src2);
- Inst* makePredBranch(Opnd *predSrc, LabelInst* labelInst);
-
+
//
//
//
@@ -1776,9 +1773,6 @@
caseAddScaledIndex(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
- caseScaledDiffRef(Inst* inst)=0;// {return caseDefault(inst);}
-
- virtual Inst*
caseStVar(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
@@ -2031,12 +2025,6 @@
virtual Inst*
caseTauIsNonNull(Inst* inst)=0;// {return caseDefault(inst);}
-
- virtual Inst*
- casePredCmp(Inst* inst)=0;// {return caseDefault(inst);}
-
- virtual Inst*
- casePredBranch(BranchInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseDefault(Inst* inst)=0;// {return NULL;}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Loop.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Loop.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Loop.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Loop.cpp Fri Jul 20 02:40:02 2007
@@ -465,8 +465,7 @@
//
Opcode op1 = ((Inst*)tail->getLastInst())->getOpcode();
Opcode op2 = ((Inst*)header->getLastInst())->getOpcode();
- if(flags.invert && (op1 != Op_Branch) && (op1 != Op_PredBranch)
- && (op2 != Op_Branch) && (op2 != Op_PredBranch)) {
+ if(flags.invert && (op1 != Op_Branch) && (op2 != Op_Branch)) {
if(isInversionCandidate(originalInvertedHeader, header, nodesInLoop, next, exit)) {
preheader = FlowGraph::tailDuplicate(irManager, preheader, header, defUses);
tail = header;
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp Fri Jul 20 02:40:02 2007
@@ -147,7 +147,6 @@
{ Op_TauArrayLen, false, MB::CSEable, MK::None, "arraylen ", "arraylen %0 ((%1,%2)) -) %l", },
{ Op_LdArrayBaseAddr, false, MB::CSEable, MK::None, "ldbase", "ldbase %s -) %l", }, // load the base (zero'th element) address of array
{ Op_AddScaledIndex, false, MB::Movable, MK::None, "addindex", "addindex %s -) %l", }, // Add a scaled index to an array element address
- { Op_ScaledDiffRef, false, MB::Movable, MK::None, "diffref", "diffref %s -) %l", }, // Subtract two references to yield a difference in number of objects
{ Op_StVar, true, MB::None, MK::None, "stvar ", "stvar %0 -) %l", },
{ Op_TauStInd, true, MB::StoreOrSync, MK::Store_AutoCompress, "stind", "stind%m:%t %0 ((%2,%3,%4)) -) [%1]", },
{ Op_TauStField, true, MB::StoreOrSync, MK::Store_AutoCompress, "stfld", "stfld%m:%t %0 ((%2,%3)) -) [%1.%d]", },
@@ -237,10 +236,6 @@
{ Op_TauHasType, false, MB::Movable, MK::None, "tauhastype ", "tauhastype %0,%d -) %l", }, // temporary declaration that source is of given type
{ Op_TauHasExactType, false, MB::CSEable, MK::None, "tauexacttype ", "tauexacttype %0,%d -) %l", }, // temporary declaration that source is exactly of given type
{ Op_TauIsNonNull, true, MB::CSEable, MK::None, "tauisnonnull ", "tauisnonnull %0 -) %l", }, // temporary declaration that source null
-
- { Op_PredCmp, false, MB::Movable, MK::Comparison, "predcmp", "pc%m:%t %s -) %l", },
- { Op_PredBranch, true, MB::ControlFlow, MK::None, "predbr", "if %s goto %l", },
-
};
unsigned short Modifier::encode(Opcode opcode, uint32 numbits) const
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Fri Jul 20 02:40:02 2007
@@ -359,7 +359,6 @@
Op_TauArrayLen,
Op_LdArrayBaseAddr, // load the base (zero'th element) address of array
Op_AddScaledIndex, // Add a scaled index to an array element address
- Op_ScaledDiffRef, // Subtract two references to yield a difference in number of objects
// Store instructions
Op_StVar,
Op_TauStInd, // StoreModifier
@@ -471,9 +470,6 @@
Op_TauHasType,
Op_TauHasExactType,
Op_TauIsNonNull,
-
- Op_PredCmp,
- Op_PredBranch,
// prefixes: unaligned, volatile, tail,
NumOpcodes,
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h Fri Jul 20 02:40:02 2007
@@ -197,8 +197,6 @@
Inst* caseAddScaledIndex(Inst* inst) {return caseDefault(inst);}
- Inst* caseScaledDiffRef(Inst* inst) {return caseDefault(inst);}
-
Inst* caseStVar(Inst* inst) {return caseDefault(inst);}
Inst* caseTauStInd(Inst* inst) {return caseDefault(inst);}
@@ -360,10 +358,6 @@
Inst* caseTauHasExactType(TypeInst* inst) {return caseDefault(inst);}
Inst* caseTauIsNonNull(Inst* inst) {return caseDefault(inst);}
-
- Inst* casePredCmp(Inst* inst) {return caseDefault(inst);}
-
- Inst* casePredBranch(BranchInst* inst) {return caseDefault(inst);}
IRManager& _irm;
bool _preserveSsa;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp Fri Jul 20 02:40:02 2007
@@ -516,7 +516,6 @@
}
Inst* caseLdArrayBaseAddr(Inst* inst) { return hashInst(inst); }
Inst* caseAddScaledIndex(Inst* inst) { return hashInst(inst); }
- Inst* caseScaledDiffRef(Inst* inst) { return hashInst(inst); }
// Stores:
Inst* caseStVar(Inst* inst) { return caseDefault(inst); }
@@ -992,12 +991,6 @@
return hashInst(inst);
}
- virtual Inst*
- casePredCmp(Inst* inst) { return hashInst(inst); }
-
- virtual Inst*
- casePredBranch(BranchInst* inst) { return lookupInst(inst); }
-
// default
Inst* caseDefault(Inst* inst) { return inst; }
private:
@@ -1355,7 +1348,6 @@
void addBranchConditions(DominatorNode* domNode);
private:
void addInfoFromBranch(Node* targetNode, BranchInst *branchi, bool isTrueEdge);
- void addInfoFromPredBranch(Node* targetNode, BranchInst *branchi, bool isTrueEdge);
void addInfoFromBranchCompare(Node* targetNode,
ComparisonModifier mod,
Type::Tag comparisonType,
@@ -1548,11 +1540,7 @@
assert(branchi1 != NULL);
BranchInst* branchi = branchi1->asBranchInst();
if (branchi) {
- if (branchi->getOpcode() == Op_PredBranch) {
- addInfoFromPredBranch(block, branchi, taken);
- } else if (branchi->getOpcode() != Op_Switch || !taken) {
- addInfoFromBranch(block, branchi, taken);
- }
+ addInfoFromBranch(block, branchi, taken);
} else {
// default edge of switch, skip it
}
@@ -1972,35 +1960,6 @@
(numSrcs==2 ? branchi->getSrc(1) : 0));
}
-void InstValueNumberer::addInfoFromPredBranch(Node* targetNode, BranchInst *branchi,
- bool isTrueEdge)
-{
- const OptimizerFlags& optimizerFlags = irManager.getOptimizerFlags();
- if (!optimizerFlags.elim_checks) return;
-
- if (Log::isEnabled()) {
- Log::out() << "addInfoFromPredBranch " << (isTrueEdge ? "taken " : "notTaken ");
- branchi->print(Log::out());
- Log::out() << ::std::endl;
- }
-
- Opnd *srcOp = branchi->getSrc(0);
- Inst *pcmpi = srcOp->getInst();
- if (pcmpi->getOpcode() != Op_PredCmp) {
- return;
- }
-
- pcmpi->getComparisonModifier();
- uint32 numSrcs = pcmpi->getNumSrcOperands();
- addInfoFromBranchCompare(targetNode,
- pcmpi->getComparisonModifier(),
- pcmpi->getType(),
- isTrueEdge,
- pcmpi->getNumSrcOperands(),
- pcmpi->getSrc(0),
- (numSrcs==2 ? branchi->getSrc(1) : 0));
-}
-
void InstValueNumberer::recordHasTypeTau(Opnd *opnd,
Type *type,
Inst *tauHasTypeInst)
@@ -2063,8 +2022,6 @@
Operation negCmpOperation(Op_Cmp, comparisonType, negModhere);
Operation branchOperation(Op_Branch, comparisonType, modhere);
Operation negBranchOperation(Op_Branch, comparisonType, negModhere);
- Operation predCmpOperation(Op_PredCmp, comparisonType, modhere);
- Operation negPredCmpOperation(Op_PredCmp, comparisonType, negModhere);
switch (numSrcOperands) {
case 1:
{
@@ -2083,14 +2040,10 @@
Log::out() << "cmpOperation.hashcode() == "
<< (int) cmpOperation.encodeForHashing()
<< ::std::endl;
- Log::out() << "predCmpOperation.hashcode() == "
- << (int) predCmpOperation.encodeForHashing()
- << ::std::endl;
}
Inst *tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge, getKey(branchOperation, src0->getId()));
setHashToInst(tauEdge, getKey(cmpOperation, src0->getId()));
- setHashToInst(tauEdge, getKey(predCmpOperation, src0->getId()));
if (Log::isEnabled()) {
Log::out() << "adding false comparison: ";
@@ -2107,14 +2060,10 @@
Log::out() << "negCmpOperation.hashcode() == "
<< (int) negCmpOperation.encodeForHashing()
<< ::std::endl;
- Log::out() << "negPredCmpOperation.hashcode() == "
- << (int) negPredCmpOperation.encodeForHashing()
- << ::std::endl;
}
setHashToInst(getTauUnsafe(), getKey(negBranchOperation, src0->getId()));
setHashToInst(getTauUnsafe(), getKey(negCmpOperation, src0->getId()));
- setHashToInst(getTauUnsafe(), getKey(negPredCmpOperation, src0->getId()));
}
break;
case 2:
@@ -2146,8 +2095,6 @@
getKey(branchOperation, posSrc0->getId(), posSrc1->getId()));
setHashToInst(tauEdge,
getKey(cmpOperation, posSrc0->getId(), posSrc1->getId()));
- setHashToInst(tauEdge,
- getKey(predCmpOperation, posSrc0->getId(), posSrc1->getId()));
if (Log::isEnabled()) {
Log::out() << "adding false comparison: ";
@@ -2172,8 +2119,6 @@
setHashToInst(getTauUnsafe(),
getKey(negCmpOperation, negSrc0->getId(),
negSrc1->getId()));
- setHashToInst(getTauUnsafe(),
- getKey(negPredCmpOperation, src0->getId(), src1->getId()));
}
break;
default:
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp Fri Jul 20 02:40:02 2007
@@ -944,7 +944,6 @@
case Op_TauArrayLen:
case Op_LdArrayBaseAddr:
case Op_AddScaledIndex:
- case Op_ScaledDiffRef:
return true;
case Op_StVar:
return false;
@@ -1096,9 +1095,6 @@
case Op_TauHasType:
case Op_TauHasExactType:
case Op_TauIsNonNull:
- return false;
- case Op_PredCmp:
- case Op_PredBranch:
return false;
default:
return true;
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/loop_unroll.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/loop_unroll.cpp?view=auto&rev=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/loop_unroll.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/loop_unroll.cpp Fri Jul 20 02:40:02 2007
@@ -0,0 +1,748 @@
+/*
+* 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 Intel, Mikhail Y. Fursov
+*/
+
+#include "escapeanalyzer.h"
+#include "Log.h"
+#include "Inst.h"
+#include "Dominator.h"
+#include "irmanager.h"
+#include "LoopTree.h"
+#include "FlowGraph.h"
+#include "ssa/SSA.h"
+#include "Opnd.h"
+
+namespace Jitrino {
+
+//TODOs:
+// 1) support parents loop unrolling -> easy
+// 2) support complete loop elimination if limit is const -> easy (or do not unroll at all)
+// 3) support more branch types (Cmp_Eq, Cmp_NotEq, Cmp_Zero..)
+// 4) support loop unrolling for counters with long, float and double types
+
+class UnrollFlags {
+public:
+ UnrollFlags()
+ : smallLoopSize(0), smallLoopHotness(0), smallLoopUnrollCount(0),
+ mediumLoopSize(0), mediumLoopHotness(0), mediumLoopUnrollCount(0),
+ largeLoopSize(0), largeLoopHotness(0), largeLoopUnrollCount(0)
+ {}
+
+ int smallLoopSize;
+ int smallLoopHotness;
+ int smallLoopUnrollCount;
+
+ int mediumLoopSize;
+ int mediumLoopHotness;
+ int mediumLoopUnrollCount;
+
+ int largeLoopSize;
+ int largeLoopHotness;
+ int largeLoopUnrollCount;
+
+ bool unrollParentLoops;
+};
+
+class LoopUnrollAction : public Action {
+public:
+ void init();
+ const UnrollFlags& getFlags() {return flags;}
+protected:
+ UnrollFlags flags;
+};
+
+DEFINE_SESSION_ACTION_WITH_ACTION(LoopUnrollPass, LoopUnrollAction, unroll, "Loop Unrolling")
+
+
+//loop structure is
+//loop {
+// BodyA
+// check
+// BodyB
+//}
+// all paths from bodyA to bodyB must go through the 'check'
+//
+class LoopUnrollInfo {
+public:
+ LoopUnrollInfo()
+ : header(NULL), branchInst(NULL), branchTargetIsExit(false),
+ branchLimitOpndPos(0), increment(0), unrollCount(0), doUnroll(false)
+ {}
+
+ Node* header;
+ BranchInst* branchInst;
+ bool branchTargetIsExit;
+ int branchLimitOpndPos;
+
+ int increment;
+ int unrollCount;
+ bool doUnroll;
+
+
+ Opnd* getLimitOpnd() const {return branchLimitOpndPos==0?branchInst->getSrc(0) : branchInst->getSrc(1);}
+ Opnd* getIdxOpnd() const {return branchLimitOpndPos==0?branchInst->getSrc(1) : branchInst->getSrc(0);}
+
+ void print(std::ostream& out) const {
+ out<<"LoopHead=";FlowGraph::printLabel(out, header);
+ out<<" inst=I"<<branchInst->getId();
+ out<<" idx-opndId="<<getIdxOpnd()->getId();
+ out<<" limit-opndId="<<getLimitOpnd()->getId();
+ out<<" increment="<<increment;
+ out<<" unroll_count="<<unrollCount;
+ out<<" do_unroll="<<doUnroll;
+ }
+};
+
+class OpndLoopInfo {
+public:
+ enum OpndType {DEF_OUT_OF_LOOP, LD_CONST, COUNTER, UNDEF};
+ OpndLoopInfo() {type=DEF_OUT_OF_LOOP; val=0; phiSplit= false;}
+
+ OpndType getType() const {return type;}
+ void setType(OpndType newType) {assert(type!=newType);type = newType; val=0;}
+ bool isCounter() const {return type == COUNTER;}
+ bool isLDConst() const {return type == LD_CONST;}
+ bool isDOL() const {return type == DEF_OUT_OF_LOOP;}
+ bool isUndefined() const {return type == UNDEF;}
+ int getConst() const {assert(getType()==LD_CONST); return val;}
+ void setConst(int32 v) {assert(getType()==LD_CONST); val=v;}
+ int getIncrement() const {assert(getType()==COUNTER); return val;}
+ void setIncrement(int32 v) {assert(getType()==COUNTER); val=v;}
+ bool isPhiSplit() const {return phiSplit;}
+ void markPhiSplit() {assert(isCounter()); phiSplit = true;}
+
+
+ void print(std::ostream& out) {
+ if (type == DEF_OUT_OF_LOOP) out << "DOL";
+ else if (type == LD_CONST) out << "LDC:"<<getConst();
+ else if (type == COUNTER) out << "CNT:"<<getIncrement() << (phiSplit?" splt":"");
+ else out << "UNDEF";
+ }
+private:
+ OpndType type;
+ int val;
+ bool phiSplit; //only 1 phi split with DOL is allowed for counters.
+};
+
+typedef StlVector<Inst*> InstStack;
+typedef StlVector<LoopUnrollInfo*> UnrollInfos;
+
+static void log_ident(int n) {for (int i=0;i<n;++i) Log::out()<<" "; }
+static int signof(int v) { return (v == 0) ? 0 : ( v < 0 ? -1 : 1); }
+
+
+
+static void findLoopsToUnroll(MemoryManager& mm, IRManager& irm, UnrollInfos& result, const UnrollFlags& flags);
+static void doUnroll(MemoryManager& mm, IRManager& irm, const LoopUnrollInfo* info, const UnrollFlags& flags);
+static void calculateReachableNodesInLoop(LoopNode* loop, Node* node, Node* stopNode, BitSet& flags);
+
+
+void LoopUnrollAction::init() {
+ flags.smallLoopSize = getIntArg("small_loop_max_size", 5);
+ flags.smallLoopHotness = getIntArg("small_loop_hotness_percent", 300);
+ flags.smallLoopUnrollCount = getIntArg("small_loop_unroll_count", 8);
+
+ flags.mediumLoopSize = getIntArg("medium_loop_max_size", 10);
+ flags.mediumLoopHotness = getIntArg("medium_loop_hotness_percent", 300);
+ flags.mediumLoopUnrollCount = getIntArg("medium_loop_unroll_count", 4);
+
+ flags.largeLoopSize = getIntArg("large_loop_max_size", 20);
+ flags.largeLoopHotness = getIntArg("large_loop_hotness_percent", 300);
+ flags.largeLoopUnrollCount = getIntArg("large_loop_unroll_count", 2);
+
+//TODO: support unrolling of parent loops
+ flags.unrollParentLoops = false;//getBoolArg("unroll_parent_loops", false);
+}
+
+void LoopUnrollPass::_run(IRManager& irm) {
+ const UnrollFlags& flags = ((LoopUnrollAction*)getAction())->getFlags();
+
+ OptPass::computeDominatorsAndLoops(irm);
+ ControlFlowGraph& cfg = irm.getFlowGraph();
+ LoopTree* lt = cfg.getLoopTree();
+ if (!lt->hasLoops()) {
+ return;
+ }
+
+ MemoryManager mm("loopUnrollMM");
+ UnrollInfos loopsToUnroll(mm);
+ findLoopsToUnroll(mm, irm, loopsToUnroll, flags);
+ if (loopsToUnroll.empty()) {
+ if (Log::isEnabled()) Log::out() << "No candidates found to unroll"<<std::endl;
+ return;
+ }
+ if (Log::isEnabled()) {
+ Log::out()<<"Loops to unroll before filtering:"<<std::endl;
+ for (UnrollInfos::const_iterator it = loopsToUnroll.begin(), end = loopsToUnroll.end();it!=end; ++it) {
+ const LoopUnrollInfo* info = *it;
+ info->print(Log::out()); Log::out()<<std::endl;
+ }
+ }
+ bool hasProfile = cfg.hasEdgeProfile();
+ //filter out that can't be unrolled, calculate BodyA and BodyB
+ BitSet bodyANodes(mm, cfg.getMaxNodeId()), bodyBNodes(mm, cfg.getMaxNodeId());
+ for (UnrollInfos::iterator it = loopsToUnroll.begin(), end = loopsToUnroll.end();it!=end; ++it) {
+ LoopUnrollInfo* info = *it;
+ if (info == NULL) {
+ continue;
+ }
+ if (!info->doUnroll) {
+ *it=NULL;
+ continue;
+ }
+ Node* header=info->header;
+ LoopNode* loopHeader = lt->getLoopNode(header, false);
+ assert(loopHeader->getHeader() == header);
+
+ Node* checkNode = info->branchInst->getNode();
+ bodyANodes.clear();
+ bodyBNodes.clear();
+ calculateReachableNodesInLoop(loopHeader, loopHeader->getHeader(), checkNode, bodyANodes);
+ calculateReachableNodesInLoop(loopHeader, checkNode, NULL, bodyBNodes);
+ bodyANodes.intersectWith(bodyBNodes);
+ bool checkNodeIsJunctionPoint = bodyANodes.isEmpty();
+ if (!checkNodeIsJunctionPoint) {
+ if (Log::isEnabled()) {
+ Log::out()<<"Check node is not a junction point -> removing from the list: branch inst id=I"<<info->branchInst->getId()<<std::endl;
+ }
+ *it=NULL;
+ continue;
+ }
+ //check if branch semantic is OK
+ ComparisonModifier cmpMod = info->branchInst->getModifier().getComparisonModifier();
+ if (cmpMod!=Cmp_GT && cmpMod!=Cmp_GTE && cmpMod!=Cmp_GT_Un && cmpMod!=Cmp_GTE_Un) {
+ if (Log::isEnabled()) {
+ Log::out()<<"Branch is not a range comparison -> removing from the list: branch inst id=I"<<info->branchInst->getId()<<std::endl;
+ }
+ *it=NULL;
+ continue;
+ }
+
+ //check config settings
+ bool failed = false;
+ int nodesInLoop = loopHeader->getNodesInLoop().size();
+ const char* reason = "unknown";
+ if (nodesInLoop > flags.largeLoopSize) {
+ reason = "loop is too large";
+ failed = true;
+ } else if (hasProfile) {
+ int headHotness = (int)(header->getExecCount()*100.0 / cfg.getEntryNode()->getExecCount());
+ int minHeaderHotness= nodesInLoop <= flags.smallLoopSize ? flags.smallLoopHotness :
+ nodesInLoop <= flags.mediumLoopSize ? flags.mediumLoopHotness : flags.largeLoopHotness;
+ info->unrollCount = nodesInLoop <= flags.smallLoopSize ? flags.smallLoopUnrollCount :
+ nodesInLoop <= flags.mediumLoopSize? flags.mediumLoopUnrollCount: flags.largeLoopUnrollCount;
+ failed = headHotness < minHeaderHotness || info->unrollCount < 1;
+ if (failed) {
+ reason = "loop is too cold";
+ }
+ }
+ if (failed) {
+ if (Log::isEnabled()) {
+ Log::out()<<"Loop does not match unroll configuration ("<<reason<<") -> removing from the list: branch inst id=I"<<info->branchInst->getId()<<std::endl;
+ }
+ *it=NULL;
+ }
+ }
+ //filter out loops with multiple exits
+ for (UnrollInfos::iterator it1 = loopsToUnroll.begin(), end = loopsToUnroll.end();it1!=end; ++it1) {
+ const LoopUnrollInfo* info1 = *it1;
+ if (info1== NULL) {
+ continue;
+ }
+ Node* header=info1->header;
+ for (UnrollInfos::iterator it2 = it1+1; it2!=end; ++it2) {
+ const LoopUnrollInfo* info2 = *it2;
+ if (info2!=NULL && header==info2->header) {
+ if (Log::isEnabled()) {
+ Log::out() << "Found multiple exits:"; FlowGraph::printLabel(Log::out(), header);Log::out()<<std::endl;
+ }
+ if (hasProfile) {
+ Node* check1 = info1->branchInst->getNode();
+ Node* check2 = info2->branchInst->getNode();
+ if (check1->getExecCount() > check2->getExecCount()) {
+ *it2 = NULL;
+ } else {
+ *it1 = NULL;
+ }
+ } else { // random selection
+ *it2=NULL;
+ }
+ }
+ }
+ }
+ loopsToUnroll.erase(std::remove(loopsToUnroll.begin(), loopsToUnroll.end(), (LoopUnrollInfo*)NULL), loopsToUnroll.end());
+ if (loopsToUnroll.empty()) {
+ if (Log::isEnabled()) Log::out() << "--------No candidates to unroll left after filtering"<<std::endl;
+ return;
+ }
+
+ //dessa CFG before unrolling -> need to duplicate regions and we can do it on dessa form only today
+ {
+ SSABuilder::deconvertSSA(&cfg, irm.getOpndManager());
+ irm.setInSsa(false);
+ }
+
+ if (Log::isEnabled()) {
+ Log::out()<<"--------Loops to unroll after filtering : n="<<loopsToUnroll.size()<<std::endl;
+ for (UnrollInfos::const_iterator it = loopsToUnroll.begin(), end = loopsToUnroll.end();it!=end; ++it) {
+ const LoopUnrollInfo* info = *it;
+ info->print(Log::out()); Log::out()<<std::endl;
+ }
+ }
+
+ for (UnrollInfos::const_iterator it = loopsToUnroll.begin(), end = loopsToUnroll.end();it!=end; ++it) {
+ const LoopUnrollInfo* info = *it;
+ doUnroll(mm, irm, info, flags);
+ }
+};
+
+static void calculateReachableNodesInLoop(LoopNode* loop, Node* node, Node* stopNode, BitSet& flags) {
+ int id = node->getId();
+ if (!loop->inLoop(node) || node == stopNode || flags.getBit(id)) {
+ return;
+ }
+ flags.setBit(id, true);
+ const Edges& edges = node->getOutEdges();
+ for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) {
+ Edge* e = *ite;
+ Node* nextNode = e->getTargetNode();
+ if (nextNode != loop->getHeader()) {
+ calculateReachableNodesInLoop(loop, nextNode, stopNode, flags);
+ }
+ }
+}
+
+
+static OpndLoopInfo processOpnd(LoopNode* loopHead, LoopTree* lt, InstStack& defStack, Opnd* opnd) {
+ OpndLoopInfo result;
+ Inst* defInst = opnd->getInst();
+ if (Log::isEnabled()) {
+ log_ident(defStack.size()); defInst->print(Log::out()); Log::out()<<"]"<<std::endl;
+ }
+ if (std::find(defStack.begin(), defStack.end(), defInst)!=defStack.end()) {
+ result.setType(OpndLoopInfo::COUNTER);
+ result.setIncrement(0);
+ if (Log::isEnabled()) {
+ log_ident(defStack.size());
+ Log::out()<<"Found duplicate in def stack -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl;
+ }
+ return result;
+ }
+ Node* defNode = defInst->getNode();
+ Opcode opcode = defInst->getOpcode();
+
+ if (opcode == Op_LdConstant) {
+ result.setType(OpndLoopInfo::LD_CONST);
+ result.setConst(defInst->asConstInst()->getValue().i4);
+ if (Log::isEnabled()) {
+ log_ident(defStack.size());
+ Log::out()<<"assigning to const -> stopping recursion. ";result.print(Log::out());Log::out()<<std::endl;
+ }
+ return result;
+ }
+ if (!loopHead->inLoop(defNode)) {
+ if (Log::isEnabled()) {
+ log_ident(defStack.size());
+ Log::out()<<"Inst out of the loop -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl;
+ }
+ return result;
+ }
+
+ defStack.push_back(defInst);
+ if (opcode == Op_Phi) {
+ OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, defInst->getSrc(0));
+ OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, defInst->getSrc(1));
+ if (Log::isEnabled()) {
+ log_ident(defStack.size());
+ Log::out()<<"PHI(";info1.print(Log::out());Log::out()<<",";info2.print(Log::out());Log::out()<<")"<<std::endl;
+ }
+ if ((info1.isCounter() && !info1.isPhiSplit()) && (info2.isDOL() || info2.isLDConst())
+ || (info2.isCounter() && !info2.isPhiSplit()) && (info1.isDOL() || info1.isLDConst()))
+ {
+ result.setType(OpndLoopInfo::COUNTER);
+ result.setIncrement(info1.isCounter() ? info1.getIncrement() : info2.getIncrement());
+ result.markPhiSplit();
+ } else {
+ result.setType(OpndLoopInfo::UNDEF);
+ }
+ } else if (opcode == Op_Add || opcode == Op_Sub) { //todo: LADD
+ Opnd *op1 = defInst->getSrc(0);
+ Opnd *op2 = defInst->getSrc(1);
+ OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, op1);
+ OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, op2);
+ if ((info1.isLDConst() || info1.isDOL()) && (info2.isLDConst() || info2.isDOL())) {
+ if (info1.isLDConst() && info2.isLDConst() && info1.getConst() == info2.getConst()) {
+ result.setType(OpndLoopInfo::LD_CONST);
+ result.setConst(info1.getConst());
+ } else {
+ //result is DOL (default type)
+ }
+ } else if ((info1.isCounter() && info2.isLDConst()) || (info2.isCounter() && info1.isLDConst())) {
+ int increment = info1.isCounter()? info1.getIncrement(): info2.getIncrement();
+ int diff = info1.isLDConst()? info1.getConst(): info2.getConst();
+
+ //we use SSA form to analyze how opnd changes in loop and we do not analyze actual control flow,
+ // so we can unroll loops with monotonically changing 'counters' only.
+ //Example: when 'counter' changes not monotonically and we can't unroll:
+ //idx=0; loop {idx+=100; if(idx>=100) break; idx-=99;} ->'increment'=1 but not monotonicaly.
+ bool monotonousFlag = increment == 0 || diff == 0
+ || (opcode == Op_Add && signof(diff) == signof(increment))
+ || (opcode == Op_Sub && signof(diff) != signof(increment));
+ if (monotonousFlag) {
+ result.setType(OpndLoopInfo::COUNTER);
+ if ((info1.isCounter() && info1.isPhiSplit()) || (info2.isCounter() && info2.isPhiSplit())) {
+ result.markPhiSplit();
+ }
+ //TO IMPROVE: for loops like: for (; length-1>=0;length--){...}
+ //we have 2 SUBs by -1 => "-2", but real counter is changed by "-1".
+ //Loop unroll will use "-2". It's ok, because this value is used in a guard inst
+ //and ABS(increment_in_unroll) >= ABS(real_increment). This work only for monotonous loops.
+ //To make increment_in_unroll == real_increment we must track modifications (SUB,ADD) that affects vars only.
+ if (opcode == Op_Add) {
+ result.setIncrement(increment + diff);
+ } else {
+ result.setIncrement(increment - diff);
+ }
+ } else {
+ result.setType(OpndLoopInfo::UNDEF);
+ }
+ } else {
+ result.setType(OpndLoopInfo::UNDEF);
+ }
+ } else if (opcode == Op_StVar || opcode == Op_LdVar) {
+ Opnd* newOpnd = defInst->getSrc(0);
+ result = processOpnd(loopHead, lt, defStack, newOpnd);
+ } else if (opcode == Op_TauArrayLen) {
+ Opnd* arrayOpnd = defInst->getSrc(0);
+ result = processOpnd(loopHead, lt, defStack, arrayOpnd);
+ } else { //unsupported op
+ result.setType(OpndLoopInfo::UNDEF);
+ if (Log::isEnabled()) {
+ log_ident(defStack.size()); Log::out()<<"unknown op -> stopping recursion. ";
+ }
+ }
+ defStack.pop_back();
+ if (Log::isEnabled()) {
+ log_ident(defStack.size());
+ result.print(Log::out());Log::out()<<std::endl;
+ }
+ return result;
+}
+
+static LoopUnrollInfo* prepareUnrollInfo(MemoryManager& mm, LoopTree* lt, BranchInst* branchInst) {
+
+ if (Log::isEnabled()) {
+ Log::out()<<"==Checking loop exit:"; branchInst->print(Log::out()); Log::out()<<std::endl;
+ }
+
+ //traverse loop and track all modifications
+ Node* node = branchInst->getNode();
+ LoopNode* loopHeader = lt->getLoopNode(node, false);
+ Opnd* opnd1 = branchInst->getSrc(0);
+ Opnd* opnd2 = branchInst->getNumSrcOperands()==1?NULL:branchInst->getSrc(1);
+
+ if (opnd2==NULL) {
+ assert(branchInst->getComparisonModifier() == Cmp_Zero || branchInst->getComparisonModifier() == Cmp_NonZero);
+ assert(opnd1->getType()->isObject());
+ if (Log::isEnabled()) {
+ Log::out()<<"----Unsupported comparison modifier."<<std::endl;
+ }
+ return NULL;
+ }
+
+ if (!opnd1->getType()->isInteger() || opnd1->getType()->isInt8()
+ || !opnd2->getType()->isInteger() || opnd2->getType()->isInt8())
+ {
+ if (Log::isEnabled()) {
+ Log::out()<<"----Unsupported opnd types."<<std::endl;
+ }
+ return NULL; //IMPROVE: longs and floating types are not supported
+ }
+
+ InstStack defStack(mm);
+
+ Log::out()<<"----Analyzing opnd1 id="<<opnd1->getId()<<std::endl;
+ OpndLoopInfo opndInfo1 = processOpnd(loopHeader, lt, defStack, opnd1);
+ assert(defStack.empty());
+
+ Log::out()<<"----Analyzing opnd2 id="<<opnd2->getId()<<std::endl;
+ OpndLoopInfo opndInfo2 = processOpnd(loopHeader, lt, defStack, opnd2);
+ assert(defStack.empty());
+
+ if(Log::isEnabled()) {
+ Log::out()<<"----Result: opndId1="<<opnd1->getId()<<" type=";opndInfo1.print(Log::out());
+ Log::out()<<", opndId2="<<opnd2->getId()<<" type=";opndInfo2.print(Log::out());Log::out()<<std::endl;
+ }
+
+ //default values -> this item will not be unrolled unless all constraints are OK
+ LoopUnrollInfo* info = new (mm) LoopUnrollInfo();
+ info->header = loopHeader->getHeader();
+ info->branchInst = branchInst;
+ info->branchTargetIsExit = !loopHeader->inLoop(branchInst->getTargetLabel()->getNode());
+ info->doUnroll = false;
+
+ if (opndInfo1.isCounter() && (opndInfo2.isDOL() || opndInfo2.isLDConst())) {
+ info->doUnroll = true;
+ info->branchLimitOpndPos=1;
+ info->increment = opndInfo1.getIncrement();
+ } else if (opndInfo2.isCounter() && (opndInfo1.isDOL() || opndInfo1.isLDConst())) {
+ info->doUnroll = true;
+ info->branchLimitOpndPos=0;
+ info->increment = opndInfo2.getIncrement();
+ }
+ return info;
+}
+
+void findLoopsToUnroll(MemoryManager& tmpMM, IRManager& irm, UnrollInfos& result, const UnrollFlags& flags) {
+
+ ControlFlowGraph& fg = irm.getFlowGraph();
+ LoopTree* lt = fg.getLoopTree();
+
+ //find all loop exits
+ Edges loopExits(tmpMM);
+ const Nodes& nodes = fg.getNodes();
+ for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
+ Node* node = *it;
+ LoopNode* loopNode = lt->getLoopNode(node, false);
+ if (loopNode == NULL) {
+ continue; //node not in a loop
+ }
+ if (!flags.unrollParentLoops && loopNode->getChild()!=NULL) {
+ continue; //skip parent loops
+ }
+ const Edges& edges = node->getOutEdges();
+ for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) {
+ Edge* edge = *ite;
+ if (lt->isLoopExit(edge)) {
+ loopExits.push_back(edge);
+ }
+ }
+ }
+
+ //filter out all edges except branches
+ for (Edges::iterator ite = loopExits.begin(), ende = loopExits.end(); ite!=ende; ++ite) {
+ Edge* edge = *ite;
+ if (edge->isDispatchEdge() || edge->isUnconditionalEdge() || edge->isCatchEdge()) {
+ *ite = NULL;
+ continue;
+ }
+ Inst* lastInst = (Inst*)edge->getSourceNode()->getLastInst();
+ if (lastInst->isSwitch()) {
+ *ite = NULL;
+ continue;
+ }
+ assert(lastInst->isBranch());
+ assert(edge->isFalseEdge() || edge->isTrueEdge());
+ }
+ loopExits.erase(std::remove(loopExits.begin(), loopExits.end(), (Edge*)NULL), loopExits.end());
+
+ // analyze every loop exit and prepare unroll info
+ for (Edges::const_iterator ite = loopExits.begin(), ende = loopExits.end(); ite!=ende; ++ite) {
+ Edge* edge = *ite;
+ Node* sourceNode = edge->getSourceNode();
+ Inst* lastInst = (Inst*)sourceNode->getLastInst();
+ assert(lastInst->isBranch());
+ LoopUnrollInfo* info = prepareUnrollInfo(tmpMM, lt, lastInst->asBranchInst());
+ if (info == NULL) {
+ continue;
+ }
+ if (Log::isEnabled()) {
+ info->print(Log::out());
+ Log::out()<<std::endl;
+ }
+ result.push_back(info);
+ }
+}
+
+static void doUnroll(MemoryManager& mm, IRManager& irm, const LoopUnrollInfo* info, const UnrollFlags& flags) {
+ //unroll algorithm does the following
+ //before:
+ // loopOrig {
+ // bodyA
+ // check(idxOpnd,limitOpnd)
+ // bodyB
+ // }
+ //after:
+ // unrolledIncOpnd = unrollCount * idx->increment
+ // unrolledLimitOpnd = limitOpnd-unrolledIncOpnd;
+ // bodyA
+ // loopUnrolled {
+ // check(idxOpnd,unrolledLimitOpnd)
+ // bodyB
+ // bodyA
+ // bodyB
+ // ...
+ // bodyA
+ // }
+ // loopEpilogue {
+ // check(idxOpnd,limitOpnd)
+ // bodyB
+ // bodyA
+ // }
+ //
+ //where:
+ // bodyA - all nodes of the same loop accessible from checkNode via incoming edges
+ // bodyB - all nodes except bodyA and checkNode
+
+ ControlFlowGraph& cfg = irm.getFlowGraph();
+ LoopTree* lt = cfg.getLoopTree();
+ InstFactory& instFactory = irm.getInstFactory();
+ OpndManager& opndManager = irm.getOpndManager();
+ Type* opType = info->getLimitOpnd()->getType();
+
+ // printf("UNROLL\n");
+
+ //STEP 0: cache all data needed
+ assert(info->unrollCount >= 1);
+ Node* origHeader = info->header;
+ assert(origHeader->getInDegree() == 2); //loop is normalized
+
+ OptPass::computeLoops(irm);//recompute loop info if needed
+ LoopNode* loopNode = lt->getLoopNode(origHeader, false);
+
+ Edge* entryEdge = origHeader->getInEdges().front();
+ if (lt->isBackEdge(entryEdge)) {
+ entryEdge = origHeader->getInEdges().back();
+ }
+ Node* origCheckNode = info->branchInst->getNode();
+ Edge* origLoopExitEdge = info->branchTargetIsExit ? origCheckNode->getTrueEdge() : origCheckNode->getFalseEdge();
+
+ uint32 maxNodeId = cfg.getMaxNodeId()+1; //+1 for a split check node
+ StlBitVector nodesInLoop(mm, maxNodeId);
+ {
+ const Nodes& loopNodes = loopNode->getNodesInLoop();
+ for (Nodes::const_iterator it = loopNodes.begin(), end = loopNodes.end(); it!=end; ++it) {
+ Node* node = *it;
+ nodesInLoop.setBit(node->getId());
+ }
+ }
+
+
+ //STEP 1: calculate bodyA nodes
+ BitSet aFlags(mm, maxNodeId);
+ calculateReachableNodesInLoop(loopNode, origHeader, origCheckNode, aFlags);
+ StlBitVector bodyANodes(mm, maxNodeId);
+ for (uint32 i=0;i<maxNodeId;i++) bodyANodes.setBit(i, aFlags.getBit(i));
+
+ //STEP 2: make checkNode a separate node, prepare loop region
+ bodyANodes.setBit(origCheckNode->getId(), true);
+ Node* checkNode = cfg.splitNodeAtInstruction(info->branchInst->prev(), true, false, instFactory.makeLabel());
+ nodesInLoop.setBit(checkNode->getId(), true);
+ Node* preCheckNode = origCheckNode;
+ bodyANodes.setBit(preCheckNode->getId(), true);
+
+ //STEP 3: rotate original loop
+ // before: {bodyA1, check , bodyB}
+ // after: bodyA2 {check, bodyB, bodyA1}
+ Edge* bodyA2ToCheckEdge = NULL;
+ Opnd* limitOpndInBodyA2 = NULL;
+ {
+ //WARN: info->limitOpnd and info->indexOpnd can be replaced after code duplication if promoted to vars
+ Opnd* limitOpndBefore = info->getLimitOpnd();
+
+ assert(preCheckNode->getOutDegree()==1 && preCheckNode->getUnconditionalEdgeTarget() == checkNode);
+ DefUseBuilder defUses(mm);
+ defUses.initialize(cfg);
+ OpndRenameTable opndRenameTable(mm, maxNodeId); //todo: maxNodeId is overkill estimate here
+ NodeRenameTable nodeRenameTable(mm, maxNodeId);
+ Node* bodyA2 = FlowGraph::duplicateRegion(irm, origHeader, bodyANodes, defUses, nodeRenameTable, opndRenameTable);
+ cfg.replaceEdgeTarget(entryEdge, bodyA2, true);
+
+ // while duplicating a region new nodes could be created and 'nodesInRegion' bitvector param is updated.
+ // BodyA is part of the loop -> if new nodes were created in the loop we must track them.
+ nodesInLoop.resize(bodyANodes.size());
+ for (uint32 i=0;i<bodyANodes.size();i++) nodesInLoop.setBit(i, bodyANodes.getBit(i) || nodesInLoop.getBit(i));
+
+ Node* bodyA2PreCheckNode = nodeRenameTable.getMapping(preCheckNode);
+ assert(bodyA2PreCheckNode->getOutDegree()==1 && bodyA2PreCheckNode->getUnconditionalEdgeTarget() == checkNode);
+ bodyA2ToCheckEdge = bodyA2PreCheckNode->getUnconditionalEdge();
+ limitOpndInBodyA2 = limitOpndBefore;
+ if (nodeRenameTable.getMapping(limitOpndBefore->getInst()->getNode())!=NULL) {
+ limitOpndInBodyA2 = opndRenameTable.getMapping(limitOpndBefore);
+ }
+ assert(limitOpndInBodyA2!=NULL);
+ }
+
+ //STEP 4: prepare epilogue loop: {check, bodyB, bodyA}
+ Node* epilogueLoopHead = NULL;
+ {
+ DefUseBuilder defUses(mm);
+ defUses.initialize(cfg);
+ OpndRenameTable opndRenameTable(mm, maxNodeId); //todo: maxNodeId is overkill estimate here
+ NodeRenameTable nodeRenameTable(mm, maxNodeId);
+ epilogueLoopHead = FlowGraph::duplicateRegion(irm, checkNode, nodesInLoop, defUses, nodeRenameTable, opndRenameTable);
+ cfg.replaceEdgeTarget(origLoopExitEdge, epilogueLoopHead, true);
+
+ //backedge was not duplicated -> this is a feature (Loop.cpp depends on it), find using tailNode
+ Node* newTailNode = nodeRenameTable.getMapping(preCheckNode);
+ assert(newTailNode->getOutDegree() == 1 && newTailNode->getUnconditionalEdgeTarget() == checkNode);
+ Edge* backedge = newTailNode->getUnconditionalEdge();
+ cfg.replaceEdgeTarget(backedge, epilogueLoopHead, true);
+ }
+
+ //STEP 5: prepare unrolledLimitOpnd and replace it in original loop's check
+ {
+ Node* unrolledPreheader = cfg.spliceBlockOnEdge(bodyA2ToCheckEdge, instFactory.makeLabel());
+ Opnd* unrolledIncOpnd = opndManager.createSsaTmpOpnd(opType);
+ unrolledPreheader->appendInst(instFactory.makeLdConst(unrolledIncOpnd, info->increment * info->unrollCount));
+ Opnd* unrolledLimitOpnd = opndManager.createSsaTmpOpnd(opType);
+ Modifier mod = Modifier(SignedOp)|Modifier(Strict_No)|Modifier(Overflow_None)|Modifier(Exception_Never);
+ unrolledPreheader->appendInst(instFactory.makeSub(mod, unrolledLimitOpnd, limitOpndInBodyA2, unrolledIncOpnd));
+ info->branchInst->setSrc(info->branchLimitOpndPos, unrolledLimitOpnd);
+ }
+
+ //STEP 6: unroll original loop and remove all checks in duplicated bodies
+ {
+ Edge* backedge = preCheckNode->getUnconditionalEdge();
+ for (int i=1;i<info->unrollCount;i++) {
+ DefUseBuilder defUses(mm);
+ OpndRenameTable opndRenameTable(mm, maxNodeId);
+ NodeRenameTable nodeRenameTable(mm, maxNodeId);
+
+ Node* unrolledRegionHeader = FlowGraph::duplicateRegion(irm, checkNode, nodesInLoop, defUses, nodeRenameTable, opndRenameTable);
+ cfg.replaceEdgeTarget(backedge, unrolledRegionHeader, true);
+
+ Node* newTail = nodeRenameTable.getMapping(preCheckNode);
+ assert(newTail->getOutDegree()==1 );
+ backedge = newTail->getUnconditionalEdge();
+ if (i>1) {
+ cfg.replaceEdgeTarget(backedge, checkNode, true);
+ }
+
+ //remove check from duplicated code
+ Node* duplicateCheckNode = nodeRenameTable.getMapping(checkNode);
+ assert(duplicateCheckNode->getOutDegree()==2);
+ Edge* exitEdge = info->branchTargetIsExit ? duplicateCheckNode->getTrueEdge() : duplicateCheckNode->getFalseEdge();
+ duplicateCheckNode->getLastInst()->unlink();
+ cfg.removeEdge(exitEdge);
+ }
+ }
+
+ //STEP 7: make old loop colder
+ if (cfg.hasEdgeProfile()) {
+ Edge* epilogueExit = info->branchTargetIsExit ? epilogueLoopHead->getTrueEdge() : epilogueLoopHead->getFalseEdge();
+ epilogueExit->setEdgeProb(epilogueExit->getEdgeProb() * 5);
+ }
+}
+
+
+}//namespace
+
+
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?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Fri Jul 20 02:40:02 2007
@@ -924,7 +924,6 @@
case Op_AddOffset:
case Op_AddOffsetPlusHeapbase:
- case Op_ScaledDiffRef:
// the following are irrelevant, but cased so we
// notice any additions:
@@ -967,8 +966,6 @@
case Op_TauHasType:
case Op_TauHasExactType:
case Op_TauIsNonNull:
- case Op_PredCmp:
- case Op_PredBranch:
break;
//case Op_TauStRef:
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/reassociate.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/reassociate.cpp?view=diff&rev=557942&r1=557941&r2=557942
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/reassociate.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/reassociate.cpp Fri Jul 20 02:40:02 2007
@@ -375,7 +375,6 @@
case Op_LdArrayLenOffset:
case Op_LdArrayLenOffsetPlusHeapbase:
case Op_AddScaledIndex:
- case Op_ScaledDiffRef:
case Op_TauArrayLen:
default:
break;