[llvm] r314601 - Refactor the SamplePGO profile annotation logic to extract inlineCallInstruction. (NFC)

Dehao Chen via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 30 13:46:15 PDT 2017


Author: dehao
Date: Sat Sep 30 13:46:15 2017
New Revision: 314601

URL: http://llvm.org/viewvc/llvm-project?rev=314601&view=rev
Log:
Refactor the SamplePGO profile annotation logic to extract inlineCallInstruction. (NFC)

Modified:
    llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp

Modified: llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp?rev=314601&r1=314600&r2=314601&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp Sat Sep 30 13:46:15 2017
@@ -172,6 +172,7 @@ protected:
   std::vector<const FunctionSamples *>
   findIndirectCallFunctionSamples(const Instruction &I) const;
   const FunctionSamples *findFunctionSamples(const Instruction &I) const;
+  bool inlineCallInstruction(Instruction *I);
   bool inlineHotFunctions(Function &F,
                           DenseSet<GlobalValue::GUID> &ImportGUIDs);
   void printEdgeWeight(raw_ostream &OS, Edge E);
@@ -676,6 +677,39 @@ SampleProfileLoader::findFunctionSamples
   return FS;
 }
 
+bool SampleProfileLoader::inlineCallInstruction(Instruction *I) {
+  assert(isa<CallInst>(I) || isa<InvokeInst>(I));
+  CallSite CS(I);
+  Function *CalledFunction = CS.getCalledFunction();
+  assert(CalledFunction);
+  DebugLoc DLoc = I->getDebugLoc();
+  BasicBlock *BB = I->getParent();
+  InlineParams Params = getInlineParams();
+  Params.ComputeFullInlineCost = true;
+  // Checks if there is anything in the reachable portion of the callee at
+  // this callsite that makes this inlining potentially illegal. Need to
+  // set ComputeFullInlineCost, otherwise getInlineCost may return early
+  // when cost exceeds threshold without checking all IRs in the callee.
+  // The acutal cost does not matter because we only checks isNever() to
+  // see if it is legal to inline the callsite.
+  InlineCost Cost = getInlineCost(CS, Params, GetTTI(*CalledFunction), GetAC,
+                                  None, nullptr, nullptr);
+  if (Cost.isNever()) {
+    ORE->emit(OptimizationRemark(DEBUG_TYPE, "Not inline", DLoc, BB)
+              << "incompatible inlining");
+    return false;
+  }
+  InlineFunctionInfo IFI(nullptr, &GetAC);
+  if (InlineFunction(CS, IFI)) {
+    // The call to InlineFunction erases I, so we can't pass it here.
+    ORE->emit(OptimizationRemark(DEBUG_TYPE, "HotInline", DLoc, BB)
+              << "inlined hot callee '" << ore::NV("Callee", CalledFunction)
+              << "' into '" << ore::NV("Caller", BB->getParent()) << "'");
+    return true;
+  }
+  return false;
+}
+
 /// \brief Iteratively inline hot callsites of a function.
 ///
 /// Iteratively traverse all callsites of the function \p F, and find if
