[llvm] 655aa1a - [llvm][NFC] Replace CallSite with CallBase in Inliner

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 15:02:16 PDT 2020


Author: Mircea Trofin
Date: 2020-04-09T15:01:58-07:00
New Revision: 655aa1ae4af46a5c89e25e1b6c5958eb7395d028

URL: https://github.com/llvm/llvm-project/commit/655aa1ae4af46a5c89e25e1b6c5958eb7395d028
DIFF: https://github.com/llvm/llvm-project/commit/655aa1ae4af46a5c89e25e1b6c5958eb7395d028.diff

LOG: [llvm][NFC] Replace CallSite with CallBase in Inliner

Summary:
*Almost* all uses are replaced. Left FIXMEs for the two sites that
require refactoring outside of Inliner, to scope this patch.

Subscribers: eraman, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77817

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/IPO/Inliner.h
    llvm/lib/Transforms/IPO/Inliner.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/IPO/Inliner.h b/llvm/include/llvm/Transforms/IPO/Inliner.h
index 38137e9d6cec..a211d1ad252f 100644
--- a/llvm/include/llvm/Transforms/IPO/Inliner.h
+++ b/llvm/include/llvm/Transforms/IPO/Inliner.h
@@ -51,8 +51,16 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
   /// This method must be implemented by the subclass to determine the cost of
   /// inlining the specified call site.  If the cost returned is greater than
   /// the current inline threshold, the call site is not inlined.
+  // FIXME(mtrofin): remove this in favor of the CallBase-based one
   virtual InlineCost getInlineCost(CallSite CS) = 0;
 
+  /// This method must be implemented by the subclass to determine the cost of
+  /// inlining the specified call site.  If the cost returned is greater than
+  /// the current inline threshold, the call site is not inlined.
+  virtual InlineCost getInlineCost(CallBase &CB) {
+    return getInlineCost(CallSite(&CB));
+  }
+
   /// Remove dead functions.
   ///
   /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag

