harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From var...@apache.org
Subject svn commit: r478177 - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src: codegenerator/ codegenerator/ia32/ optimizer/ translator/ translator/java/
Date Wed, 22 Nov 2006 14:53:27 GMT
Author: varlax
Date: Wed Nov 22 06:53:25 2006
New Revision: 478177

URL: http://svn.apache.org/viewvc?view=rev&rev=478177
Log:
Applied HARMONY-2247 [drlvm][jit][performance] System::arraycopy by 'rep move' instruction.
Tested on SUSE9, observed ~20% gain in default mode (no -Djit options).

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
    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/optimizer/CodeGenerator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Wed Nov 22 06:53:25
2006
@@ -156,7 +156,9 @@
 class IntrinsicCallOp {
 public:
     enum Id {
-        CharArrayCopy
+        CharArrayCopy,
+        ArrayCopyDirect,
+        ArrayCopyReverse
     };
 };
 
@@ -267,6 +269,8 @@
                                                 NamedType* vtableType) = 0;
     virtual CG_OpndHandle*  call(uint32 numArgs, CG_OpndHandle** args, Type* retType,
                                  MethodDesc *desc, InlineInfo* ii = NULL) = 0;
+    virtual CG_OpndHandle*  arraycopyReverse(uint32 numArgs, CG_OpndHandle** args) = 0;
+    virtual CG_OpndHandle*  arraycopy(uint32 numArgs, CG_OpndHandle** args) = 0;
     virtual CG_OpndHandle*  tau_call(uint32 numArgs, CG_OpndHandle** args, Type* retType,
                                      MethodDesc *desc,
                                      CG_OpndHandle *tauNullChecked,
@@ -345,6 +349,7 @@
     virtual CG_OpndHandle*  ldStaticAddr(Type* fieldRefType,FieldDesc *desc) = 0;
     virtual CG_OpndHandle*  ldElemBaseAddr(CG_OpndHandle* array) = 0;
     virtual CG_OpndHandle*  addElemIndex(Type*, CG_OpndHandle *elemBase,CG_OpndHandle* index)
= 0;
+    virtual CG_OpndHandle*  addElemIndexWithLEA(Type*, CG_OpndHandle *elemBase,CG_OpndHandle*
index) = 0;
     virtual CG_OpndHandle*  ldElemAddr(CG_OpndHandle* array,CG_OpndHandle* index) = 0;
     // COMPRESSED_PTR note: 
     // if we are using compressed references, and ptr is Ptr<CompressedRef>, then

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp Wed Nov
22 06:53:25 2006
@@ -276,9 +276,7 @@
             break;
         }
     }
-    if (inst->getId() == 12) {
-   //     raise(SIGTRAP);
-    }
+
     return (uint8*)EncoderBase::encode((char*)stream, mnemonic, args);
 }
 

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp Wed
Nov 22 06:53:25 2006
@@ -439,7 +439,16 @@
             int32 offset = MPTR_OFFSET_UNKNOWN;
             assert(fromOpnd->getType()->isObject() || fromOpnd->getType()->isManagedPtr());
             uint32 useIndex2 = opnds.next(useIndex1);
-            if (useIndex2 < opnds.end()) {
+            if (inst->getMnemonic() == Mnemonic_LEA) {
+                assert(fromOpnd->isPlacedIn(OpndKind_Memory));
+                Opnd* scaleOpnd = fromOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Scale);
+                if (scaleOpnd == NULL) {
+                    Opnd* displOpnd = fromOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Displacement);
+                    assert(displOpnd!=NULL);
+                    offset = (int32)displOpnd->getImmValue();
+                }
+                fromOpnd = fromOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Base);
+            } else if (useIndex2 < opnds.end()) {
                 Opnd* offsetOpnd = inst->getOpnd(useIndex2); 
                 offset = getOffsetFromImmediate(offsetOpnd);
             }
@@ -449,7 +458,10 @@
     } else { // mode == MODE_2_CALC_OFFSETS   - 2 addr form
         //we can't rely on base/mptr type info here.
         //algorithm:
-        if (inst->hasKind(Inst::Kind_ControlTransferInst)) {
+        if (inst->hasKind(Inst::Kind_ControlTransferInst) ||
+            inst->getMnemonic() == Mnemonic_MOVS8         ||
+            inst->getMnemonic() == Mnemonic_MOVS16        ||
+            inst->getMnemonic() == Mnemonic_MOVS32        ) {
             //Do nothing, calls return only bases
         } else {
             Opnd* fromOpnd = NULL;
@@ -491,6 +503,7 @@
                         } else {
                             offset = MPTR_OFFSET_UNKNOWN;
                         }
+                        fromOpnd = fromOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Base);
                     }
                     break;
                 default: assert(0);
