harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r467429 - in /incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer: devirtualizer.cpp devirtualizer.h optimizer.cpp optimizer.h
Date Tue, 24 Oct 2006 18:20:44 GMT
Author: geirm
Date: Tue Oct 24 11:20:43 2006
New Revision: 467429

URL: http://svn.apache.org/viewvc?view=rev&rev=467429
Log:
HARMONY-1754

This patch contains the following changes:
1) All previously hardcoded parameters used by devirt and unguard optimization passes could
be set up from command 
line.
2) Unguard pass is usable from now. Now it processes edge profile correctly. I hope we add
profile guided unguarding 
to the server path after this fix commited. It shows ~1-2% performance improvement on some
benchmarks.
3) Profile guided devirtualization of object (not interface) methods added

Ubuntu 6 - smoke, c-unit, ~kernel


Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp?view=diff&rev=467429&r1=467428&r2=467429
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp Tue
Oct 24 11:20:43 2006
@@ -25,6 +25,7 @@
 #include "Log.h"
 #include "Dominator.h"
 #include "inliner.h"
+#include "EMInterface.h"
 
 namespace Jitrino {
 
@@ -52,17 +53,22 @@
   _instFactory(irm.getInstFactory()), _opndManager (irm.getOpndManager()) {
     
     const OptimizerFlags& optFlags = irm.getOptimizerFlags();
-    _skipColdTargets = optFlags.devirt_skip_cold_targets;
     _doAggressiveGuardedDevirtualization = !_hasProfileInfo || optFlags.devirt_do_aggressive_guarded_devirtualization;
-    _devirtUseCHA = optFlags.devirt_devirt_use_cha;
-    _devirtSkipExceptionPath = optFlags.devirt_devirt_skip_exception_path;
+    _devirtUseCHAWithProfile = optFlags.devirt_use_cha_with_profile;
+    _devirtUseCHAWithProfileThreshold = optFlags.devirt_use_cha_with_profile_threshold;
+    _devirtSkipExceptionPath = optFlags.devirt_skip_exception_path;
+    _devirtBlockHotnessMultiplier = optFlags.devirt_block_hotness_multiplier;
+    _devirtSkipJLObjectMethods = optFlags.devirt_skip_object_methods;
+
+    _directCallPercent = optFlags.unguard_dcall_percent;
+    _directCallPercientOfEntry = optFlags.unguard_dcall_percent_of_entry;
 }
 
 bool
 Devirtualizer::isGuardableVirtualCall(Inst* inst, MethodInst*& methodInst, Opnd*&
base, Opnd*& tauNullChecked, Opnd *&tauTypesChecked, uint32 &argOffset)
 {
     //
-    // Returns true if this call site may be considered for guarded de-virtualization
+    // Returns true if this call site may be considered for guarded devirtualization
     //
     Opcode opcode = inst->getOpcode();
     if(opcode == Op_TauVirtualCall) { 
@@ -325,15 +331,17 @@
 
 bool
 Devirtualizer::doGuard(IRManager& irm, Node* node, MethodDesc& methodDesc) {
-    
-
-    if(_skipColdTargets && _hasProfileInfo && irm.getFlowGraph().getEntryNode()->getExecCount()
== 0)
-        return false;
-
     //
     // Determine if a call site should be guarded
     //
 
+    if (_devirtSkipJLObjectMethods) {
+        const char* className = methodDesc.getParentType()->getName();
+        if (!strcmp(className, "java/lang/Object")) {
+            return false;
+        }
+    }
+
     if (_doAggressiveGuardedDevirtualization) {
         // 
         // In this mode, always guard in the first pass
@@ -342,15 +350,16 @@
     }
 
     //
-    // Only de-virtualize if there's profile information for this
+    // Only devirtualize if there's profile information for this
     // node and the apparent target.
     //
-    if(!_hasProfileInfo)
+    if(!_hasProfileInfo) {
         return false;
+    }
 
     double methodCount = irm.getFlowGraph().getEntryNode()->getExecCount();
     double blockCount = node->getExecCount();
-    return (blockCount >= methodCount / 10.0);
+    return (blockCount >= methodCount / _devirtBlockHotnessMultiplier);
 }
 
 void
@@ -370,120 +379,70 @@
                                   argOffset)) {
             assert(methodInst && base && tauNullChecked && tauTypesChecked
&& argOffset);
 
-            bool done = false;
             assert(base->getType()->isObject());
             ObjectType* baseType = (ObjectType*) base->getType();
-            MethodDesc* methodDesc = methodInst->getMethodDesc();
-            // Class hierarchy analysis -- can we de-virtualize without a guard?
-            if(_devirtUseCHA && isPreexisting(base)) {
-                ClassHierarchyMethodIterator* iterator = regionIRM.getCompilationInterface().getClassHierarchyMethodIterator(baseType,
methodDesc);
-                if(iterator) {
-                    if(!baseType->isNullObject() && (!baseType->isAbstract()
|| baseType->isArray()) && !baseType->isInterface()) {
-                        methodDesc = regionIRM.getCompilationInterface().getOverriddenMethod(baseType,
methodDesc);
-                        jitrino_assert(regionIRM.getCompilationInterface(),methodDesc);
-                    }
-
-                    if(!iterator->hasNext()) {
-                        // No candidate
-                        Log::out() << "CHA no candidate " << baseType->getName()
<< "::" << methodDesc->getName() << methodDesc->getSignatureString()
<< ::std::endl;
-                        jitrino_assert(regionIRM.getCompilationInterface(),0);
-                    }
-                
-                    MethodDesc* newMethodDesc = iterator->getNext();
-                    if(!iterator->hasNext()) {
-                        // Only one candidate
-                        Log::out() << "CHA devirtualize " << baseType->getName()
<< "::" << methodDesc->getName() << methodDesc->getSignatureString()
<< ::std::endl;
-                        if(!baseType->isNullObject() && (!baseType->isAbstract()
|| baseType->isArray()) && !baseType->isInterface()) {
-                            assert(newMethodDesc == methodDesc);
-                        }
-
-                        Opnd* dst = last->getDst(); 
-                        uint32 numArgs = last->getNumSrcOperands()-argOffset;
-                        uint32 i = 0;
-                        uint32 j = argOffset;
-                        Opnd** args = new (regionIRM.getMemoryManager()) Opnd*[numArgs];
-                        for(; i < numArgs; ++i, ++j)
-                            args[i] = last->getSrc(j-argOffset);
-                        Inst* directCall = 
-                            _instFactory.makeDirectCall(dst, 
-                                                        tauNullChecked,
-                                                        tauTypesChecked,
-                                                        numArgs, args, 
-                                                        newMethodDesc);
-                        //
-                        // copy InlineInfo
-                        //
-                        InlineInfo* call_ii = last->getCallInstInlineInfoPtr();
-                        InlineInfo* new_ii = directCall->getCallInstInlineInfoPtr();
-                        assert(call_ii && new_ii);
-                        new_ii->getInlineChainFrom(*call_ii);
-
-                        last->unlink();
-                        node->appendInst(directCall);
-                        done = true;
-                    }
-                }
-            }
+            MethodDesc* origMethodDesc = methodInst->getMethodDesc();
             
             // If base type is concrete, consider an explicit guarded test against it
-            if(!done && !baseType->isNullObject() && (!baseType->isAbstract()
|| baseType->isArray()) && !baseType->isInterface()) {
-
-                NamedType* methodType = methodDesc->getParentType();
-                if (_typeManager.isSubClassOf(baseType, methodType)) {
-                    // only bother if the baseType has the given method
-                    // for an interface call, this may not be the case
-                       
-                    methodDesc =
-                        regionIRM.getCompilationInterface().getOverriddenMethod(baseType,
methodDesc);
-                    if (methodDesc) {
-                        jitrino_assert(regionIRM.getCompilationInterface(), methodDesc->getParentType()->isClass());
-                        methodInst->setMethodDesc(methodDesc);
-                        
-                        //
-                        // Try to guard this call
-                        //
-                        if(doGuard(regionIRM, node, *methodDesc)) {
-                            Log::out() << "Guard call to " << baseType->getName()
<< "::" << methodDesc->getName() << ::std::endl;
-                            genGuardedDirectCall(regionIRM, node, last, methodDesc, tauNullChecked,
-                                                 tauTypesChecked, argOffset);
-                            Log::out() << "Done guarding call to " << baseType->getName()
<< "::" << methodDesc->getName() << ::std::endl;
-                        } else {
-                            Log::out() << "Don't guard call to " << baseType->getName()
<< "::" << methodDesc->getName() << ::std::endl;
+            if(!baseType->isNullObject() && (!baseType->isAbstract() || baseType->isArray())
&& !baseType->isInterface()) {
+                MethodDesc* candidateMeth = NULL;
+                int candidateExecCount = 0;
+                CompilationContext* cc = regionIRM.getCompilationContext();
+                bool profileSelection = _devirtUseCHAWithProfile && cc->hasDynamicProfileToUse();
+                if (profileSelection) {
+                    ClassHierarchyMethodIterator* iterator = regionIRM.getCompilationInterface().getClassHierarchyMethodIterator(baseType,
origMethodDesc);
+                    if(iterator) {
+                        if (profileSelection) {
+                            ProfilingInterface* pi = cc->getProfilingInterface();
+                            while (iterator->hasNext()) {
+                                MethodDesc* tmpMeth = iterator->getNext();
+                                int tmpCount = pi->getProfileMethodCount(*tmpMeth);
+                                Log::out() << "CHA devirt profile-selection" <<
baseType->getName() << "::" << tmpMeth->getName() << tmpMeth->getSignatureString()

+                                    << " exec_count=" << tmpCount << std::endl;
+                                if (candidateExecCount < tmpCount) {
+                                    candidateExecCount = tmpCount;
+                                    candidateMeth = tmpMeth;
+                                }
+                            }
                         }
                     }
+                } else {
+                    NamedType* methodType = origMethodDesc->getParentType();
+                    if (_typeManager.isSubClassOf(baseType, methodType)) {
+                        // only bother if the baseType has the given method
+                        // for an interface call, this may not be the case
+                        candidateMeth = regionIRM.getCompilationInterface().getOverriddenMethod(baseType,
origMethodDesc);
+                    }
+                }
+                if (candidateMeth) {
+                    jitrino_assert(regionIRM.getCompilationInterface(), origMethodDesc->getParentType()->isClass());
+                    methodInst->setMethodDesc(candidateMeth);
+                    //
+                    // Try to guard this call
+                    //
+                    if(doGuard(regionIRM, node, *candidateMeth )) {
+                        Log::out() << "Guard call to " << baseType->getName()
<< "::" << candidateMeth->getName() 
+                            <<" CHAWithProfile="<<(profileSelection ? "true":"false")<<"
execCnt="<<candidateExecCount<< std::endl;
+                        genGuardedDirectCall(regionIRM, node, last, candidateMeth, tauNullChecked,
tauTypesChecked, argOffset);
+                        Log::out() << "Done guarding call to " << baseType->getName()
<< "::" << candidateMeth->getName() << std::endl;
+                    } else {
+                        Log::out() << "Don't guard call to " << baseType->getName()
<< "::" << origMethodDesc->getName() << std::endl;
+                    }
                 }
             }
         }
     }
 }
 
-bool
-Devirtualizer::isPreexisting(Opnd* obj) {
-    assert(obj->getType()->isObject());
-
-    SsaOpnd* ssa = obj->asSsaOpnd();
-    if(ssa == NULL)
-        return false;
-
-    Inst* inst = ssa->getInst();
-    switch(inst->getOpcode()) {
-    case Op_DefArg:
-        return true;
-    case Op_Copy:
-    case Op_TauAsType:
-    case Op_TauCast:
-    case Op_TauStaticCast:
-        return isPreexisting(inst->getSrc(0));
-    default:
-        return false;
-    }
-}
-
 void
-Devirtualizer::unguardCallsInRegion(IRManager& regionIRM, uint32 safetyLevel) {
+Devirtualizer::unguardCallsInRegion(IRManager& regionIRM) {
     ControlFlowGraph &regionFG = regionIRM.getFlowGraph();
-    if(!regionFG.hasEdgeProfile())
+    if(!regionFG.hasEdgeProfile()) {
+        if (Log::isEnabled()) {
+            Log::out()<<"No edge profile, skipping unguard pass"<<std::endl;
+        }
         return;
+    }
 
     //
     // Search for previously guarded virtual calls
@@ -523,34 +482,23 @@
             //
             // A guard - fold based on profile results.
             //
-            bool fold = false;
-            bool foldDirect = false;
-            if(node->getExecCount() == 0) {
-                fold = true;
-                foldDirect = false;
-            } else if(vCallNode->getExecCount() == 0) {
-                if(safetyLevel == 0) {
-                    fold = false;
-                } else if(safetyLevel == 1) {
-                    Inst* inst0 = src0->getInst();
-                    fold = (inst0->getOpcode() == Op_TauLdVTableAddr && isPreexisting(inst0->getSrc(0)));
-                } else {
-                    assert(safetyLevel == 2);
-                    fold = true;
-                }
-                foldDirect = true;
-            } else if(dCallNode->getExecCount() == 0) {
-                fold = true;
-                foldDirect = false;
-            }
+            
+            bool fold = dCallNode->getExecCount() < (node->getExecCount() * _directCallPercent
/ 100);
+            fold = fold || (dCallNode->getExecCount()  < (regionFG.getEntryNode()->getExecCount()
* _directCallPercientOfEntry / 100));
             
             if(fold) {
                 //
                 // A compile time is compared.  Later simplification will fold branch appropriately.
                 //
+                if (Log::isEnabled()) {
+                    Log::out()<<"Unguarding: instId="<<last->getId()<<std::endl;
+                }
+               
                 branch->setSrc(1, src0);
-                if(!foldDirect)
-                    branch->setComparisonModifier(Cmp_NE_Un);
+                branch->setComparisonModifier(Cmp_NE_Un);
+
+                //regionFG.removeEdge(node->getTrueEdge());
+               // branch->unlink();
             }
         }
     }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h?view=diff&rev=467429&r1=467428&r2=467429
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h Tue Oct
24 11:20:43 2006
@@ -35,7 +35,7 @@
 
     void guardCallsInRegion(IRManager& irm, DominatorTree* tree);
 
-    void unguardCallsInRegion(IRManager& irm, uint32 safetyLevel=0);
+    void unguardCallsInRegion(IRManager& irm);
 
 private:
     void guardCallsInBlock(IRManager& irm, Node* node);
@@ -44,14 +44,20 @@
                                 Opnd* & tauNullChecked, Opnd*&tauTypesChecked,
                                 uint32 &argOffset);
     bool doGuard(IRManager& irm, Node* node, MethodDesc& methodDesc);
-    bool isPreexisting(Opnd* obj);
-
+    
     bool _hasProfileInfo;
     bool _doProfileOnlyGuardedDevirtualization;
     bool _doAggressiveGuardedDevirtualization;
-    bool _skipColdTargets;
-    bool _devirtUseCHA;
+    bool _devirtUseCHAWithProfile;
+    bool _devirtUseCHAWithProfileThreshold;
     bool _devirtSkipExceptionPath;
+    float _devirtBlockHotnessMultiplier;
+    bool _devirtSkipJLObjectMethods;
+
+
+    //unguard pass params
+    int _directCallPercent;
+    int _directCallPercientOfEntry;
 
     TypeManager& _typeManager;
     InstFactory& _instFactory;

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp?view=diff&rev=467429&r1=467428&r2=467429
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp Tue Oct
24 11:20:43 2006
@@ -158,10 +158,17 @@
     optimizerFlags.gc_build_var_map = getBoolArg("gc_build_var_map", true);
 
     //devirtualizer flags
-    optimizerFlags.devirt_skip_cold_targets = getBoolArg("devirt_skip_cold", true);
     optimizerFlags.devirt_do_aggressive_guarded_devirtualization = getBoolArg("devirt_aggressive",
false);
-    optimizerFlags.devirt_devirt_use_cha = getBoolArg("devirt_use_cha", false);
-    optimizerFlags.devirt_devirt_skip_exception_path = getBoolArg("devirt_skip_exception_path",
true);
+    optimizerFlags.devirt_use_cha_with_profile = getBoolArg("devirt_use_cha_with_profile",
false);
+    optimizerFlags.devirt_use_cha_with_profile_threshold = getIntArg("devirt_use_cha_with_profile_threshold",
-1);
+    optimizerFlags.devirt_skip_exception_path = getBoolArg("devirt_skip_exception_path",
true);
+    optimizerFlags.devirt_block_hotness_multiplier= (float)getIntArg("devirt_block_hotness_multiplier",
10);
+    optimizerFlags.devirt_skip_object_methods = getBoolArg("devirt_skip_object_methods",
false);
+
+    //unguard
+    optimizerFlags.unguard_dcall_percent = getIntArg("unguard_dcall_percent", 30);
+    optimizerFlags.unguard_dcall_percent_of_entry= getIntArg("unguard_dcall_percent_of_entry",
10);
+
 
     optimizerFlags.abcdFlags = new (mm) AbcdFlags;
     memset(optimizerFlags.abcdFlags, sizeof(AbcdFlags), 0);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h?view=diff&rev=467429&r1=467428&r2=467429
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h Tue Oct 24
11:20:43 2006
@@ -91,10 +91,17 @@
     bool gc_build_var_map;
 
     //devirt
-    bool devirt_skip_cold_targets;
     bool devirt_do_aggressive_guarded_devirtualization;
-    bool devirt_devirt_use_cha;
-    bool devirt_devirt_skip_exception_path;
+    bool devirt_use_cha_with_profile;
+    int devirt_use_cha_with_profile_threshold;
+    bool devirt_skip_exception_path;
+    float devirt_block_hotness_multiplier;
+    bool devirt_skip_object_methods;
+
+    //unguard
+    int unguard_dcall_percent;
+    int unguard_dcall_percent_of_entry;
+
 
     AbcdFlags*              abcdFlags;
     GcmFlags*               gcmFlags;



Mime
View raw message