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