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