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