Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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) |
||
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. |
||
136 | CGSCCPassManager &getPM() { return PM; } |
||
137 | |||
138 | /// Add a module pass that runs before the CGSCC passes. |
||
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. |
||
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 |