1 | // llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- 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 | // This file defines the PassManagerBuilder class, which is used to set up a |
10 | // "standard" optimization sequence suitable for languages like C and C++. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H |
15 | #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H |
16 | |
17 | #include "llvm-c/Transforms/PassManagerBuilder.h" |
18 | #include <functional> |
19 | #include <memory> |
20 | #include <string> |
21 | #include <vector> |
22 | |
23 | namespace llvm { |
24 | class ModuleSummaryIndex; |
25 | class Pass; |
26 | class TargetLibraryInfoImpl; |
27 | |
28 | // The old pass manager infrastructure is hidden in a legacy namespace now. |
29 | namespace legacy { |
30 | class FunctionPassManager; |
31 | class PassManagerBase; |
32 | } |
33 | |
34 | /// PassManagerBuilder - This class is used to set up a standard optimization |
35 | /// sequence for languages like C and C++, allowing some APIs to customize the |
36 | /// pass sequence in various ways. A simple example of using it would be: |
37 | /// |
38 | /// PassManagerBuilder Builder; |
39 | /// Builder.OptLevel = 2; |
40 | /// Builder.populateFunctionPassManager(FPM); |
41 | /// Builder.populateModulePassManager(MPM); |
42 | /// |
43 | /// In addition to setting up the basic passes, PassManagerBuilder allows |
44 | /// frontends to vend a plugin API, where plugins are allowed to add extensions |
45 | /// to the default pass manager. They do this by specifying where in the pass |
46 | /// pipeline they want to be added, along with a callback function that adds |
47 | /// the pass(es). For example, a plugin that wanted to add a loop optimization |
48 | /// could do something like this: |
49 | /// |
50 | /// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) { |
51 | /// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0) |
52 | /// PM.add(createMyAwesomePass()); |
53 | /// } |
54 | /// ... |
55 | /// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, |
56 | /// addMyLoopPass); |
57 | /// ... |
58 | class PassManagerBuilder { |
59 | public: |
60 | /// Extensions are passed to the builder itself (so they can see how it is |
61 | /// configured) as well as the pass manager to add stuff to. |
62 | typedef std::function<void(const PassManagerBuilder &Builder, |
63 | legacy::PassManagerBase &PM)> |
64 | ExtensionFn; |
65 | typedef int GlobalExtensionID; |
66 | |
67 | enum ExtensionPointTy { |
68 | /// EP_EarlyAsPossible - This extension point allows adding passes before |
69 | /// any other transformations, allowing them to see the code as it is coming |
70 | /// out of the frontend. |
71 | EP_EarlyAsPossible, |
72 | |
73 | /// EP_ModuleOptimizerEarly - This extension point allows adding passes |
74 | /// just before the main module-level optimization passes. |
75 | EP_ModuleOptimizerEarly, |
76 | |
77 | /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to |
78 | /// the end of the loop optimizer. |
79 | EP_LoopOptimizerEnd, |
80 | |
81 | /// EP_ScalarOptimizerLate - This extension point allows adding optimization |
82 | /// passes after most of the main optimizations, but before the last |
83 | /// cleanup-ish optimizations. |
84 | EP_ScalarOptimizerLate, |
85 | |
86 | /// EP_OptimizerLast -- This extension point allows adding passes that |
87 | /// run after everything else. |
88 | EP_OptimizerLast, |
89 | |
90 | /// EP_VectorizerStart - This extension point allows adding optimization |
91 | /// passes before the vectorizer and other highly target specific |
92 | /// optimization passes are executed. |
93 | EP_VectorizerStart, |
94 | |
95 | /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that |
96 | /// should not be disabled by O0 optimization level. The passes will be |
97 | /// inserted after the inlining pass. |
98 | EP_EnabledOnOptLevel0, |
99 | |
100 | /// EP_Peephole - This extension point allows adding passes that perform |
101 | /// peephole optimizations similar to the instruction combiner. These passes |
102 | /// will be inserted after each instance of the instruction combiner pass. |
103 | EP_Peephole, |
104 | |
105 | /// EP_LateLoopOptimizations - This extension point allows adding late loop |
106 | /// canonicalization and simplification passes. This is the last point in |
107 | /// the loop optimization pipeline before loop deletion. Each pass added |
108 | /// here must be an instance of LoopPass. |
109 | /// This is the place to add passes that can remove loops, such as target- |
110 | /// specific loop idiom recognition. |
111 | EP_LateLoopOptimizations, |
112 | |
113 | /// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC |
114 | /// passes at the end of the main CallGraphSCC passes and before any |
115 | /// function simplification passes run by CGPassManager. |
116 | EP_CGSCCOptimizerLate, |
117 | |
118 | /// EP_FullLinkTimeOptimizationEarly - This extensions point allow adding |
119 | /// passes that |
120 | /// run at Link Time, before Full Link Time Optimization. |
121 | EP_FullLinkTimeOptimizationEarly, |
122 | |
123 | /// EP_FullLinkTimeOptimizationLast - This extensions point allow adding |
124 | /// passes that |
125 | /// run at Link Time, after Full Link Time Optimization. |
126 | EP_FullLinkTimeOptimizationLast, |
127 | }; |
128 | |
129 | /// The Optimization Level - Specify the basic optimization level. |
130 | /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 |
131 | unsigned OptLevel; |
132 | |
133 | /// SizeLevel - How much we're optimizing for size. |
134 | /// 0 = none, 1 = -Os, 2 = -Oz |
135 | unsigned SizeLevel; |
136 | |
137 | /// LibraryInfo - Specifies information about the runtime library for the |
138 | /// optimizer. If this is non-null, it is added to both the function and |
139 | /// per-module pass pipeline. |
140 | TargetLibraryInfoImpl *LibraryInfo; |
141 | |
142 | /// Inliner - Specifies the inliner to use. If this is non-null, it is |
143 | /// added to the per-module passes. |
144 | Pass *Inliner; |
145 | |
146 | /// The module summary index to use for exporting information from the |
147 | /// regular LTO phase, for example for the CFI and devirtualization type |
148 | /// tests. |
149 | ModuleSummaryIndex *ExportSummary = nullptr; |
150 | |
151 | /// The module summary index to use for importing information to the |
152 | /// thin LTO backends, for example for the CFI and devirtualization type |
153 | /// tests. |
154 | const ModuleSummaryIndex *ImportSummary = nullptr; |
155 | |
156 | bool DisableUnrollLoops; |
157 | bool CallGraphProfile; |
158 | bool SLPVectorize; |
159 | bool LoopVectorize; |
160 | bool LoopsInterleaved; |
161 | bool RerollLoops; |
162 | bool NewGVN; |
163 | bool DisableGVNLoadPRE; |
164 | bool ForgetAllSCEVInLoopUnroll; |
165 | bool VerifyInput; |
166 | bool VerifyOutput; |
167 | bool MergeFunctions; |
168 | bool PrepareForLTO; |
169 | bool PrepareForThinLTO; |
170 | bool PerformThinLTO; |
171 | bool DivergentTarget; |
172 | unsigned LicmMssaOptCap; |
173 | unsigned LicmMssaNoAccForPromotionCap; |
174 | |
175 | /// Enable profile instrumentation pass. |
176 | bool EnablePGOInstrGen; |
177 | /// Enable profile context sensitive instrumentation pass. |
178 | bool EnablePGOCSInstrGen; |
179 | /// Enable profile context sensitive profile use pass. |
180 | bool EnablePGOCSInstrUse; |
181 | /// Profile data file name that the instrumentation will be written to. |
182 | std::string PGOInstrGen; |
183 | /// Path of the profile data file. |
184 | std::string PGOInstrUse; |
185 | /// Path of the sample Profile data file. |
186 | std::string PGOSampleUse; |
187 | |
188 | private: |
189 | /// ExtensionList - This is list of all of the extensions that are registered. |
190 | std::vector<std::pair<ExtensionPointTy, ExtensionFn>> Extensions; |
191 | |
192 | public: |
193 | PassManagerBuilder(); |
194 | ~PassManagerBuilder(); |
195 | /// Adds an extension that will be used by all PassManagerBuilder instances. |
196 | /// This is intended to be used by plugins, to register a set of |
197 | /// optimisations to run automatically. |
198 | /// |
199 | /// \returns A global extension identifier that can be used to remove the |
200 | /// extension. |
201 | static GlobalExtensionID addGlobalExtension(ExtensionPointTy Ty, |
202 | ExtensionFn Fn); |
203 | /// Removes an extension that was previously added using addGlobalExtension. |
204 | /// This is also intended to be used by plugins, to remove any extension that |
205 | /// was previously registered before being unloaded. |
206 | /// |
207 | /// \param ExtensionID Identifier of the extension to be removed. |
208 | static void removeGlobalExtension(GlobalExtensionID ExtensionID); |
209 | void addExtension(ExtensionPointTy Ty, ExtensionFn Fn); |
210 | |
211 | private: |
212 | void addExtensionsToPM(ExtensionPointTy ETy, |
213 | legacy::PassManagerBase &PM) const; |
214 | void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const; |
215 | void addLTOOptimizationPasses(legacy::PassManagerBase &PM); |
216 | void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); |
217 | void addPGOInstrPasses(legacy::PassManagerBase &MPM, bool IsCS); |
218 | void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM); |
219 | void addVectorPasses(legacy::PassManagerBase &PM, bool IsFullLTO); |
220 | |
221 | public: |
222 | /// populateFunctionPassManager - This fills in the function pass manager, |
223 | /// which is expected to be run on each function immediately as it is |
224 | /// generated. The idea is to reduce the size of the IR in memory. |
225 | void populateFunctionPassManager(legacy::FunctionPassManager &FPM); |
226 | |
227 | /// populateModulePassManager - This sets up the primary pass manager. |
228 | void populateModulePassManager(legacy::PassManagerBase &MPM); |
229 | void populateLTOPassManager(legacy::PassManagerBase &PM); |
230 | void populateThinLTOPassManager(legacy::PassManagerBase &PM); |
231 | }; |
232 | |
233 | /// Registers a function for adding a standard set of passes. This should be |
234 | /// used by optimizer plugins to allow all front ends to transparently use |
235 | /// them. Create a static instance of this class in your plugin, providing a |
236 | /// private function that the PassManagerBuilder can use to add your passes. |
237 | class RegisterStandardPasses { |
238 | PassManagerBuilder::GlobalExtensionID ExtensionID; |
239 | |
240 | public: |
241 | RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty, |
242 | PassManagerBuilder::ExtensionFn Fn) { |
243 | ExtensionID = PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn)); |
244 | } |
245 | |
246 | ~RegisterStandardPasses() { |
247 | // If the collection holding the global extensions is destroyed after the |
248 | // plugin is unloaded, the extension has to be removed here. Indeed, the |
249 | // destructor of the ExtensionFn may reference code in the plugin. |
250 | PassManagerBuilder::removeGlobalExtension(ExtensionID); |
251 | } |
252 | }; |
253 | |
254 | inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) { |
255 | return reinterpret_cast<PassManagerBuilder*>(P); |
256 | } |
257 | |
258 | inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) { |
259 | return reinterpret_cast<LLVMPassManagerBuilderRef>(P); |
260 | } |
261 | |
262 | } // end namespace llvm |
263 | #endif |
264 | |