@@ -713,82 +747,55 @@ bool SampleProfileLoader::inlineHotFunct
       }
     }
     for (auto I : CIS) {
-      InlineFunctionInfo IFI(nullptr, &GetAC);
       Function *CalledFunction = CallSite(I).getCalledFunction();
       // Do not inline recursive calls.
       if (CalledFunction == &F)
         continue;
-      Instruction *DI = I;
-      if (!CalledFunction && !PromotedInsns.count(I) &&
-          CallSite(I).isIndirectCall()) {
+      if (CallSite(I).isIndirectCall()) {
+        if (PromotedInsns.count(I))
+          continue;
         for (const auto *FS : findIndirectCallFunctionSamples(*I)) {
           auto CalleeFunctionName = FS->getName();
           // If it is a recursive call, we do not inline it as it could bloat
           // the code exponentially. There is way to better handle this, e.g.
           // clone the caller first, and inline the cloned caller if it is
-          // recursive. As llvm does not inline recursive calls, we will simply
-          // ignore it instead of handling it explicitly.
+          // recursive. As llvm does not inline recursive calls, we will
+          // simply ignore it instead of handling it explicitly.
           if (CalleeFunctionName == F.getName())
             continue;
+
           const char *Reason = "Callee function not available";
           auto R = SymbolMap.find(CalleeFunctionName);
-          if (R == SymbolMap.end())
-            continue;
-          CalledFunction = R->getValue();
-          if (CalledFunction && isLegalToPromote(I, CalledFunction, &Reason)) {
-            // The indirect target was promoted and inlined in the profile, as a
-            // result, we do not have profile info for the branch probability.
-            // We set the probability to 80% taken to indicate that the static
-            // call is likely taken.
-            DI = dyn_cast<Instruction>(
-                promoteIndirectCall(I, CalledFunction, 80, 100, false, ORE)
+          if (R != SymbolMap.end() && R->getValue() &&
+              !R->getValue()->isDeclaration() &&
+              R->getValue()->getSubprogram() &&
+              isLegalToPromote(I, R->getValue(), &Reason)) {
+            // The indirect target was promoted and inlined in the profile,
+            // as a result, we do not have profile info for the branch
+            // probability. We set the probability to 80% taken to indicate
+            // that the static call is likely taken.
+            Instruction *DI = dyn_cast<Instruction>(
+                promoteIndirectCall(I, R->getValue(), 80, 100, false, ORE)
                     ->stripPointerCasts());
             PromotedInsns.insert(I);
+            // If profile mismatches, we should not attempt to inline DI.
+            if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&
+                inlineCallInstruction(DI))
+              LocalChanged = true;
           } else {
-            DEBUG(dbgs() << "\nFailed to promote indirect call to "
-                         << CalleeFunctionName << " because " << Reason
-                         << "\n");
-            continue;
+            FS->findImportedFunctions(ImportGUIDs, F.getParent(),
+                                      Samples->getTotalSamples() *
+                                          SampleProfileHotThreshold / 100);
           }
         }
-        // If there is profile mismatch, we should not attempt to inline DI.
-        if (!isa<CallInst>(DI) && !isa<InvokeInst>(DI))
-          continue;
-      }
-      if (!CalledFunction || !CalledFunction->getSubprogram()) {
-        // Handles functions that are imported from other modules.
-        for (const FunctionSamples *FS : findIndirectCallFunctionSamples(*I))
-          FS->findImportedFunctions(
-              ImportGUIDs, F.getParent(),
-              Samples->getTotalSamples() * SampleProfileHotThreshold / 100);
-        continue;
-      }
-      assert(isa<CallInst>(DI) || isa<InvokeInst>(DI));
-      CallSite CS(DI);
-      DebugLoc DLoc = I->getDebugLoc();
-      BasicBlock *BB = I->getParent();
-      InlineParams Params = getInlineParams();
-      Params.ComputeFullInlineCost = true;
-      // Checks if there is anything in the reachable portion of the callee at
-      // this callsite that makes this inlining potentially illegal. Need to
-      // set ComputeFullInlineCost, otherwise getInlineCost may return early
-      // when cost exceeds threshold without checking all IRs in the callee.
-      // The acutal cost does not matter because we only checks isNever() to
-      // see if it is legal to inline the callsite.
-      InlineCost Cost = getInlineCost(CS, Params, GetTTI(*CalledFunction), GetAC,
-                                      None, nullptr, nullptr);
-      if (Cost.isNever()) {
-        ORE->emit(OptimizationRemark(DEBUG_TYPE, "Not inline", DLoc, BB)
-                  << "incompatible inlining");
-        continue;
-      }
-      if (InlineFunction(CS, IFI)) {
-        LocalChanged = true;
-        // The call to InlineFunction erases DI, so we can't pass it here.
-        ORE->emit(OptimizationRemark(DEBUG_TYPE, "HotInline", DLoc, BB)
-                  << "inlined hot callee '"
-                  << ore::NV("Callee", CalledFunction) << "' into '"
-                  << ore::NV("Caller", &F) << "'");
+      } else if (CalledFunction && CalledFunction->getSubprogram() &&
+                 !CalledFunction->isDeclaration()) {
+        if (inlineCallInstruction(I))
+          LocalChanged = true;
+      } else {
+        findCalleeFunctionSamples(*I)->findImportedFunctions(
+            ImportGUIDs, F.getParent(),
+            Samples->getTotalSamples() * SampleProfileHotThreshold / 100);
       }
     }
     if (LocalChanged) {




More information about the llvm-commits mailing list