diff  --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index 1b10c5433b46..c9eac60cc574 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -273,7 +273,7 @@ static void mergeInlinedArrayAllocas(
 /// inline this call site we attempt to reuse already available allocas or add
 /// any new allocas to the set if not possible.
 static InlineResult InlineCallIfPossible(
-    CallSite CS, InlineFunctionInfo &IFI,
+    CallBase &CS, InlineFunctionInfo &IFI,
     InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory,
     bool InsertLifetime, function_ref<AAResults &(Function &)> &AARGetter,
     ImportedFunctionsInliningStatistics &ImportedFunctionsStats) {
@@ -284,7 +284,7 @@ static InlineResult InlineCallIfPossible(
 
   // Try to inline the function.  Get the list of static allocas that were
   // inlined.
-  InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime);
+  InlineResult IR = InlineFunction(&CS, IFI, &AAR, InsertLifetime);
   if (!IR.isSuccess())
     return IR;
 
@@ -305,9 +305,8 @@ static InlineResult InlineCallIfPossible(
 /// \p TotalSecondaryCost will be set to the estimated cost of inlining the
 /// caller if \p CS is suppressed for inlining.
 static bool
-shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
-                 int &TotalSecondaryCost,
-                 function_ref<InlineCost(CallSite CS)> GetInlineCost) {
+shouldBeDeferred(Function *Caller, InlineCost IC, int &TotalSecondaryCost,
+                 function_ref<InlineCost(CallBase &CS)> GetInlineCost) {
   // For now we only handle local or inline functions.
   if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
     return false;
@@ -346,17 +345,17 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
     // applied), then we can exit the loop early.
     if (!ApplyLastCallBonus && TotalSecondaryCost >= IC.getCost())
       return false;
-    CallSite CS2(U);
+    CallBase *CS2 = dyn_cast<CallBase>(U);
 
     // If this isn't a call to Caller (it could be some other sort
     // of reference) skip it.  Such references will prevent the caller
     // from being removed.
-    if (!CS2 || CS2.getCalledFunction() != Caller) {
+    if (!CS2 || CS2->getCalledFunction() != Caller) {
       ApplyLastCallBonus = false;
       continue;
     }
 
-    InlineCost IC2 = GetInlineCost(CS2);
+    InlineCost IC2 = GetInlineCost(*CS2);
     ++NumCallerCallersAnalyzed;
     if (!IC2) {
       ApplyLastCallBonus = false;
@@ -417,24 +416,24 @@ static std::string inlineCostStr(const InlineCost &IC) {
 /// CallSite. If we return the cost, we will emit an optimisation remark later
 /// using that cost, so we won't do so from this function.
 static Optional<InlineCost>
-shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
+shouldInline(CallBase &CS, function_ref<InlineCost(CallBase &CS)> GetInlineCost,
              OptimizationRemarkEmitter &ORE) {
   using namespace ore;
 
   InlineCost IC = GetInlineCost(CS);
-  Instruction *Call = CS.getInstruction();
+  Instruction *Call = &CS;
   Function *Callee = CS.getCalledFunction();
   Function *Caller = CS.getCaller();
 
   if (IC.isAlways()) {
     LLVM_DEBUG(dbgs() << "    Inlining " << inlineCostStr(IC)
-                      << ", Call: " << *CS.getInstruction() << "\n");
+                      << ", Call: " << CS << "\n");
     return IC;
   }
 
   if (IC.isNever()) {
     LLVM_DEBUG(dbgs() << "    NOT Inlining " << inlineCostStr(IC)
-                      << ", Call: " << *CS.getInstruction() << "\n");
+                      << ", Call: " << CS << "\n");
     ORE.emit([&]() {
       return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
              << NV("Callee", Callee) << " not inlined into "
@@ -446,7 +445,7 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
 
   if (!IC) {
     LLVM_DEBUG(dbgs() << "    NOT Inlining " << inlineCostStr(IC)
-                      << ", Call: " << *CS.getInstruction() << "\n");
+                      << ", Call: " << CS << "\n");
     ORE.emit([&]() {
       return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
              << NV("Callee", Callee) << " not inlined into "
@@ -456,8 +455,8 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
   }
 
   int TotalSecondaryCost = 0;
-  if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost, GetInlineCost)) {
-    LLVM_DEBUG(dbgs() << "    NOT Inlining: " << *CS.getInstruction()
+  if (shouldBeDeferred(Caller, IC, TotalSecondaryCost, GetInlineCost)) {
+    LLVM_DEBUG(dbgs() << "    NOT Inlining: " << CS
                       << " Cost = " << IC.getCost()
                       << ", outer Cost = " << TotalSecondaryCost << '\n');
     ORE.emit([&]() {
@@ -473,8 +472,8 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
     return None;
   }
 
-  LLVM_DEBUG(dbgs() << "    Inlining " << inlineCostStr(IC)
-                    << ", Call: " << *CS.getInstruction() << '\n');
+  LLVM_DEBUG(dbgs() << "    Inlining " << inlineCostStr(IC) << ", Call: " << CS
+                    << '\n');
   return IC;
 }
 
@@ -517,11 +516,11 @@ static void emit_inlined_into(OptimizationRemarkEmitter &ORE, DebugLoc &DLoc,
   });
 }
 
-static void setInlineRemark(CallSite &CS, StringRef message) {
+static void setInlineRemark(CallBase &CS, StringRef Message) {
   if (!InlineRemarkAttribute)
     return;
 
-  Attribute attr = Attribute::get(CS->getContext(), "inline-remark", message);
+  Attribute attr = Attribute::get(CS.getContext(), "inline-remark", Message);
   CS.addAttribute(AttributeList::FunctionIndex, attr);
 }
 
@@ -531,7 +530,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
                 ProfileSummaryInfo *PSI,
                 std::function<const TargetLibraryInfo &(Function &)> GetTLI,
                 bool InsertLifetime,
-                function_ref<InlineCost(CallSite CS)> GetInlineCost,
+                function_ref<InlineCost(CallBase &CS)> GetInlineCost,
                 function_ref<AAResults &(Function &)> AARGetter,
                 ImportedFunctionsInliningStatistics &ImportedFunctionsStats) {
   SmallPtrSet<Function *, 8> SCCFunctions;
@@ -546,7 +545,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
   // Scan through and identify all call sites ahead of time so that we only
   // inline call sites in the original functions, not call sites that result
   // from inlining other functions.
-  SmallVector<std::pair<CallSite, int>, 16> CallSites;
+  SmallVector<std::pair<CallBase *, int>, 16> CallSites;
 
   // When inlining a callee produces new call sites, we want to keep track of
   // the fact that they were inlined from the callee.  This allows us to avoid
@@ -562,7 +561,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
     OptimizationRemarkEmitter ORE(F);
     for (BasicBlock &BB : *F)
       for (Instruction &I : BB) {
-        CallSite CS(cast<Value>(&I));
+        auto *CS = dyn_cast<CallBase>(&I);
         // If this isn't a call, or it is a call to an intrinsic, it can
         // never be inlined.
         if (!CS || isa<IntrinsicInst>(I))
@@ -571,15 +570,15 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
         // If this is a direct call to an external function, we can never inline
         // it.  If it is an indirect call, inlining may resolve it to be a
         // direct call, so we keep it.
-        if (Function *Callee = CS.getCalledFunction())
+        if (Function *Callee = CS->getCalledFunction())
           if (Callee->isDeclaration()) {
             using namespace ore;
 
-            setInlineRemark(CS, "unavailable definition");
+            setInlineRemark(*CS, "unavailable definition");
             ORE.emit([&]() {
               return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
                      << NV("Callee", Callee) << " will not be inlined into "
-                     << NV("Caller", CS.getCaller())
+                     << NV("Caller", CS->getCaller())
                      << " because its definition is unavailable"
                      << setIsVerbose();
             });
@@ -600,7 +599,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
   // current SCC to the end of the list.
   unsigned FirstCallInSCC = CallSites.size();
   for (unsigned i = 0; i < FirstCallInSCC; ++i)
-    if (Function *F = CallSites[i].first.getCalledFunction())
+    if (Function *F = CallSites[i].first->getCalledFunction())
       if (SCCFunctions.count(F))
         std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
 
@@ -617,7 +616,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
     // calls to become direct calls.
     // CallSites may be modified inside so ranged for loop can not be used.
     for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) {
-      CallSite CS = CallSites[CSi].first;
+      CallBase &CS = *CallSites[CSi].first;
 
       Function *Caller = CS.getCaller();
       Function *Callee = CS.getCalledFunction();
@@ -626,7 +625,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
       if (!Callee || Callee->isDeclaration())
         continue;
 
-      Instruction *Instr = CS.getInstruction();
+      Instruction *Instr = &CS;
 
       bool IsTriviallyDead =
           isInstructionTriviallyDead(Instr, &GetTLI(*Caller));
@@ -674,12 +673,12 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
         LLVM_DEBUG(dbgs() << "    -> Deleting dead call: " << *Instr << "\n");
         // Update the call graph by deleting the edge from Callee to Caller.
         setInlineRemark(CS, "trivially dead");
-        CG[Caller]->removeCallEdgeFor(*cast<CallBase>(CS.getInstruction()));
+        CG[Caller]->removeCallEdgeFor(CS);
         Instr->eraseFromParent();
         ++NumCallsDeleted;
       } else {
         // Get DebugLoc to report. CS will be invalid after Inliner.
-        DebugLoc DLoc = CS->getDebugLoc();
+        DebugLoc DLoc = CS.getDebugLoc();
         BasicBlock *Block = CS.getParent();
 
         // Attempt to inline the function.
@@ -717,16 +716,17 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
           // happen when a callsite is simpilfied to reusing the return value
           // of another callsite during function cloning, thus the other
           // callsite will be reconsidered here.
-          DenseSet<CallSite> DbgCallSites;
+          DenseSet<CallBase *> DbgCallSites;
           for (auto &II : CallSites)
             DbgCallSites.insert(II.first);
 #endif
 
           for (Value *Ptr : InlineInfo.InlinedCalls) {
 #ifndef NDEBUG
-            assert(DbgCallSites.count(CallSite(Ptr)) == 0);
+            assert(DbgCallSites.count(dyn_cast<CallBase>(Ptr)) == 0);
 #endif
-            CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID));
+            CallSites.push_back(
+                std::make_pair(dyn_cast<CallBase>(Ptr), NewHistoryID));
           }
         }
       }
@@ -784,8 +784,8 @@ bool LegacyInlinerBase::inlineCalls(CallGraphSCC &SCC) {
   };
   return inlineCallsImpl(
       SCC, CG, GetAssumptionCache, PSI, GetTLI, InsertLifetime,
-      [this](CallSite CS) { return getInlineCost(CS); }, LegacyAARGetter(*this),
-      ImportedFunctionsStats);
+      [this](CallBase &CS) { return getInlineCost(CS); },
+      LegacyAARGetter(*this), ImportedFunctionsStats);
 }
 
 /// Remove now-dead linkonce functions at the end of
@@ -929,7 +929,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
   // this model, but it is uniformly spread across all the functions in the SCC
   // and eventually they all become too large to inline, rather than
   // incrementally maknig a single function grow in a super linear fashion.
-  SmallVector<std::pair<CallSite, int>, 16> Calls;
+  SmallVector<std::pair<CallBase *, int>, 16> Calls;
 
   FunctionAnalysisManager &FAM =
       AM.getResult<FunctionAnalysisManagerCGSCCProxy>(InitialC, CG)
@@ -945,17 +945,17 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
     // FIXME: Using instructions sequence is a really bad way to do this.
     // Instead we should do an actual RPO walk of the function body.
     for (Instruction &I : instructions(N.getFunction()))
-      if (auto CS = CallSite(&I))
-        if (Function *Callee = CS.getCalledFunction()) {
+      if (auto *CS = dyn_cast<CallBase>(&I))
+        if (Function *Callee = CS->getCalledFunction()) {
           if (!Callee->isDeclaration())
             Calls.push_back({CS, -1});
           else if (!isa<IntrinsicInst>(I)) {
             using namespace ore;
-            setInlineRemark(CS, "unavailable definition");
+            setInlineRemark(*CS, "unavailable definition");
             ORE.emit([&]() {
               return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
                      << NV("Callee", Callee) << " will not be inlined into "
-                     << NV("Caller", CS.getCaller())
+                     << NV("Caller", CS->getCaller())
                      << " because its definition is unavailable"
                      << setIsVerbose();
             });
@@ -991,12 +991,12 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
     // have the same caller, so we first set up some shared infrastructure for
     // this caller. We also do any pruning we can at this layer on the caller
     // alone.
-    Function &F = *Calls[i].first.getCaller();
+    Function &F = *Calls[i].first->getCaller();
     LazyCallGraph::Node &N = *CG.lookup(F);
     if (CG.lookupSCC(N) != C)
       continue;
     if (F.hasOptNone()) {
-      setInlineRemark(Calls[i].first, "optnone attribute");
+      setInlineRemark(*Calls[i].first, "optnone attribute");
       continue;
     }
 
@@ -1027,30 +1027,29 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
       return FAM.getResult<TargetLibraryAnalysis>(F);
     };
 
-    auto GetInlineCost = [&](CallSite CS) {
+    auto GetInlineCost = [&](CallBase &CS) {
       Function &Callee = *CS.getCalledFunction();
       auto &CalleeTTI = FAM.getResult<TargetIRAnalysis>(Callee);
       bool RemarksEnabled =
           Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
               DEBUG_TYPE);
-      return getInlineCost(cast<CallBase>(*CS.getInstruction()), Params,
-                           CalleeTTI, GetAssumptionCache, {GetBFI}, GetTLI, PSI,
-                           RemarksEnabled ? &ORE : nullptr);
+      return getInlineCost(CS, Params, CalleeTTI, GetAssumptionCache, {GetBFI},
+                           GetTLI, PSI, RemarksEnabled ? &ORE : nullptr);
     };
 
     // Now process as many calls as we have within this caller in the sequnece.
     // We bail out as soon as the caller has to change so we can update the
     // call graph and prepare the context of that new caller.
     bool DidInline = false;
-    for (; i < (int)Calls.size() && Calls[i].first.getCaller() == &F; ++i) {
+    for (; i < (int)Calls.size() && Calls[i].first->getCaller() == &F; ++i) {
       int InlineHistoryID;
-      CallSite CS;
+      CallBase *CS = nullptr;
       std::tie(CS, InlineHistoryID) = Calls[i];
-      Function &Callee = *CS.getCalledFunction();
+      Function &Callee = *CS->getCalledFunction();
 
       if (InlineHistoryID != -1 &&
           InlineHistoryIncludes(&Callee, InlineHistoryID, InlineHistory)) {
-        setInlineRemark(CS, "recursive");
+        setInlineRemark(*CS, "recursive");
         continue;
       }
 
@@ -1064,21 +1063,21 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
         LLVM_DEBUG(dbgs() << "Skipping inlining internal SCC edge from a node "
                              "previously split out of this SCC by inlining: "
                           << F.getName() << " -> " << Callee.getName() << "\n");
-        setInlineRemark(CS, "recursive SCC split");
+        setInlineRemark(*CS, "recursive SCC split");
         continue;
       }
 
-      Optional<InlineCost> OIC = shouldInline(CS, GetInlineCost, ORE);
+      Optional<InlineCost> OIC = shouldInline(*CS, GetInlineCost, ORE);
       // Check whether we want to inline this callsite.
       if (!OIC.hasValue()) {
-        setInlineRemark(CS, "deferred");
+        setInlineRemark(*CS, "deferred");
         continue;
       }
 
       if (!OIC.getValue()) {
         // shouldInline() call returned a negative inline cost that explains
         // why this callsite should not be inlined.
-        setInlineRemark(CS, inlineCostStr(*OIC));
+        setInlineRemark(*CS, inlineCostStr(*OIC));
         continue;
       }
 
@@ -1086,19 +1085,19 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
       // `InlineFunction` routine.
       InlineFunctionInfo IFI(
           /*cg=*/nullptr, &GetAssumptionCache, PSI,
-          &FAM.getResult<BlockFrequencyAnalysis>(*(CS.getCaller())),
+          &FAM.getResult<BlockFrequencyAnalysis>(*(CS->getCaller())),
           &FAM.getResult<BlockFrequencyAnalysis>(Callee));
 
       // Get DebugLoc to report. CS will be invalid after Inliner.
       DebugLoc DLoc = CS->getDebugLoc();
-      BasicBlock *Block = CS.getParent();
+      BasicBlock *Block = CS->getParent();
 
       using namespace ore;
 
       InlineResult IR = InlineFunction(CS, IFI);
       if (!IR.isSuccess()) {
-        setInlineRemark(CS, std::string(IR.getFailureReason()) + "; " +
-                                inlineCostStr(*OIC));
+        setInlineRemark(*CS, std::string(IR.getFailureReason()) + "; " +
+                                 inlineCostStr(*OIC));
         ORE.emit([&]() {
           return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
                  << NV("Callee", &Callee) << " will not be inlined into "
@@ -1118,6 +1117,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
       if (!IFI.InlinedCallSites.empty()) {
         int NewHistoryID = InlineHistory.size();
         InlineHistory.push_back({&Callee, InlineHistoryID});
+
+        // FIXME(mtrofin): refactor IFI.InlinedCallSites to be CallBase-based
         for (CallSite &CS : reverse(IFI.InlinedCallSites)) {
           Function *NewCallee = CS.getCalledFunction();
           if (!NewCallee) {
@@ -1130,7 +1131,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
           }
           if (NewCallee)
             if (!NewCallee->isDeclaration())
-              Calls.push_back({CS, NewHistoryID});
+              Calls.push_back(
+                  {cast<CallBase>(CS.getInstruction()), NewHistoryID});
         }
       }
 
@@ -1151,8 +1153,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
         if (Callee.use_empty() && !CG.isLibFunction(Callee)) {
           Calls.erase(
               std::remove_if(Calls.begin() + i + 1, Calls.end(),
-                             [&Callee](const std::pair<CallSite, int> &Call) {
-                               return Call.first.getCaller() == &Callee;
+                             [&Callee](const std::pair<CallBase *, int> &Call) {
+                               return Call.first->getCaller() == &Callee;
                              }),
               Calls.end());
           // Clear the body and queue the function itself for deletion when we


        


More information about the llvm-commits mailing list