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/04/04 12:06:15 UTC

svn commit: r525483 - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src: codegenerator/ia32/Ia32FastArrayFilling.cpp codegenerator/ia32/Ia32GCSafePoints.cpp codegenerator/ia32/Ia32InstCodeSelector.cpp optimizer/FastArrayFilling.cpp

Author: varlax
Date: Wed Apr  4 03:06:12 2007
New Revision: 525483

URL: http://svn.apache.org/viewvc?view=rev&rev=525483
Log:
Applied HARMONY-3423 [drlvm][jit][opt] SPECjbb2005 fails on DRLVM on Linux/EM64T in -Xem:server mode with extended inliner parameters

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp

Modified: 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=diff&rev=525483&r1=525482&r2=525483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32FastArrayFilling.cpp Wed Apr  4 03:06:12 2007
@@ -35,6 +35,11 @@
 void
 FastArrayFilling::runImpl() 
 {
+    /*
+    find and replace particular internal helper (inserted by HLO path) 
+    with a loop providing fast array filling with a constant.
+    */
+
     const Nodes& nodes = irManager->getFlowGraph()->getNodesPostOrder();
     for (Nodes::const_reverse_iterator it = nodes.rbegin(),end = nodes.rend();it!=end; ++it) {
         Node* bb = *it;
@@ -70,8 +75,8 @@
         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; 
+        Inst::Opnds opnds(inst, Inst::OpndRole_Use|Inst::OpndRole_Auxilary);
+        Inst::Opnds::iterator ito = opnds.begin(); 
 
 //      Opnd* args[4] = {valueOp, arrayRef, arrayBound, baseOp};
         Opnd * value = inst->getOpnd(ito++);
@@ -106,16 +111,21 @@
         Opnd * index = irManager->newOpnd(ptrToIntType);
         bb->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, index, arrayBase));
 
+        //create increment
+        Opnd * incOp = irManager->newOpnd(intPtrType);
+        bb->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, incOp, irManager->newImmOpnd(intPtrType,8)));
+
         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));
+#ifndef _EM64T_
+        Opnd * memOp2 = irManager->newMemOpndAutoKind(value->getType(), index,irManager->newImmOpnd(int32Type,4));
         loopNode->appendInst(irManager->newCopyPseudoInst(Mnemonic_MOV, memOp2, value));
-        
+#endif
+
         //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

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp?view=diff&rev=525483&r1=525482&r2=525483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp Wed Apr  4 03:06:12 2007
@@ -321,18 +321,35 @@
     return res;
 }
 
+static bool isHeapBase(Opnd* immOpnd) {
+    assert(immOpnd->isPlacedIn(OpndKind_Imm));
+#ifndef _EM64T_
+    return false;
+#else 
+    int64 heapBase = (int64)VMInterface::getHeapBase();
+    return immOpnd->getImmValue() == heapBase;
+#endif
+}
+
+static Opnd* findImmediateSource(Opnd* opnd) {
+    Opnd* res = opnd;
+    while (!res->isPlacedIn(OpndKind_Imm)) {
+        Inst* defInst = res->getDefiningInst();
+        if (!defInst || defInst->getMnemonic()!=Mnemonic_MOV) {
+            return NULL;
+        }
+        res = defInst->getOpnd(1);
+    }
+    return res;
+}
 
 int32 GCSafePointsInfo::getOffsetFromImmediate(Opnd* offsetOpnd) const {
     if (offsetOpnd->isPlacedIn(OpndKind_Immediate)) {
         if (offsetOpnd->getImmValue() == 0 && offsetOpnd->getRuntimeInfo()!=NULL) {
             irm.resolveRuntimeInfo(offsetOpnd);
         }
-#ifndef _EM64T_
+        assert(!isHeapBase(offsetOpnd));
         return (int32)offsetOpnd->getImmValue();
-#else
-        return offsetOpnd->getImmValue() == (int64)VMInterface::getHeapBase() ?
-            0 : (int32)offsetOpnd->getImmValue();
-#endif
     }
     return MPTR_OFFSET_UNKNOWN;
 }
