LLVM 24.0.0git
PassInstrumentation.h
Go to the documentation of this file.
1//===- llvm/IR/PassInstrumentation.h ----------------------*- 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/// \file
9///
10/// This file defines the Pass Instrumentation classes that provide
11/// instrumentation points into the pass execution by PassManager.
12///
13/// There are two main classes:
14/// - PassInstrumentation provides a set of instrumentation points for
15/// pass managers to call on.
16///
17/// - PassInstrumentationCallbacks registers callbacks and provides access
18/// to them for PassInstrumentation.
19///
20/// PassInstrumentation object is being used as a result of
21/// PassInstrumentationAnalysis (so it is intended to be easily copyable).
22///
23/// Intended scheme of use for Pass Instrumentation is as follows:
24/// - register instrumentation callbacks in PassInstrumentationCallbacks
25/// instance. PassBuilder provides helper for that.
26///
27/// - register PassInstrumentationAnalysis with all the PassManagers.
28/// PassBuilder handles that automatically when registering analyses.
29///
30/// - Pass Manager requests PassInstrumentationAnalysis from analysis manager
31/// and gets PassInstrumentation as its result.
32///
33/// - Pass Manager invokes PassInstrumentation entry points appropriately,
34/// passing StringRef identification ("name") of the pass currently being
35/// executed and IRUnit it works on. There can be different schemes of
36/// providing names in future, currently it is just a name() of the pass.
37///
38/// - PassInstrumentation wraps address of IRUnit into an IRUnitRef and
39/// passes control to all the registered callbacks. Note that we
40/// specifically wrap 'const IRUnitT*' so as to avoid any accidental
41/// changes to IR in instrumenting callbacks.
42///
43/// - Some instrumentation points (BeforePass) allow to control execution
44/// of a pass. For those callbacks returning false means pass will not be
45/// executed.
46///
47//===----------------------------------------------------------------------===//
48
49#ifndef LLVM_IR_PASSINSTRUMENTATION_H
50#define LLVM_IR_PASSINSTRUMENTATION_H
51
52#include "llvm/ADT/DenseMap.h"
55#include "llvm/IR/IRUnitRef.h"
56#include "llvm/IR/PassManager.h"
58#include <vector>
59
60namespace llvm {
61
63class StringRef;
64
65/// This class manages callbacks registration, as well as provides a way for
66/// PassInstrumentation to pass control to the registered callbacks.
68public:
69 // Before/After callbacks accept IRUnits whenever appropriate, so they need
70 // to take them as constant pointers, wrapped with IRUnitRef.
71 // For the case when IRUnit has been invalidated there is a different
72 // callback to use - AfterPassInvalidated.
73 // We call all BeforePassFuncs to determine if a pass should run or not.
74 // BeforeNonSkippedPassFuncs are called only if the pass should run.
75 // TODO: currently AfterPassInvalidated does not accept IRUnit, since passing
76 // already invalidated IRUnit is unsafe. There are ways to handle invalidated
77 // IRUnits in a safe way, and we might pursue that as soon as there is a
78 // useful instrumentation that needs it.
88
89public:
91
92 /// Copying PassInstrumentationCallbacks is not intended.
95
96 template <typename CallableT>
98 ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
99 }
100
101 template <typename CallableT>
103 BeforeSkippedPassCallbacks.emplace_back(std::move(C));
104 }
105
106 template <typename CallableT>
108 BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
109 }
110
111 template <typename CallableT>
112 void registerAfterPassCallback(CallableT C, bool ToFront = false) {
113 if (ToFront)
114 AfterPassCallbacks.insert(AfterPassCallbacks.begin(), std::move(C));
115 else
116 AfterPassCallbacks.emplace_back(std::move(C));
117 }
118
119 template <typename CallableT>
120 void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront = false) {
121 if (ToFront)
122 AfterPassInvalidatedCallbacks.insert(
123 AfterPassInvalidatedCallbacks.begin(), std::move(C));
124 else
125 AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
126 }
127
128 template <typename CallableT>
130 BeforeAnalysisCallbacks.emplace_back(std::move(C));
131 }
132
133 template <typename CallableT>
134 void registerAfterAnalysisCallback(CallableT C, bool ToFront = false) {
135 if (ToFront)
136 AfterAnalysisCallbacks.insert(AfterAnalysisCallbacks.begin(),
137 std::move(C));
138 else
139 AfterAnalysisCallbacks.emplace_back(std::move(C));
140 }
141
142 template <typename CallableT>
144 AnalysisInvalidatedCallbacks.emplace_back(std::move(C));
145 }
146
147 template <typename CallableT>
149 AnalysesClearedCallbacks.emplace_back(std::move(C));
150 }
151
152 template <typename CallableT>
154 ClassToPassNameCallbacks.emplace_back(std::move(C));
155 }
156
157 /// Add a class name to pass name mapping for use by pass instrumentation.
159 /// Get the pass name for a given pass class name. Empty if no match found.
161
162private:
164
165 /// These are only run on passes that are not required. They return false when
166 /// an optional pass should be skipped.
168 ShouldRunOptionalPassCallbacks;
169 /// These are run on passes that are skipped.
171 BeforeSkippedPassCallbacks;
172 /// These are run on passes that are about to be run.
174 BeforeNonSkippedPassCallbacks;
175 /// These are run on passes that have just run.
177 /// These are run on passes that have just run on invalidated IR.
179 AfterPassInvalidatedCallbacks;
180 /// These are run on analyses that are about to be run.
182 BeforeAnalysisCallbacks;
183 /// These are run on analyses that have been run.
185 AfterAnalysisCallbacks;
186 /// These are run on analyses that have been invalidated.
188 AnalysisInvalidatedCallbacks;
189 /// These are run on analyses that have been cleared.
191 AnalysesClearedCallbacks;
192
193 SmallVector<llvm::unique_function<void ()>, 4> ClassToPassNameCallbacks;
194 DenseMap<StringRef, std::string> ClassToPassName;
195};
196
197/// This class provides instrumentation entry points for the Pass Manager,
198/// doing calls to callbacks registered in PassInstrumentationCallbacks.
201
202 // Template argument PassT of PassInstrumentation::runBeforePass could be two
203 // kinds: (1) a regular pass inherited from PassInfoMixin (happen when
204 // creating a adaptor pass for a regular pass); (2) a type-erased PassConcept
205 // created from (1). Here we want to make case (1) skippable unconditionally
206 // since they are regular passes. We call PassConcept::isRequired to decide
207 // for case (2).
208 template <typename PassT> static bool isRequired(const PassT &Pass) {
209 return Pass.isRequired();
210 }
211
212public:
213 /// Callbacks object is not owned by PassInstrumentation, its life-time
214 /// should at least match the life-time of corresponding
215 /// PassInstrumentationAnalysis (which usually is till the end of current
216 /// compilation).
218 : Callbacks(CB) {}
219
220 /// BeforePass instrumentation point - takes \p Pass instance to be executed
221 /// and constant reference to IR it operates on. \Returns true if pass is
222 /// allowed to be executed. These are only run on optional pass since required
223 /// passes must always be run. This allows these callbacks to print info when
224 /// they want to skip a pass.
225 template <typename IRUnitT, typename PassT>
226 bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
227 if (!Callbacks)
228 return true;
229
230 bool ShouldRun = true;
231 if (!isRequired(Pass)) {
232 for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
233 ShouldRun &= C(Pass.name(), IR);
234 }
235
236 if (ShouldRun) {
237 for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
238 C(Pass.name(), IR);
239 } else {
240 for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
241 C(Pass.name(), IR);
242 }
243
244 return ShouldRun;
245 }
246
247 /// AfterPass instrumentation point - takes \p Pass instance that has
248 /// just been executed and constant reference to \p IR it operates on.
249 /// \p IR is guaranteed to be valid at this point.
250 template <typename IRUnitT, typename PassT>
251 void runAfterPass(const PassT &Pass, const IRUnitT &IR,
252 const PreservedAnalyses &PA) const {
253 if (Callbacks)
254 for (auto &C : Callbacks->AfterPassCallbacks)
255 C(Pass.name(), IR, PA);
256 }
257
258 /// AfterPassInvalidated instrumentation point - takes \p Pass instance
259 /// that has just been executed. For use when IR has been invalidated
260 /// by \p Pass execution.
261 template <typename IRUnitT, typename PassT>
262 void runAfterPassInvalidated(const PassT &Pass,
263 const PreservedAnalyses &PA) const {
264 if (Callbacks)
265 for (auto &C : Callbacks->AfterPassInvalidatedCallbacks)
266 C(Pass.name(), PA);
267 }
268
269 /// BeforeAnalysis instrumentation point - takes \p Analysis instance
270 /// to be executed and constant reference to IR it operates on.
271 template <typename IRUnitT, typename PassT>
272 void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
273 if (Callbacks)
274 for (auto &C : Callbacks->BeforeAnalysisCallbacks)
275 C(Analysis.name(), IR);
276 }
277
278 /// AfterAnalysis instrumentation point - takes \p Analysis instance
279 /// that has just been executed and constant reference to IR it operated on.
280 template <typename IRUnitT, typename PassT>
281 void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
282 if (Callbacks)
283 for (auto &C : Callbacks->AfterAnalysisCallbacks)
284 C(Analysis.name(), IR);
285 }
286
287 /// AnalysisInvalidated instrumentation point - takes \p Analysis instance
288 /// that has just been invalidated and constant reference to IR it operated
289 /// on.
290 template <typename IRUnitT, typename PassT>
291 void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const {
292 if (Callbacks)
293 for (auto &C : Callbacks->AnalysisInvalidatedCallbacks)
294 C(Analysis.name(), IR);
295 }
296
297 /// AnalysesCleared instrumentation point - takes name of IR that analyses
298 /// operated on.
299 void runAnalysesCleared(StringRef Name) const {
300 if (Callbacks)
301 for (auto &C : Callbacks->AnalysesClearedCallbacks)
302 C(Name);
303 }
304
305 /// Handle invalidation from the pass manager when PassInstrumentation
306 /// is used as the result of PassInstrumentationAnalysis.
307 ///
308 /// On attempt to invalidate just return false. There is nothing to become
309 /// invalid here.
310 template <typename IRUnitT, typename... ExtraArgsT>
311 bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
312 ExtraArgsT...) {
313 return false;
314 }
315
316 template <typename CallableT>
318 if (Callbacks)
319 Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
320 }
322 if (Callbacks)
323 Callbacks->BeforeNonSkippedPassCallbacks.pop_back();
324 }
325
326 /// Get the pass name for a given pass class name.
328 if (Callbacks)
329 return Callbacks->getPassNameForClassName(ClassName);
330 return {};
331 }
332};
333
334LLVM_ABI bool isSpecialPass(StringRef PassID,
335 const std::vector<StringRef> &Specials);
336
337/// Pseudo-analysis pass that exposes the \c PassInstrumentation to pass
338/// managers.
340 : public AnalysisInfoMixin<PassInstrumentationAnalysis> {
342 LLVM_ABI static AnalysisKey Key;
343
345
346public:
347 /// PassInstrumentationCallbacks object is shared, owned by something else,
348 /// not this analysis.
350 : Callbacks(Callbacks) {}
351
353
354 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
355 Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
356 return PassInstrumentation(Callbacks);
357 }
358};
359
360
361} // namespace llvm
362
363#endif
block Block Frequency Analysis
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_ABI
Definition Compiler.h:215
This file defines the DenseMap class.
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
This file defines IRUnitRef, a type-erased reference to the IR unit a pass or analysis is running on,...
This header defines various interfaces for pass management in LLVM.
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:81
This file defines the SmallVector class.
static const char PassName[]
A type-erased reference to the IR unit a pass or analysis is running on, together with the kind of IR...
Definition IRUnitRef.h:60
Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...)
PassInstrumentationAnalysis(PassInstrumentationCallbacks *Callbacks=nullptr)
PassInstrumentationCallbacks object is shared, owned by something else, not this analysis.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront=false)
void registerAnalysisInvalidatedCallback(CallableT C)
void(StringRef, IRUnitRef, const PreservedAnalyses &) AfterPassFunc
void registerAfterAnalysisCallback(CallableT C, bool ToFront=false)
void(StringRef, IRUnitRef) AnalysisInvalidatedFunc
void(StringRef, IRUnitRef) BeforeAnalysisFunc
void(StringRef, const PreservedAnalyses &) AfterPassInvalidatedFunc
LLVM_ABI void addClassToPassName(StringRef ClassName, StringRef PassName)
Add a class name to pass name mapping for use by pass instrumentation.
void(StringRef, IRUnitRef) AfterAnalysisFunc
void registerBeforeNonSkippedPassCallback(CallableT C)
PassInstrumentationCallbacks(const PassInstrumentationCallbacks &)=delete
Copying PassInstrumentationCallbacks is not intended.
bool(StringRef, IRUnitRef) BeforePassFunc
void(StringRef, IRUnitRef) BeforeNonSkippedPassFunc
void(StringRef, IRUnitRef) BeforeSkippedPassFunc
void registerShouldRunOptionalPassCallback(CallableT C)
LLVM_ABI StringRef getPassNameForClassName(StringRef ClassName)
Get the pass name for a given pass class name. Empty if no match found.
void operator=(const PassInstrumentationCallbacks &)=delete
void registerAfterPassCallback(CallableT C, bool ToFront=false)
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runAfterPassInvalidated(const PassT &Pass, const PreservedAnalyses &PA) const
AfterPassInvalidated instrumentation point - takes Pass instance that has just been executed.
void pushBeforeNonSkippedPassCallback(CallableT C)
PassInstrumentation(PassInstrumentationCallbacks *CB=nullptr)
Callbacks object is not owned by PassInstrumentation, its life-time should at least match the life-ti...
bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &, ExtraArgsT...)
Handle invalidation from the pass manager when PassInstrumentation is used as the result of PassInstr...
void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const
BeforeAnalysis instrumentation point - takes Analysis instance to be executed and constant reference ...
void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const
AnalysisInvalidated instrumentation point - takes Analysis instance that has just been invalidated an...
void runAnalysesCleared(StringRef Name) const
AnalysesCleared instrumentation point - takes name of IR that analyses operated on.
StringRef getPassNameForClassName(StringRef ClassName) const
Get the pass name for a given pass class name.
void runAfterPass(const PassT &Pass, const IRUnitT &IR, const PreservedAnalyses &PA) const
AfterPass instrumentation point - takes Pass instance that has just been executed and constant refere...
void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const
AfterAnalysis instrumentation point - takes Analysis instance that has just been executed and constan...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
unique_function is a type-erasing functor similar to std::function.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29