@@ -501,7 +514,7 @@
             if (fromPair != NULL || offset!=0)  {//opnd is mptr -> update pairs
                 updateMptrInfoInPairs(res, opnd, fromOpnd, offset,  fromPair == NULL);
             } else {
-                //new def of base -> we must to remove all pairs where opnd acts as base
or mptr 
+                //new def of base -> we must remove all pairs where opnd acts as base
or mptr 
                 //the problem is that in MODE2 we do not save info about bases (no ambiguity
resolution is done) 
                 //so we can't match pairs where opnd is a base. 
                 //Solution: let pairs derived from this base to live, due to the fact that


Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp Wed Nov
22 06:53:25 2006
@@ -1750,6 +1750,10 @@
                             stackDepth+=getByteSize(inst->getOpnd(it)->getSize());
                         } else if (inst->getMnemonic() == Mnemonic_POP) {
                             stackDepth-=getByteSize(inst->getOpnd(it)->getSize());
+                        } else if (inst->getMnemonic() == Mnemonic_PUSHFD) {
+                            stackDepth+=4;
+                        } else if (inst->getMnemonic() == Mnemonic_POPFD) {
+                            stackDepth-=4;
                         } else if (inst->getMnemonic() == Mnemonic_CALL && ((CallInst
*)inst)->getCallingConventionClient().getCallingConvention()->calleeRestoresStack())
{
                             stackDepth -= ((CallInst *)inst)->getArgStackDepth();
                         }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h Wed Nov 22 06:53:25
2006
@@ -697,7 +697,22 @@
 
     /** Returns true if the instruction has side effect not described by its operands */
     virtual bool hasSideEffect()const