@@ -486,16 +503,15 @@
 #endif
                         fromOpnd = opnd;
                         Opnd* offsetOpnd = inst->getOpnd(useIndex1);
-                        if (offsetOpnd->isPlacedIn(OpndKind_Immediate)) {
-                            offset = getOffsetFromImmediate(offsetOpnd);
+                        Opnd* immOffset = findImmediateSource(offsetOpnd);
+                        if (immOffset) {
+                           if (isHeapBase(immOffset)) {
+                               offset = 0;
+                           } else {
+                               offset = getOffsetFromImmediate(immOffset);
+                           }
                         } else {
-                            assert(offsetOpnd->isPlacedIn(OpndKind_Memory) || offsetOpnd->isPlacedIn(OpndKind_Reg));
-#ifdef _EM64T_
-                            if(offsetOpnd->getDefiningInst() && offsetOpnd->getDefiningInst()->getMnemonic() == Mnemonic_MOV && offsetOpnd->getDefiningInst()->getOpnd(1)->isPlacedIn(OpndKind_Immediate)) 
-                                offset = getOffsetFromImmediate(offsetOpnd->getDefiningInst()->getOpnd(1));
-                            else 
-#endif
-                                offset = MPTR_OFFSET_UNKNOWN;
+                           offset = MPTR_OFFSET_UNKNOWN;
                         }
                     }
                     break;

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=525483&r1=525482&r2=525483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Wed Apr  4 03:06:12 2007
@@ -149,6 +149,7 @@
 }
 
 void __stdcall fill_array_with_const(uint32 copyOp, uint32 arrayRef, uint32 arrayBound, uint32 baseOp) {
+    Jitrino::crash("Illegal internal helper was called.\n Please enable cg_fastArrayFill optimization in the code generator path");
     assert(0);
     return;
 }

