You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/03/22 05:22:14 UTC
svn commit: r521112 - in /harmony/enhanced/drlvm/trunk/vm/jitrino:
config/em64t/ config/ia32/ src/codegenerator/ src/codegenerator/ia32/
src/optimizer/
Author: varlax
Date: Wed Mar 21 21:22:11 2007
New Revision: 521112
URL: http://svn.apache.org/viewvc?view=rev&rev=521112
Log:
Applied HARMONY-3243 [drlvm][jit][opt]It's possible to fill array with constant much faster
Added:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp (with props)
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf?view=diff&rev=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf Wed Mar 21 21:22:11 2007
@@ -62,8 +62,8 @@
-XDjit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XDjit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,so2-,simplify,dce,uce,escape,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.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,early_prop-,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,so2-,simplify,dce,uce,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,fastArrayFill,statprof,markglobals
+-XDjit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,early_prop-,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,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
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Wed Mar 21 21:22:11 2007
@@ -63,8 +63,8 @@
-XDjit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
--XDjit.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,abcd,dce,uce,gcm,dessa,statprof,markglobals
--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.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,abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
+-XDjit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,cg_fastArrayFill,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
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Wed Mar 21 21:22:11 2007
@@ -166,6 +166,7 @@
public:
enum Id {
InitializeArray,
+ FillArrayWithConst,
PseudoCanThrow,
SaveThisState,
ReadThisState,
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp?view=diff&rev=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp Wed Mar 21 21:22:11 2007
@@ -131,11 +131,21 @@
opndInfo.sourceOpndId = EmptyUint32;
}
}
+ /*
+ Here is the previous version to test whether the inst is copy or not.
bool isCopy = inst->getMnemonic() == Mnemonic_MOV ||(
(inst->getMnemonic() == Mnemonic_ADD || inst->getMnemonic() == Mnemonic_SUB) &&
inst->getOpnd(3)->isPlacedIn(OpndKind_Imm) && inst->getOpnd(3)->getImmValue()==0
&& inst->getOpnd(3)->getRuntimeInfo()==NULL
);
+ It considered special case of 'dst = src +/- 0' as copy.
+ In fact there are more similar cases like 'IMUL src, 1 ; shift src, 0' etc.
+ Such checks are obsolete now, Should as peephole takes care about such copies.
+
+ Anyway, the code above had a bug: 'inst->getOpnd(3)' crashes in instructions
+ in native form (like ADD def_use, use).
+ */
+ const bool isCopy = inst->getMnemonic() == Mnemonic_MOV;
if (isCopy){ // CopyPseudoInst or mov
Opnd * defOpnd = inst->getOpnd(0);
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp?view=auto&rev=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp Wed Mar 21 21:22:11 2007
@@ -0,0 +1,132 @@
+/*
+ * 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 FastArrayFilling: public SessionAction {
+
+ void runImpl();
+};
+
+static ActionFactory<FastArrayFilling> _faf("cg_fastArrayFill");
+
+void
+FastArrayFilling::runImpl()
+{
+ const Nodes& nodes = irManager->getFlowGraph()->getNodesPostOrder();
+ for (Nodes::const_reverse_iterator it = nodes.rbegin(),end = nodes.rend();it!=end; ++it) {
+ Node* bb = *it;
+ if (!bb->isBlockNode()) {
+ continue;
+ }
+ if(bb->isEmpty()) {
+ continue;
+ }
+
+ //find basic block with only instruction: internal helper fill_array_with_const
+ Inst * inst = (Inst*)bb->getLastInst();
+ if (inst->getMnemonic() != Mnemonic_CALL) {
+ continue;
+ }
+
+ Opnd::RuntimeInfo * rt = inst->getOpnd(((ControlTransferInst*)inst)->getTargetOpndIndex())->getRuntimeInfo();
+
+ if (!rt || rt->getKind() != Opnd::RuntimeInfo::Kind_InternalHelperAddress) {
+ continue;
+ }
+
+ std::string str = std::string((const char*)rt->getValue(0));
+ if (str != "fill_array_with_const") {
+ continue;
+ }
+
+ //replace the internal helper with a sequence of instructions
+ inst->unlink();
+
+ ControlFlowGraph * fg = irManager->getFlowGraph();
+ Edge * outEdge = bb->getOutEdges().front();
+ Node * nextNode = outEdge->getTargetNode();
+
+ //extract operands from the internal helper instruction
+ Inst::Opnds opnds(inst, Inst::OpndRole_Use|Inst::OpndRole_Explicit|Inst::OpndRole_Auxilary);
+ Inst::Opnds::iterator ito = opnds.begin()+1;
+
+// Opnd* args[4] = {valueOp, arrayRef, arrayBound, baseOp};
+ Opnd * value = inst->getOpnd(ito++);
+ Opnd * arrayRef = inst->getOpnd(ito++);
+ Opnd * arrayBound = inst->getOpnd(ito++);
+ Opnd * arrayBase = inst->getOpnd(ito++);
+
+ //number of operands must be 5. First operand is the internal helper address
+ assert(ito == opnds.end());
+
+ //insert preparing instructions for filling loop
+ //LEA instruction loads address of the end of an array
+
+ TypeManager& tm = irManager->getTypeManager();
+
+ Type * int32Type = tm.getInt32Type();
+ Type * intPtrType = tm.getIntPtrType();
+ Type * elemType = arrayRef->getType()->asArrayType()->getElementType();
+ //memory operand should contains only operand with managed pointer type
+ Type * ptrToIntType = tm.getManagedPtrType(int32Type);
+
+ Opnd * arrayEnd = irManager->newOpnd(intPtrType);
+ Opnd * scale = irManager->newImmOpnd(int32Type, getByteSize(irManager->getTypeSize(elemType)));
+ if (arrayEnd->getSize() > arrayBound->getSize()) {
+ bb->appendInst(irManager->newInst(Mnemonic_MOVZX, arrayEnd, arrayBound));
+ } else {
+ bb->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, arrayEnd, arrayBound));
+ }
+ bb->appendInst(irManager->newInst(Mnemonic_LEA, arrayEnd, irManager->newMemOpnd(arrayEnd->getType(), arrayBase, arrayEnd, scale)));
+
+ //load an address of the first element
+ Opnd * index = irManager->newOpnd(ptrToIntType);
+ bb->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, index, arrayBase));
+
+ Node * loopNode = fg->createNode(Node::Kind_Block);
+
+ //insert filling instructions
+ Opnd * memOp1 = irManager->newMemOpndAutoKind(value->getType(), index);
+ Opnd * memOp2 = irManager->newMemOpndAutoKind(value->getType(), index,irManager->newImmOpnd(int32Type,4));
+ loopNode->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, memOp1, value));
+ loopNode->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, memOp2, value));
+
+ //increment the element address
+ Opnd * incOp = irManager->newImmOpnd(intPtrType,8);
+ loopNode->appendInst(irManager->newInst(Mnemonic_ADD, index, incOp));
+
+ //compare the element address with the end of the array
+ loopNode->appendInst(irManager->newInst(Mnemonic_CMP, index, arrayEnd));
+
+ fg->replaceEdgeTarget(outEdge, loopNode);
+
+ loopNode->appendInst(irManager->newBranchInst(Mnemonic_JL, loopNode, nextNode));
+ fg->addEdge(loopNode, loopNode, 0.95);
+ fg->addEdge(loopNode, nextNode, 0.05);
+ }
+}
+
+}}
Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp
------------------------------------------------------------------------------
svn:eol-style = native
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Wed Mar 21 21:22:11 2007
@@ -156,6 +156,10 @@
profileAccessInterface->value_profiler_add_value(mpHandle, index, value);
}
+void __stdcall fill_array_with_const(uint32 copyOp, uint32 arrayRef, uint32 arrayBound, uint32 baseOp) {
+ assert(0);
+ return;
+}
//_______________________________________________________________________________________________________________
uint32 InstCodeSelector::_tauUnsafe;
@@ -177,6 +181,8 @@
irManager.registerInternalHelperInfo("initialize_array", IRManager::InternalHelperInfo((void*)&initialize_array,&CallingConvention_STDCALL));
irManager.registerInternalHelperInfo("add_value_profile_value", IRManager::InternalHelperInfo((void*)&add_value_profile_value,&CallingConvention_STDCALL));
+
+ irManager.registerInternalHelperInfo("fill_array_with_const", IRManager::InternalHelperInfo((void*)&fill_array_with_const,&CallingConvention_STDCALL));
}
//_______________________________________________________________________________________________________________
@@ -2837,8 +2843,18 @@
appendInsts(irManager.newInternalRuntimeHelperCallInst("add_value_profile_value", nArgs, newArgs, dstOpnd));
break;
}
+ case FillArrayWithConst:
+ {
+ assert(numArgs == 4);
+ Opnd * newArgs[4] = {(Opnd *)args[0], (Opnd *)args[1], (Opnd *)args[2], (Opnd *)args[3]};
+ appendInsts(irManager.newInternalRuntimeHelperCallInst("fill_array_with_const", numArgs, newArgs, dstOpnd));
+ break;
+ }
default:
+ {
assert(0);
+ break;
+ }
}
return dstOpnd;
}
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Wed Mar 21 21:22:11 2007
@@ -409,6 +409,7 @@
case ReadThisState: return JitHelperCallOp::ReadThisState;
case LockedCompareAndExchange: return JitHelperCallOp::LockedCompareAndExchange;
case AddValueProfileValue: return JitHelperCallOp::AddValueProfileValue;
+ case FillArrayWithConst: return JitHelperCallOp::FillArrayWithConst;
}
assert(0);
return JitHelperCallOp::InitializeArray; // to keep compiler quiet
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp?view=auto&rev=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp Wed Mar 21 21:22:11 2007
@@ -0,0 +1,269 @@
+/*
+* 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, Nikolay A. Sidelnikov
+* @version $Revision: 1.20.8.1.4.4 $
+*
+*/
+
+#include "escapeanalyzer.h"
+#include "Log.h"
+#include "Inst.h"
+#include "Dominator.h"
+#include "globalopndanalyzer.h"
+#include "optimizer.h"
+#include "FlowGraph.h"
+#include "LoopTree.h"
+
+#include <algorithm>
+
+namespace Jitrino {
+
+ struct LoopEdges
+ {
+ Edge * outEdge;
+ Edge * inEdge;
+ Edge * backEdge;
+
+ LoopEdges() : outEdge(NULL), inEdge(NULL), backEdge(NULL) {} ;
+ };
+
+DEFINE_SESSION_ACTION(FastArrayFillPass, fastArrayFill, "Fast Array Filling")
+
+void
+FastArrayFillPass::_run(IRManager& irManager)
+{
+ LoopTree * info = irManager.getLoopTree();
+ if (!info->isValid()) {
+ info->rebuild(false);
+ }
+ if (!info->hasLoops()) {
+ return;
+ }
+
+ MemoryManager tmm(1024,"FastArrayInitPass::insertFastArrayInit");
+ Edges loopEdges(tmm);
+ StlMap<Node *, LoopEdges> loopInfo(tmm);
+
+ const Nodes& nodes = irManager.getFlowGraph().getNodes();
+ for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
+ Node* node = *it;
+ if (!info->isLoopHeader(node)) {
+ continue;
+ }
+ //compute number of nodes of the loop
+ Nodes loopNodes = info->getLoopNode(node,false)->getNodesInLoop();
+ unsigned sz = loopNodes.size();
+ if (sz!=3) {
+ continue;
+ }
+
+ if (info->isBackEdge(node->getInEdges().front())) {
+ loopInfo[node].backEdge = node->getInEdges().front();
+ loopInfo[node].inEdge = node->getInEdges().back();
+ } else {
+ loopInfo[node].inEdge = node->getInEdges().front();
+ loopInfo[node].backEdge = node->getInEdges().back();
+ }
+ loopInfo[node].outEdge = info->isLoopExit(node->getOutEdges().front())? node->getOutEdges().front() : node->getOutEdges().back();
+ }
+
+ //check found loops for pattern
+ for(StlMap<Node *, LoopEdges>::const_iterator it = loopInfo.begin(); it != loopInfo.end(); ++it) {
+
+ Edge * backEdge = it->second.backEdge;
+ Edge * inEdge = it->second.inEdge;
+ Edge * outEdge = it->second.outEdge;
+
+ Node * startNode = backEdge->getSourceNode();
+ Opnd * index = NULL;
+ Opnd * tmpIndex = NULL;
+ Opnd * constValue = NULL;
+ Opnd * address = NULL;
+ Opnd * arrayBase = NULL;
+ Opnd * arrayRef = NULL;
+ Opnd* inc = NULL;
+ Opnd * arrayBound = NULL;
+ Opnd * fillBound = NULL;
+ Opnd *startIndex;
+ Inst * inst = ((Inst *)startNode->getLastInst());
+ bool found = false;
+
+ //check StVar
+ if (inst->getOpcode() == Op_StVar) {
+ index = inst->getDst();
+ inc = inst->getSrc(0);
+ inst = inst->getPrevInst();
+ //check Add
+ if (inst->getOpcode() == Op_Add) {
+ Opnd* addOp = inst->getSrc(1);
+ tmpIndex = inst->getSrc(0);
+ //check Add operands
+ if (inst->getDst() == inc &&
+ addOp->getInst()->getOpcode() == Op_LdConstant &&
+ ((ConstInst *)addOp->getInst())->getValue().i4 == 1)
+ {
+ inst = inst->getPrevInst();
+ //check StInd
+ if (inst->getOpcode() == Op_TauStInd) {
+ constValue = inst->getSrc(0);
+ address = inst->getSrc(1);
+ inst = inst->getPrevInst();
+ //check AddIndex
+ if (inst->getOpcode() == Op_AddScaledIndex && inst->getDst() == address &&
+ inst->getSrc(1) == tmpIndex)
+ {
+ arrayBase = inst->getSrc(0);
+ inst = inst->getPrevInst();
+ //check Label aka beginning of BB
+ if (inst->getOpcode() == Op_Label) {
+ found = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!found) {
+ continue;
+ }
+ startNode = startNode->getInEdges().front()->getSourceNode();
+ inst = ((Inst *)startNode->getLastInst());
+
+ //check CheckUpperBound
+ if (inst->getOpcode() == Op_TauCheckUpperBound && inst->getSrc(0) == tmpIndex && inst->getPrevInst()->getOpcode() == Op_Label) {
+ arrayBound = inst->getSrc(1);
+ } else {
+ continue;
+ }
+
+ startNode = startNode->getInEdges().front()->getSourceNode();
+ inst = ((Inst *)startNode->getLastInst());
+ found = false;
+ //check Branch
+ if (inst->getOpcode() == Op_Branch && inst->getSrc(0) == tmpIndex) {
+ fillBound = inst->getSrc(1);
+ inst = inst->getPrevInst();
+ //check LdVar and Label
+ if (inst->getOpcode() == Op_LdVar && inst->getSrc(0) == index && inst->getDst() == tmpIndex && inst->getPrevInst()->getOpcode() == Op_Label) {
+ found = true;
+ }
+ }
+ if (!found) {
+ continue;
+ }
+
+ startNode = inEdge->getSourceNode();
+ inst = ((Inst *)startNode->getLastInst());
+ found = false;
+
+ //check StVar
+ if (inst->getOpcode() == Op_StVar && inst->getDst() == index) {
+ startIndex = inst->getSrc(0);
+ inst = inst->getPrevInst();
+ //check StInd
+ if (inst->getOpcode() == Op_TauStInd && inst->getSrc(0) == constValue && inst->getSrc(1) == arrayBase) {
+ inst = inst->getPrevInst();
+ //check LdBase
+ if (inst->getOpcode() == Op_LdArrayBaseAddr && inst->getDst() == arrayBase && inst->getPrevInst()->getOpcode() == Op_Label) {
+ arrayRef = inst->getSrc(0);
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ continue;
+ }
+
+ startNode = startNode->getInEdges().front()->getSourceNode();
+ inst = ((Inst *)startNode->getLastInst());
+ found = false;
+
+ //check CheckUpperBound
+ ConstInst * cInst = (ConstInst *)inst->getSrc(0)->getInst();
+ if (inst->getOpcode() == Op_TauCheckUpperBound && cInst && cInst->getValue().i4 == 0 ) {
+ inst = inst->getPrevInst();
+ //check ArrayLength and Label
+ if (inst->getOpcode() == Op_TauArrayLen && inst->getSrc(0) == arrayRef && inst->getDst() == arrayBound && inst->getPrevInst()->getOpcode() == Op_Label) {
+ found = true;
+ }
+ }
+ if (!found) {
+ continue;
+ }
+
+ //now we found our pattern
+
+ inEdge = startNode->getInEdges().front();
+
+ //get a new constant
+ int val = ((ConstInst*)constValue->getInst())->getValue().i4;
+ switch (((Type*)arrayRef->getType()->asArrayType()->getElementType())->tag) {
+ case Type::Int8:
+ case Type::Boolean:
+ case Type::UInt8:
+ val |= (val << 8);
+ val |= (val << 16);
+ break;
+ case Type::Int16:
+ case Type::UInt16:
+ case Type::Char:
+ val |= (val << 16);
+ break;
+ case Type::Int32:
+ case Type::UInt32:
+ case Type::UIntPtr:
+ case Type::IntPtr:
+ break;
+ default:
+ continue;
+ break;
+ }
+
+ ControlFlowGraph& fg = irManager.getFlowGraph();
+ Node * preheader = fg.splitNodeAtInstruction(inst, true, false, irManager.getInstFactory().makeLabel());
+ Inst * cmp = irManager.getInstFactory().makeBranch(Cmp_NE_Un, arrayBound->getType()->tag, arrayBound, fillBound, (LabelInst *)preheader->getFirstInst());
+ startNode->appendInst(cmp);
+
+ Node * prepNode = fg.createBlockNode(irManager.getInstFactory().makeLabel());
+ fg.addEdge(startNode,prepNode);
+
+ OpndManager& opndManager = irManager.getOpndManager();
+
+ Opnd * copyOp = opndManager.createArgOpnd(irManager.getTypeManager().getInt32Type());
+ Inst * copyInst = irManager.getInstFactory().makeLdConst(copyOp,val);
+ prepNode->appendInst(copyInst);
+
+ Opnd *baseOp = opndManager.createArgOpnd(irManager.getTypeManager().getIntPtrType());
+ Inst * ldBaseInst = irManager.getInstFactory().makeLdArrayBaseAddr(arrayRef->getType()->asArrayType()->getElementType(),baseOp, arrayRef);
+ prepNode->appendInst(ldBaseInst);
+
+ Opnd* args[4] = {copyOp, arrayRef, arrayBound, baseOp};
+
+ // add jit helper
+ Inst* initInst = irManager.getInstFactory().makeJitHelperCall(
+ OpndManager::getNullOpnd(), FillArrayWithConst, 4, args);
+ prepNode->appendInst(initInst);
+
+ fg.addEdge(prepNode, outEdge->getTargetNode());
+
+ }
+}
+}
+
+
Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp
------------------------------------------------------------------------------
svn:eol-style = native
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Wed Mar 21 21:22:11 2007
@@ -468,6 +468,8 @@
os << "LockedCmpExchange"; break;
case AddValueProfileValue:
os << "AddValueProfileValue"; break;
+ case FillArrayWithConst:
+ os << "FillArrayWithConst"; break;
default:
assert(0); break;
}
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=521112&r1=521111&r2=521112
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Wed Mar 21 21:22:11 2007
@@ -271,6 +271,7 @@
enum JitHelperCallId {
InitializeArray,
+ FillArrayWithConst,
PseudoCanThrow,
SaveThisState, //todo: replace with GetTLS + offset sequence
ReadThisState, //todo: replace with GetTLS + offset sequence