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 Debugging = false,
123       bool MandatoryFirst = true,
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.
132   CGSCCPassManager &getPM() { return PM; }
133 
134   /// Allow adding module-level analyses benefiting the contained CGSCC passes.
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