Home | History | Annotate | Line # | Download | only in IPO
      1 //===- Inliner.h - Inliner pass and infrastructure --------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_TRANSFORMS_IPO_INLINER_H
     10 #define LLVM_TRANSFORMS_IPO_INLINER_H
     11 
     12 #include "llvm/Analysis/CGSCCPassManager.h"
     13 #include "llvm/Analysis/CallGraphSCCPass.h"
     14 #include "llvm/Analysis/InlineAdvisor.h"
     15 #include "llvm/Analysis/InlineCost.h"
     16 #include "llvm/Analysis/LazyCallGraph.h"
     17 #include "llvm/Analysis/ReplayInlineAdvisor.h"
     18 #include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
     19 #include "llvm/IR/PassManager.h"
     20 #include <utility>
     21 
     22 namespace llvm {
     23 
     24 class AssumptionCacheTracker;
     25 class CallGraph;
     26 class ProfileSummaryInfo;
     27 
     28 /// This class contains all of the helper code which is used to perform the
     29 /// inlining operations that do not depend on the policy. It contains the core
     30 /// bottom-up inlining infrastructure that specific inliner passes use.
     31 struct LegacyInlinerBase : public CallGraphSCCPass {
     32   explicit LegacyInlinerBase(char &ID);
     33   explicit LegacyInlinerBase(char &ID, bool InsertLifetime);
     34 
     35   /// For this class, we declare that we require and preserve the call graph.
     36   /// If the derived class implements this method, it should always explicitly
     37   /// call the implementation here.
     38   void getAnalysisUsage(AnalysisUsage &Info) const override;
     39 
     40   using llvm::Pass::doInitialization;
     41 
     42   bool doInitialization(CallGraph &CG) override;
     43 
     44   /// Main run interface method, this implements the interface required by the
     45   /// Pass class.
     46   bool runOnSCC(CallGraphSCC &SCC) override;
     47 
     48   using llvm::Pass::doFinalization;
     49 
     50   /// Remove now-dead linkonce functions at the end of processing to avoid
     51   /// breaking the SCC traversal.
     52   bool doFinalization(CallGraph &CG) override;
     53 
     54   /// This method must be implemented by the subclass to determine the cost of
     55   /// inlining the specified call site.  If the cost returned is greater than
     56   /// the current inline threshold, the call site is not inlined.
     57   virtual InlineCost getInlineCost(CallBase &CB) = 0;
     58 
     59   /// Remove dead functions.
     60   ///
     61   /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
     62   /// which restricts it to deleting functions with an 'AlwaysInline'
     63   /// attribute. This is useful for the InlineAlways pass that only wants to
     64   /// deal with that subset of the functions.
     65   bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
     66 
     67   /// This function performs the main work of the pass.  The default of
     68   /// Inlinter::runOnSCC() calls skipSCC() before calling this method, but
     69   /// derived classes which cannot be skipped can override that method and call
     70   /// this function unconditionally.
     71   bool inlineCalls(CallGraphSCC &SCC);
     72 
     73 private:
     74   // Insert @llvm.lifetime intrinsics.
     75   bool InsertLifetime = true;
     76 
     77 protected:
     78   AssumptionCacheTracker *ACT;
     79   ProfileSummaryInfo *PSI;
     80   std::function<const TargetLibraryInfo &(Function &)> GetTLI;
     81   ImportedFunctionsInliningStatistics ImportedFunctionsStats;
     82 };
     83 
     84 /// The inliner pass for the new pass manager.
     85 ///
     86 /// This pass wires together the inlining utilities and the inline cost
     87 /// analysis into a CGSCC pass. It considers every call in every function in
     88 /// the SCC and tries to inline if profitable. It can be tuned with a number of
     89 /// parameters to control what cost model is used and what tradeoffs are made
     90 /// when making the decision.
     91 ///
     92 /// It should be noted that the legacy inliners do considerably more than this
     93 /// inliner pass does. They provide logic for manually merging allocas, and
     94 /// doing considerable DCE including the DCE of dead functions. This pass makes
     95 /// every attempt to be simpler. DCE of functions requires complex reasoning
     96 /// about comdat groups, etc. Instead, it is expected that other more focused
     97 /// passes be composed to achieve the same end result.
     98 class InlinerPass : public PassInfoMixin<InlinerPass> {
     99 public:
    100   InlinerPass(bool OnlyMandatory = false) : OnlyMandatory(OnlyMandatory) {}
    101   InlinerPass(InlinerPass &&Arg) = default;
    102 
    103   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
    104                         LazyCallGraph &CG, CGSCCUpdateResult &UR);
    105 
    106 private:
    107   InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
    108                             FunctionAnalysisManager &FAM, Module &M);
    109   std::unique_ptr<InlineAdvisor> OwnedAdvisor;
    110   const bool OnlyMandatory;
    111 };
    112 
    113 /// Module pass, wrapping the inliner pass. This works in conjunction with the
    114 /// InlineAdvisorAnalysis to facilitate inlining decisions taking into account
    115 /// module-wide state, that need to keep track of inter-inliner pass runs, for
    116 /// a given module. An InlineAdvisor is configured and kept alive for the
    117 /// duration of the ModuleInlinerWrapperPass::run.
    118 class ModuleInlinerWrapperPass
    119     : public PassInfoMixin<ModuleInlinerWrapperPass> {
    120 public:
    121   ModuleInlinerWrapperPass(
    122       InlineParams Params = getInlineParams(), bool MandatoryFirst = true,
    123       InliningAdvisorMode Mode = InliningAdvisorMode::Default,
    124       unsigned MaxDevirtIterations = 0);
    125   ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
    126 
    127   PreservedAnalyses run(Module &, ModuleAnalysisManager &);
    128 
    129   /// Allow adding more CGSCC passes, besides inlining. This should be called
    130   /// before run is called, as part of pass pipeline building.
    131   CGSCCPassManager &getPM() { return PM; }
    132 
    133   /// Allow adding module-level passes benefiting the contained CGSCC passes.
    134   template <class T> void addModulePass(T Pass) {
    135     MPM.addPass(std::move(Pass));
    136   }
    137 
    138 private:
    139   const InlineParams Params;
    140   const InliningAdvisorMode Mode;
    141   const unsigned MaxDevirtIterations;
    142   CGSCCPassManager PM;
    143   ModulePassManager MPM;
    144 };
    145 } // end namespace llvm
    146 
    147 #endif // LLVM_TRANSFORMS_IPO_INLINER_H
    148