-    { return false; }
+    { 
+        Mnemonic m = getMnemonic();
+        if(m==Mnemonic_MOVS8  ||
+           m==Mnemonic_MOVS16 ||
+           m==Mnemonic_MOVS32 ||
+           m==Mnemonic_STD    ||
+           m==Mnemonic_CLD    ||
+           m==Mnemonic_POPFD  ||
+           m==Mnemonic_PUSHFD ||
+           m==Mnemonic_POP    ||
+           m==Mnemonic_PUSH   )
+        {
+            return true;
+        }
+        return false;
+    }
 
     /* Checks that inst is valid*/
     virtual void verify() const { assert(node!=NULL);}

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
(original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
Wed Nov 22 06:53:25 2006
@@ -1845,6 +1845,43 @@
 //_______________________________________________________________________________________________________________
 //  Compute address of the array element given 
 //  address of the first element and index
+//  using 'LEA' instruction
+
+CG_OpndHandle*  InstCodeSelector::addElemIndexWithLEA(Type          * eType,
+                                                      CG_OpndHandle * array,
+                                                      CG_OpndHandle * index) 
+{
+    ArrayType * arrayType=((Opnd*)array)->getType()->asArrayType();
+    Type * elemType=arrayType->getElementType();
+    Type * dstType=irManager.getManagedPtrType(elemType);
+
+    uint32 elemSize = getByteSize(irManager.getTypeSize(elemType));
+
+    
+#ifdef _EM64T_
+    Type * indexType = typeManager.getInt64Type();
+    Type * offType = typeManager.getInt64Type();
+#else
+    Type * indexType = typeManager.getInt32Type();
+    Type * offType = typeManager.getInt32Type();
+#endif
+        
+    Opnd * indexOpnd = (Opnd *)index;
+    indexOpnd = convert(indexOpnd, indexType);
+    
+    Opnd * addr = irManager.newMemOpnd(dstType,(Opnd*)array, (Opnd*)index,
+                                       irManager.newImmOpnd(indexType, elemSize),
+                                       irManager.newImmOpnd(offType, arrayType->getArrayElemOffset())
+                                       );
+    Opnd * dst = irManager.newOpnd(dstType);
+    appendInsts(irManager.newInstEx(Mnemonic_LEA, 1, dst, addr));
+    return dst;
+}
+
+//_______________________________________________________________________________________________________________
+//  Compute address of the array element given 
+//  address of the first element and index
+//  using 'ADD' instruction
 
 CG_OpndHandle*  InstCodeSelector::addElemIndex(Type          * eType,
                                                CG_OpndHandle * elemBase,
@@ -2505,6 +2542,107 @@
                                          InlineInfo*       ii)
 {
     return tau_call(numArgs, args, retType, desc, getTauUnsafe(), getTauUnsafe());
+}
+
+//_______________________________________________________________________________________________________________
+//  reverse copying with 'rep move' instruction
+//  start indexes (args[1] and args[3] must be prepared respectively)
+
+CG_OpndHandle* InstCodeSelector::arraycopyReverse(uint32          numArgs, 
+                                                  CG_OpndHandle** args)
+{
+
+
+    appendInsts(irManager.newInst(Mnemonic_PUSHFD));
+    appendInsts(irManager.newInst(Mnemonic_STD));
+
+    arraycopy(numArgs,args);
+
+    appendInsts(irManager.newInst(Mnemonic_POPFD));
+
+    return NULL;
+}
+
+//_______________________________________________________________________________________________________________
+//  Transforming System::arraycopy call into 'rep move'
+
+CG_OpndHandle* InstCodeSelector::arraycopy(uint32          numArgs, 
+                                           CG_OpndHandle** args)
+{
+    assert(numArgs == 5);
+    
+#ifdef _EM64T_
+    RegName counterRegName = RegName_RCX;
+    RegName srcAddrRegName = RegName_RSI;
+    RegName dstAddrRegName = RegName_RDI;
+#else
+    RegName counterRegName = RegName_ECX;
+    RegName srcAddrRegName = RegName_ESI;
+    RegName dstAddrRegName = RegName_EDI;
+#endif
+
+    // prepare counter
+    Type* counterType = typeManager.getInt32Type();
+    Opnd* counter = irManager.newRegOpnd(counterType,counterRegName);
+    copyOpnd(counter,(Opnd*)args[4]);
+
+    // prepare src position
+    Opnd* srcAddr = (Opnd*)addElemIndexWithLEA(NULL,args[0],args[1]);
+    Opnd* srcAddrReg = irManager.newRegOpnd(srcAddr->getType(),srcAddrRegName);
+    copyOpnd(srcAddrReg,srcAddr);
+
+    // prepare dst position
+    Opnd* dstAddr = (Opnd*)addElemIndexWithLEA(NULL,args[2],args[3]);
+    Opnd* dstAddrReg = irManager.newRegOpnd(dstAddr->getType(),dstAddrRegName);
+    copyOpnd(dstAddrReg,dstAddr);
+
+    // double counter if elem type is 64 bits long
+    PtrType* srcAddrType = srcAddr->getType()->asPtrType();
+    assert(srcAddrType);
+    Type::Tag tag = srcAddrType->getPointedToType()->tag;
+    Mnemonic mn = Mnemonic_NULL;
+    switch(tag) {
+        case Type::Int8   :
+        case Type::UInt8  :
+        case Type::Boolean:
+        {
+            mn = Mnemonic_MOVS8; break;
+        }
+        case Type::Char   :
+        case Type::Int16  :
+        case Type::UInt16 :
+        {
+            mn = Mnemonic_MOVS16; break;
+        }
+        case Type::IntPtr :
+        case Type::Int32  :
+        case Type::UIntPtr:
+        case Type::UInt32 :
+        case Type::Single :
+        case Type::Float  : 
+        case Type::Object  : 
+        case Type::SystemObject  : 
+        case Type::SystemString  : 
+        case Type::Array  : 
+        {
+            mn = Mnemonic_MOVS32; break;
+        }
+        case Type::Int64  :
+        case Type::UInt64 :
+        case Type::Double :
+        {
+            appendInsts(irManager.newInst(Mnemonic_SHL, counter, irManager.newImmOpnd(counterType,
(int32)1)));
+            mn = Mnemonic_MOVS32; break;
+        }
+    default:
+        assert(0);
+        mn = Mnemonic_MOVS32; break;
+    }
+
+    Inst* copyInst = irManager.newInst(mn,dstAddrReg,srcAddrReg,counter);
+    copyInst->setPrefix(InstPrefix_REP);
+    appendInsts(copyInst);
+    return NULL;
 }
 
 //_______________________________________________________________________________________________________________

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h
(original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h
Wed Nov 22 06:53:25 2006
@@ -156,6 +156,7 @@
     CG_OpndHandle* ldStaticAddr(Type* fieldRefType,FieldDesc *desc); 
     CG_OpndHandle* ldElemBaseAddr(CG_OpndHandle *array);
     CG_OpndHandle* addElemIndex(Type*, CG_OpndHandle *elemBase,CG_OpndHandle* index);
+    CG_OpndHandle* addElemIndexWithLEA(Type*, CG_OpndHandle *elemBase,CG_OpndHandle* index);
     CG_OpndHandle* ldElemAddr(CG_OpndHandle* array,CG_OpndHandle* index) {
         return addElemIndex(NULL,ldElemBaseAddr(array),index);
     }
@@ -215,6 +216,8 @@
                              CG_OpndHandle* tauTypesChecked, InlineInfo* ii = NULL);
     CG_OpndHandle* call(uint32 numArgs, CG_OpndHandle** args, Type* retType,
                         MethodDesc *desc, InlineInfo* ii = NULL);
+    CG_OpndHandle* arraycopyReverse(uint32 numArgs, CG_OpndHandle** args);
+    CG_OpndHandle* arraycopy(uint32 numArgs, CG_OpndHandle** args);
     CG_OpndHandle* tau_call(uint32 numArgs, CG_OpndHandle** args, Type* retType,
                             MethodDesc *desc, CG_OpndHandle *nonNullFirstArgTau,
                             CG_OpndHandle *tauTypesChecked, InlineInfo* ii = NULL);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp Wed Nov 22 06:53:25
2006
@@ -428,7 +428,9 @@
     //
     IntrinsicCallOp::Id convertIntrinsicId(IntrinsicCallId callId) {
         switch(callId) {
-        case CharArrayCopy: return IntrinsicCallOp::CharArrayCopy;
+        case CharArrayCopy:      return IntrinsicCallOp::CharArrayCopy;
+        case ArrayCopyDirect:    return IntrinsicCallOp::ArrayCopyDirect;
+        case ArrayCopyReverse:   return IntrinsicCallOp::ArrayCopyReverse;
         }
         assert(0);
         return IntrinsicCallOp::CharArrayCopy; // to keep compiler quiet
@@ -894,13 +896,29 @@
                 IntrinsicCallInst * call = (IntrinsicCallInst *)inst;
                 IntrinsicCallId callId = call->getIntrinsicId();
 
-                cgInst = 
-                    instructionCallback.tau_callintr(inst->getNumSrcOperands()-2, // omit
taus
-                                                     genCallArgs(call,2), // omit taus
-                                                     inst->getDst()->getType(),
-                                                     convertIntrinsicId(callId),
-                                                     getCGInst(tauNullChecked),
-                                                     getCGInst(tauTypesChecked));
+                if (callId == ArrayCopyDirect)
+                {
+                    cgInst = 
+                        instructionCallback.arraycopy(inst->getNumSrcOperands()-2, //
omit taus
+                                                      genCallArgs(call,2) // omit taus
+                                                     );
+                } else if (callId == ArrayCopyReverse)
+                {
+                    cgInst = 
+                        instructionCallback.arraycopyReverse(inst->getNumSrcOperands()-2,
// omit taus
+                                                             genCallArgs(call,2) // omit
taus
+                                                            );
+                } else {
+
+                    cgInst = 
+                        instructionCallback.tau_callintr(inst->getNumSrcOperands()-2,
// omit taus
+                                                         genCallArgs(call,2), // omit taus
+                                                         inst->getDst()->getType(),
+                                                         convertIntrinsicId(callId),
+                                                         getCGInst(tauNullChecked),
+                                                         getCGInst(tauTypesChecked));
+                }
+   
             }
             break;
         case Op_JitHelperCall:

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Wed Nov 22 06:53:25 2006
@@ -438,6 +438,10 @@
         switch(intrinsicId) {
         case CharArrayCopy:
             os << "charArrayCopy"; break;
+        case ArrayCopyDirect:
+            os << "ArrayCopyDirect"; break;
+        case ArrayCopyReverse:
+            os << "ArrayCopyReverse"; 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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Wed Nov 22 06:53:25 2006
@@ -264,7 +264,9 @@
 };
 
 enum IntrinsicCallId {
-    CharArrayCopy
+    CharArrayCopy,
+    ArrayCopyDirect,
+    ArrayCopyReverse
 };
 
 enum JitHelperCallId {

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=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Wed Nov 22 06:53:25
2006
@@ -624,6 +624,8 @@
             IntrinsicCallId callId = calli->getIntrinsicId();
             switch (callId) {
             case CharArrayCopy:
+            case ArrayCopyDirect:
+            case ArrayCopyReverse:
                 {
                     assert(calli->getNumSrcOperands() == 7);
 #ifndef NDEBUG
@@ -638,6 +640,8 @@
                     Opnd *dstoffset = calli->getSrc(5);
                     Opnd *length = calli->getSrc(6);
 
+                    // effectXXXArrayElements actually does not depends on offset parameter
+                    // so we do not need any special managing for the case of reverse copying
                     thePass->effectReadArrayLength(n, i, srcarray);
                     thePass->effectReadArrayElements(n, i, srcarray, srcoffset, length);
                     thePass->effectReadArrayLength(n, i, dstarray);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp Wed Nov 22
06:53:25 2006
@@ -87,7 +87,8 @@
     "  propValues[={ON|off}]    -  propagate values during translation\n"\
     "  guardedInlining[={on|OFF}]  - do guarded inlining during translation\n"\
     "  genCharArrayCopy[={on|off}] - generate intrinsic calls to char array copy\n"\
-    "  genArrayCopy[={ON|off}] - inline java/lang/System::arraycopy call\n"\
+    "  genArrayCopy[={ON|off}] - inline java/lang/System::arraycopy call as a copying loop\n"\
+    "  genArrayCopyRepMove[={ON|off}] - inline java/lang/System::arraycopy call as 'rep move'
instruction\n"\
     "  balancedSync[={on|OFF}] - treat all synchronization as balanced\n"\
     "  ignoreSync[={on|OFF}]   - do not generate synchronization\n"\
     "  syncAsEnterFence[={on|OFF}] - implement synchronization as monitor enter fence\n"\
@@ -115,7 +116,8 @@
     flags.genCharArrayCopy = getBoolArg("genCharArrayCopy", false); 
     flags.optArrayInit = getBoolArg("optArrayInit", true);
 #endif
-    flags.genArrayCopy = getBoolArg("genArrayCopy", true); 
+    flags.genArrayCopy = getBoolArg("genArrayCopy", false); 
+    flags.genArrayCopyRepMove = getBoolArg("genArrayCopyRepMove", true);
     flags.onlyBalancedSync = getBoolArg("balancedSync", false);
 
     flags.ignoreSync       = getBoolArg("ignoreSync",false);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h Wed Nov 22 06:53:25
2006
@@ -49,18 +49,19 @@
 
     // to select which byte code translator optimizations are done
 struct TranslatorFlags {
-    bool propValues       : 1;    // do value propagation
-    bool inlineMethods    : 1;    // do method inlining
-    bool guardedInlining  : 1;    // a step further for inlining
-    bool genCharArrayCopy : 1;    // generate intrinsic calls to CharArrayCopy
-    bool genArrayCopy     : 1;    // inline java/lang/System::arraycopy call
-    bool onlyBalancedSync : 1;    // treat all method synchronization as balanced
-    bool ignoreSync       : 1;    // do not generate monitor enter/exit instructions
-    bool syncAsEnterFence : 1;    // implement monitor enter as enter fence and
-    bool newCatchHandling : 1;    // use fix for catch handler ordering problem
-    bool genMinMaxAbs     : 1;    // gen min/max/abs opcodes instead of using select
-    bool genFMinMaxAbs    : 1;    // gen min/max/abs opcodes for floats
-    bool optArrayInit     : 1;    // skip array initializers from optimizations
+    bool propValues         : 1;    // do value propagation
+    bool inlineMethods      : 1;    // do method inlining
+    bool guardedInlining    : 1;    // a step further for inlining
+    bool genCharArrayCopy   : 1;    // generate intrinsic calls to CharArrayCopy
+    bool genArrayCopy       : 1;    // inline java/lang/System::arraycopy call as a copying
loop
+    bool genArrayCopyRepMove: 1;    // inline java/lang/System::arraycopy call as 'rep move'
instruction
+    bool onlyBalancedSync   : 1;    // treat all method synchronization as balanced
+    bool ignoreSync         : 1;    // do not generate monitor enter/exit instructions
+    bool syncAsEnterFence   : 1;    // implement monitor enter as enter fence and
+    bool newCatchHandling   : 1;    // use fix for catch handler ordering problem
+    bool genMinMaxAbs       : 1;    // gen min/max/abs opcodes instead of using select
+    bool genFMinMaxAbs      : 1;    // gen min/max/abs opcodes for floats
+    bool optArrayInit       : 1;    // skip array initializers from optimizations
     Method_Table* inlineSkipTable; // do not inline these methods
 };
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
(original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
Wed Nov 22 06:53:25 2006
@@ -2013,10 +2013,13 @@
         returnType = typeManager.getNullObjectType();
     }
     //
-    //  Try to match to charArrayCopy
+    //  Try some optimizations for System::arraycopy(...), Min, Max, Abs...
     //
-    if (translationFlags.genArrayCopy == true &&
-        genArrayCopy(methodDesc,numArgs,srcOpnds,returnType)) {
+    if (translationFlags.genArrayCopyRepMove == true &&
+        genArrayCopyRepMove(methodDesc,numArgs,srcOpnds)) {
+        return;
+    } else if (translationFlags.genArrayCopy == true &&
+        genArrayCopy(methodDesc,numArgs,srcOpnds)) {
         return;
     } else if (translationFlags.genCharArrayCopy == true &&
         genCharArrayCopy(methodDesc,numArgs,srcOpnds,returnType)) {
@@ -2699,18 +2702,16 @@
 }
 
 bool
-JavaByteCodeTranslator::genArrayCopy(MethodDesc * methodDesc, 
-                                     uint32       numArgs,
-                                     Opnd **      srcOpnds,
-                                     Type *       returnType) {
+JavaByteCodeTranslator::methodIsArraycopy(MethodDesc * methodDesc) {
 
-    //
-    //  Check if method is java/lang/System.arraycopy
-    //  (Object src, int srcPos, Object dst, int dstPos, int len)
-    //
-    if (strcmp(methodDesc->getName(),"arraycopy") != 0 ||
-        strcmp(methodDesc->getParentType()->getName(),"java/lang/System") !=0)
-          return false;
+    return (strcmp(methodDesc->getName(),"arraycopy") == 0 &&
+            strcmp(methodDesc->getParentType()->getName(),"java/lang/System") ==0);
+}
+
+bool
+JavaByteCodeTranslator::arraycopyOptimizable(MethodDesc * methodDesc, 
+                                             uint32       numArgs,
+                                             Opnd **      srcOpnds) {
 
     //
     //  an ArrayStoreException is thrown and the destination is not modified: 
@@ -2725,19 +2726,14 @@
     //
     assert(numArgs == 5);
     Opnd * src = srcOpnds[0];
-    Opnd * srcPos = srcOpnds[1];
     Type * srcType = src->getType();
-    Type * srcPosType = srcPos->getType();
     Opnd * dst = srcOpnds[2];
-    Opnd * dstPos = srcOpnds[3];
     Type * dstType = dst->getType();
-    Type * dstPosType = dstPos->getType();
-    Opnd * len = srcOpnds[4];
     assert(srcType->isObject() &&
-           srcPosType->isInt4() &&
+           srcOpnds[1]->getType()->isInt4() && // 1 - srcPos
            dstType->isObject() &&
-           dstPosType->isInt4() &&
-           len->getType()->isInt4());
+           srcOpnds[3]->getType()->isInt4() && // 3 - dstPos
+           srcOpnds[4]->getType()->isInt4());  // 4 - length
 
     bool throwsASE = false;
     bool srcIsArray = srcType->isArray();
@@ -2762,11 +2758,190 @@
         throwsASE = ! typeManager.isSubClassOf(srcElemType->getVMTypeHandle(),dstElemType->getVMTypeHandle());
     }
     if ( throwsASE )
-        return false; // reject the inlining of System::arraycopy call
+        return false;
+    else
+        return true;
+}
+
+bool
+JavaByteCodeTranslator::genArrayCopyRepMove(MethodDesc * methodDesc, 
+                                            uint32       numArgs,
+                                            Opnd **      srcOpnds) {
+
+    if( !methodIsArraycopy(methodDesc) ||
+        !arraycopyOptimizable(methodDesc,numArgs,srcOpnds) )
+    {
+        // reject the inlining of System::arraycopy call
+        return false;
+    }
+
+    if (Log::isEnabled()) {
+        Log::out() << "XXX array copy into 'rep move': ";
+        methodDesc->printFullName(Log::out());
+        Log::out() << ::std::endl;
+    }
+
+    assert(numArgs == 5);
+    Opnd * src = srcOpnds[0];
+    Opnd * srcPos = srcOpnds[1];
+    Type * srcPosType = srcPos->getType();
+    Opnd * dst = srcOpnds[2];
+    Opnd * dstPos = srcOpnds[3];
+    Type * dstPosType = dstPos->getType();
+    Opnd * len = srcOpnds[4];
+
+    //
+    //  Generate exception condition checks:
+    //      chknull src
+    //      chknull dst
+    //      cmpbr srcPos < 0, boundsException
+    //      cmpbr dstPos < 0, boundsException
+    //      cmpbr len < 0, boundsException
+    //      srcEnd = add srcPos, len
+    //      srcLen = src.length
+    //      cmpbr srcEnd > srcLen, boundsException
+    //      dstEnd = add dstPos, len
+    //      dstLen = dst.length
+    //      cmpbr dstEnd > dstLen, boundsException
+    //  Skip trivial:
+    //      cmpbr (src == dst) && (dstPos == srcPos), Exit
+    //  Choose a direction:
+    //      cmpbr (dstPos > srcPos) && (src == dst), Reverse
+    //
+    //  Intrinsic calls will be codeselected into rep move instruction.
+    //  Direct:
+    //      IntrinsicCall id=ArrayCopyDirect
+    //      goto Exit
+    //  Reverse:
+    //      srcPos = srcPos + len - 1
+    //      dstPos = dstPos + len - 1
+    //      IntrinsicCall id=ArrayCopyReverse
+    //      goto Exit
+    //
+    //  boundsException:
+    //      chkbounds -1, src
+    //  Exit:
+    //
+    Opnd *tauSrcNullChecked = irBuilder.genTauCheckNull(src);
+    Opnd *tauDstNullChecked = irBuilder.genTauCheckNull(dst);
+    Opnd *tauNullCheckedRefArgs = irBuilder.genTauAnd(tauSrcNullChecked,tauDstNullChecked);
+    
+    LabelInst * reverseCopying = irBuilder.createLabel();
+    LabelInst * boundsException = irBuilder.createLabel();
+    LabelInst * Exit = irBuilder.createLabel();
+    Type * intType = typeManager.getInt32Type();
+    Type * voidType = typeManager.getVoidType();
+
+    newFallthroughBlock();
+    Opnd * zero = irBuilder.genLdConstant((int32)0);
+    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,srcPos);        
+
+    newFallthroughBlock();
+    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,dstPos);
+
+    newFallthroughBlock();
+    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,len);
+
+    Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
+
+    newFallthroughBlock();   
+    Opnd * srcLen = irBuilder.genArrayLen(intType,Type::Int32,src);
+    Opnd * srcEnd = irBuilder.genAdd(intType,mod,srcPos,len);
+    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,srcEnd,srcLen);
+    
+    newFallthroughBlock();
+    Opnd * dstEnd = irBuilder.genAdd(intType,mod,dstPos,len);
+    Opnd * dstLen = irBuilder.genArrayLen(intType,Type::Int32,dst);
+    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,dstEnd,dstLen);
+
+    newFallthroughBlock();
+
+    // The case of same arrays and same positions
+    Opnd * diff = irBuilder.genCmp3(intType,Type::Int32,Cmp_GT,dstPos,srcPos);
+    Opnd * sameArrays = irBuilder.genCmp(intType,Type::IntPtr,Cmp_EQ,src,dst);
+    Opnd * zeroDiff = irBuilder.genCmp(intType,Type::Int32,Cmp_EQ,diff,zero);
+    Opnd * nothingToCopy = irBuilder.genAnd(intType,sameArrays,zeroDiff);
+    irBuilder.genBranch(Type::Int32,Cmp_GT,Exit,nothingToCopy,zero);
+
+    newFallthroughBlock();
+
+    Opnd* tauTypesChecked = irBuilder.genTauSafe();
+
+    // Choosing direction
+    Opnd * dstIsGreater = irBuilder.genCmp(intType,Type::Int32,Cmp_GT,diff,zero);
+    Opnd * reverseCopy = irBuilder.genAnd(intType,sameArrays,dstIsGreater);
+    irBuilder.genBranch(Type::Int32,Cmp_GT,reverseCopying,reverseCopy,zero);
+
+    newFallthroughBlock();
+
+    {   // Direct Copying
+    irBuilder.genIntrinsicCall(ArrayCopyDirect,voidType,
+                               tauNullCheckedRefArgs,
+                               tauTypesChecked,
+                               numArgs,srcOpnds);
+    irBuilder.genJump(Exit);
+    }   // End of Direct Copying
+
+    irBuilder.genLabel(reverseCopying);
+    cfgBuilder.genBlockAfterCurrent(reverseCopying);
+    {   // Reverse Copying
+
+    Opnd* minusone = irBuilder.genLdConstant((int32)-1);
+    Opnd* lastSrcIdx = irBuilder.genAdd(srcPosType,mod,srcEnd,minusone);
+    Opnd* lastDstIdx = irBuilder.genAdd(dstPosType,mod,dstEnd,minusone);
+
+    Opnd** reverseArgs = new (memManager) Opnd*[numArgs];
+    reverseArgs[0] = srcOpnds[0]; // src
+    reverseArgs[1] = lastSrcIdx;  // srcPos+len-1
+    reverseArgs[2] = srcOpnds[2]; // dst
+    reverseArgs[3] = lastDstIdx;  // dstPos+len-1
+    reverseArgs[4] = srcOpnds[4]; // len
+    // copy
+    irBuilder.genIntrinsicCall(ArrayCopyReverse,voidType,
+                               tauNullCheckedRefArgs,
+                               tauTypesChecked,
+                               numArgs,reverseArgs);
+    irBuilder.genJump(Exit);
+    }   // End of Reverse Copying
+
+    irBuilder.genLabel(boundsException);
+    cfgBuilder.genBlockAfterCurrent(boundsException);
+    Opnd * minusOne = irBuilder.genLdConstant((int32)-1);
+    irBuilder.genTauCheckBounds(src,minusOne,tauSrcNullChecked);
+
+    irBuilder.genLabel(Exit);
+    cfgBuilder.genBlockAfterCurrent(Exit);
+
+    return true;
+}
+
+bool
+JavaByteCodeTranslator::genArrayCopy(MethodDesc * methodDesc, 
+                                     uint32       numArgs,
+                                     Opnd **      srcOpnds) {
+
+    if( !methodIsArraycopy(methodDesc) ||
+        !arraycopyOptimizable(methodDesc,numArgs,srcOpnds) )
+    {
+        // reject the inlining of System::arraycopy call
+        return false;
+    }
 
     if (Log::isEnabled()) {
         Log::out() << "XXX array copy: "; methodDesc->printFullName(Log::out());
Log::out() << ::std::endl;
     }
+
+    assert(numArgs == 5);
+    Opnd * src = srcOpnds[0];
+    Type * srcType = src->getType();
+    Opnd * srcPos = srcOpnds[1];
+    Type * srcPosType = srcPos->getType();
+    Opnd * dst = srcOpnds[2];
+    Type * dstType = dst->getType();
+    Opnd * dstPos = srcOpnds[3];
+    Type * dstPosType = dstPos->getType();
+    Opnd * len = srcOpnds[4];
+
     //
     //  Generate exception condition checks:
     //      chknull src

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h?view=diff&rev=478177&r1=478176&r2=478177
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h Wed
Nov 22 06:53:25 2006
@@ -317,8 +317,12 @@
     void    genInvokeStatic(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds,Type
* returnType);
     void    genMagic(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds,Type * returnType);
     
+    bool    methodIsArraycopy(MethodDesc * methodDesc);
+    bool    arraycopyOptimizable(MethodDesc * methodDesc, uint32 numArgs, Opnd ** srcOpnds);
+
     bool    genCharArrayCopy(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds, Type
* returnType);
-    bool    genArrayCopy(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds, Type *
returnType);
+    bool    genArrayCopyRepMove(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds);
+    bool    genArrayCopy(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds);
     bool    genMinMax(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds, Type * returnType);
     void    newFallthroughBlock();
 



Mime
View raw message