Modified: 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=diff&rev=525483&r1=525482&r2=525483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FastArrayFilling.cpp Wed Apr  4 03:06:12 2007
@@ -48,6 +48,48 @@
 void
 FastArrayFillPass::_run(IRManager& irManager) 
 {
+    /*
+    This pass tries to find the array filling code pattern and adds 
+    new code under a branch. The new code will be executed in the case of 
+    array filling goes from first to last index of the array.
+
+    Example (C++ like):
+
+    Old code:
+
+        char[] a = new char[100];
+        char c = 1;
+        int num = 100;
+        for (int i = 0; i < num; i++) {
+            a[i] = c;
+        }
+
+    New code:
+
+        char[] a = new char[100];
+        int num = 100;
+        if (num == lengthof(a)) {
+            int * b = (int *)a;
+            int cc = 1 | (1 << 16)
+            for (int i = 0; i < 100; i += 2) {
+                b[i] = cc;
+            }
+        } else {
+            char c = 1;
+            int num = 100;
+            for (int i = 0; i < num; i++) {
+                a[i] = c;
+            }
+        }
+    
+    The pattern depends on loop peeling, de-SSA pass and ABCD pass.
+    Also it needs cg_fastArrayFill pass in code generator.
+    
+    Seems like this pass could be moved into the translator phase with 
+    significant reducing of the pattern and removing of dependencies 
+    from HLO optimizations.
+    */
+
     LoopTree * info = irManager.getLoopTree();
     if (!info->isValid()) {
         info->rebuild(false);
@@ -60,6 +102,7 @@
     Edges loopEdges(tmm);
     StlMap<Node *, LoopEdges> loopInfo(tmm);
         
+    //collect necessary information about loops
     const Nodes& nodes = irManager.getFlowGraph().getNodes();
     for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
         Node* node = *it;
@@ -84,6 +127,37 @@
     }
 
     //check found loops for pattern
+    /* Code pattern:
+
+    label .node1
+    arraylen  arrayRef ((tau1,tau3)) -) arrayBound:int32
+    chkub 0 .lt. arrayBound -) tau2:tau
+    GOTO .node2
+
+    label .node2
+    ldbase    arrayRef -) arrayBase:ref:char
+    stind.unc:chr constValue ((tau1,tau2,tau3)) -) [arrayBase]
+    stvar     startIndex -) index:int32
+    GOTO .loopNode1
+
+    label .loopNode1
+    ldvar     index -) tmpIndex:int32
+    if cge.i4  tmpIndex, fillBound goto .loopExit
+    GOTO .node2
+
+    label .loopNode2
+    chkub tmpIndex .lt. arrayBound -) tau2:tau
+    GOTO .node3
+
+    label .loopNode3
+    addindex  arrayBase, tmpIndex -) address:ref:char
+    stind.unc:chr constValue ((tau1,tau2,tau3)) -) [address]
+    add   tmpIndex, addOp -) inc:int32
+    stvar     inc -) index:int32
+    GOTO .node1
+    
+    */
+
     for(StlMap<Node *, LoopEdges>::const_iterator it = loopInfo.begin(); it != loopInfo.end(); ++it) {
 
         Edge * backEdge = it->second.backEdge;
@@ -103,6 +177,7 @@
         Inst * inst = ((Inst *)startNode->getLastInst());
         bool found = false;
 
+
         //check StVar
         if (inst->getOpcode() == Op_StVar) {
             index = inst->getDst();
@@ -210,49 +285,73 @@
         inEdge = startNode->getInEdges().front();
 
         //get a new constant
-        int val = ((ConstInst*)constValue->getInst())->getValue().i4;
+#ifdef _EM64T_
+        int64 val = (int64)((ConstInst*)constValue->getInst())->getValue().i8;
+#else
+        int32 val = (int32)((ConstInst*)constValue->getInst())->getValue().i4;
+#endif
         switch (((Type*)arrayRef->getType()->asArrayType()->getElementType())->tag) {
             case Type::Int8:
             case Type::Boolean:
             case Type::UInt8:
                 val |= (val << 8);
                 val |= (val << 16);
+#ifdef _EM64T_
+                val |= (val << 32);
+#endif
                 break;
             case Type::Int16:
             case Type::UInt16:
             case Type::Char:
                 val |= (val << 16);
+#ifdef _EM64T_
+                val |= (val << 32);
+#endif
                 break;
             case Type::Int32:
             case Type::UInt32:
+#ifdef _EM64T_
+                val |= (val << 32);
+                break;
+#endif
             case Type::UIntPtr:
             case Type::IntPtr:
+#ifdef _EM64T_
+            case Type::UInt64:
+            case Type::Int64:
+#endif
                 break;
             default:
                 continue;
         }
 
+        //split node1 (see code pattern) after arraylen instruction 
+        //and insert a check whether fillBound is equal to arrayBound.
+        //if not equal then go to the regular loop
         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);
 
+        //create a node with some instructions to prepare variables for loop
         Node * prepNode = fg.createBlockNode(irManager.getInstFactory().makeLabel());
         fg.addEdge(startNode,prepNode);
         
         OpndManager& opndManager = irManager.getOpndManager();
 
-        Opnd * copyOp = opndManager.createArgOpnd(irManager.getTypeManager().getInt32Type());
+        Opnd * copyOp = opndManager.createArgOpnd(irManager.getTypeManager().getIntPtrType());
         Inst * copyInst  = irManager.getInstFactory().makeLdConst(copyOp,val);
         prepNode->appendInst(copyInst);
 
+        //insert ldbase instruction
         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
+        // insert the helper.
+        // this helper should be expanded in the code generator phase
         Inst* initInst = irManager.getInstFactory().makeJitHelperCall(
             OpndManager::getNullOpnd(), FillArrayWithConst, 4, args);
         prepNode->appendInst(initInst);