LLVM 19.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 llvm::Any and passes
39/// control to all the registered callbacks. Note that we specifically wrap
40/// 'const IRUnitT*' so as to avoid any accidental changes to IR in
41/// 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/Any.h"
55#include "llvm/ADT/StringMap.h"
56#include <type_traits>
57#include <vector>
58
59namespace llvm {
60
61class PreservedAnalyses;
62class StringRef;
63
64/// This class manages callbacks registration, as well as provides a way for
65/// PassInstrumentation to pass control to the registered callbacks.
67public:
68 // Before/After callbacks accept IRUnits whenever appropriate, so they need
69 // to take them as constant pointers, wrapped with llvm::Any.
70 // For the case when IRUnit has been invalidated there is a different
71 // callback to use - AfterPassInvalidated.
72 // We call all BeforePassFuncs to determine if a pass should run or not.
73 // BeforeNonSkippedPassFuncs are called only if the pass should run.
74 // TODO: currently AfterPassInvalidated does not accept IRUnit, since passing
75 // already invalidated IRUnit is unsafe. There are ways to handle invalidated
76 // IRUnits in a safe way, and we might pursue that as soon as there is a
77 // useful instrumentation that needs it.
87
88public:
90
91 /// Copying PassInstrumentationCallbacks is not intended.
94
95 template <typename CallableT>
97 ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
98 }
99
100 template <typename CallableT>
102 BeforeSkippedPassCallbacks.emplace_back(std::move(C));
103 }
104
105 template <typename CallableT>
107 BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
108 }
109
110 template <typename CallableT>
111 void registerAfterPassCallback(CallableT C, bool ToFront = false) {
112 if (ToFront)
113 AfterPassCallbacks.insert(AfterPassCallbacks.begin(), std::move(C));
114 else
115 AfterPassCallbacks.emplace_back(std::move(C));
116 }
117
118 template <typename CallableT>
119 void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront = false) {
120 if (ToFront)
121 AfterPassInvalidatedCallbacks.insert(
122 AfterPassInvalidatedCallbacks.begin(), std::move(C));
123 else
124 AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
125 }
126
127 template <typename CallableT>
129 BeforeAnalysisCallbacks.emplace_back(std::move(C));
130 }
131
132 template <typename CallableT>
133 void registerAfterAnalysisCallback(CallableT C, bool ToFront = false) {
134 if (ToFront)
135 AfterAnalysisCallbacks.insert(AfterAnalysisCallbacks.begin(),
136 std::move(C));
137 else
138 AfterAnalysisCallbacks.emplace_back(std::move(C));
139 }
140
141 template <typename CallableT>
143 AnalysisInvalidatedCallbacks.emplace_back(std::move(C));
144 }
145
146 template <typename CallableT>
148 AnalysesClearedCallbacks.emplace_back(std::move(C));
149 }
150
151 /// Add a class name to pass name mapping for use by pass instrumentation.
153 /// Get the pass name for a given pass class name.
155
156private:
158
159 /// These are only run on passes that are not required. They return false when
160 /// an optional pass should be skipped.
162 ShouldRunOptionalPassCallbacks;
163 /// These are run on passes that are skipped.
165 BeforeSkippedPassCallbacks;
166 /// These are run on passes that are about to be run.
168 BeforeNonSkippedPassCallbacks;
169 /// These are run on passes that have just run.
171 /// These are run passes that have just run on invalidated IR.
173 AfterPassInvalidatedCallbacks;
174 /// These are run on analyses that are about to be run.
176 BeforeAnalysisCallbacks;
177 /// These are run on analyses that have been run.
179 AfterAnalysisCallbacks;
180 /// These are run on analyses that have been invalidated.
182 AnalysisInvalidatedCallbacks;
183 /// These are run on analyses that have been cleared.
185 AnalysesClearedCallbacks;
186
187 StringMap<std::string> ClassToPassName;
188};
189
190/// This class provides instrumentation entry points for the Pass Manager,
191/// doing calls to callbacks registered in PassInstrumentationCallbacks.
194
195 // Template argument PassT of PassInstrumentation::runBeforePass could be two
196 // kinds: (1) a regular pass inherited from PassInfoMixin (happen when
197 // creating a adaptor pass for a regular pass); (2) a type-erased PassConcept
198 // created from (1). Here we want to make case (1) skippable unconditionally
199 // since they are regular passes. We call PassConcept::isRequired to decide
200 // for case (2).
201 template <typename PassT>
202 using has_required_t = decltype(std::declval<PassT &>().isRequired());
203
204 template <typename PassT>
205 static std::enable_if_t<is_detected<has_required_t, PassT>::value, bool>
206 isRequired(const PassT &Pass) {
207 return Pass.isRequired();
208 }
209 template <typename PassT>
210 static std::enable_if_t<!is_detected<has_required_t, PassT>::value, bool>
211 isRequired(const PassT &Pass) {
212 return false;
213 }
214
215public:
216 /// Callbacks object is not owned by PassInstrumentation, its life-time
217 /// should at least match the life-time of corresponding
218 /// PassInstrumentationAnalysis (which usually is till the end of current
219 /// compilation).
221 : Callbacks(CB) {}
222
223 /// BeforePass instrumentation point - takes \p Pass instance to be executed
224 /// and constant reference to IR it operates on. \Returns true if pass is
225 /// allowed to be executed. These are only run on optional pass since required
226 /// passes must always be run. This allows these callbacks to print info when
227 /// they want to skip a pass.
228 template <typename IRUnitT, typename PassT>
229 bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
230 if (!Callbacks)
231 return true;
232
233 bool ShouldRun = true;
234 if (!isRequired(Pass)) {
235 for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
236 ShouldRun &= C(Pass.name(), llvm::Any(&IR));
237 }
238
239 if (ShouldRun) {
240 for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
241 C(Pass.name(), llvm::Any(&IR));
242 } else {
243 for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
244 C(Pass.name(), llvm::Any(&IR));
245 }
246
247 return ShouldRun;
248 }
249
250 /// AfterPass instrumentation point - takes \p Pass instance that has
251 /// just been executed and constant reference to \p IR it operates on.
252 /// \p IR is guaranteed to be valid at this point.
253 template <typename IRUnitT, typename PassT>
254 void runAfterPass(const PassT &Pass, const IRUnitT &IR,
255 const PreservedAnalyses &PA) const {
256 if (Callbacks)
257 for (auto &C : Callbacks->AfterPassCallbacks)
258 C(Pass.name(), llvm::Any(&IR), PA);
259 }
260
261 /// AfterPassInvalidated instrumentation point - takes \p Pass instance
262 /// that has just been executed. For use when IR has been invalidated
263 /// by \p Pass execution.
264 template <typename IRUnitT, typename PassT>
266 const PreservedAnalyses &PA) const {
267 if (Callbacks)
268 for (auto &C : Callbacks->AfterPassInvalidatedCallbacks)
269 C(Pass.name(), PA);
270 }
271
272 /// BeforeAnalysis instrumentation point - takes \p Analysis instance
273 /// to be executed and constant reference to IR it operates on.
274 template <typename IRUnitT, typename PassT>
275 void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
276 if (Callbacks)
277 for (auto &C : Callbacks->BeforeAnalysisCallbacks)
278 C(Analysis.name(), llvm::Any(&IR));
279 }
280
281 /// AfterAnalysis instrumentation point - takes \p Analysis instance
282 /// that has just been executed and constant reference to IR it operated on.
283 template <typename IRUnitT, typename PassT>
284 void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
285 if (Callbacks)
286 for (auto &C : Callbacks->AfterAnalysisCallbacks)
287 C(Analysis.name(), llvm::Any(&IR));
288 }
289
290 /// AnalysisInvalidated instrumentation point - takes \p Analysis instance
291 /// that has just been invalidated and constant reference to IR it operated
292 /// on.
293 template <typename IRUnitT, typename PassT>
294 void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const {
295 if (Callbacks)
296 for (auto &C : Callbacks->AnalysisInvalidatedCallbacks)
297 C(Analysis.name(), llvm::Any(&IR));
298 }
299
300 /// AnalysesCleared instrumentation point - takes name of IR that analyses
301 /// operated on.
303 if (Callbacks)
304 for (auto &C : Callbacks->AnalysesClearedCallbacks)
305 C(Name);
306 }
307
308 /// Handle invalidation from the pass manager when PassInstrumentation
309 /// is used as the result of PassInstrumentationAnalysis.
310 ///
311 /// On attempt to invalidate just return false. There is nothing to become
312 /// invalid here.
313 template <typename IRUnitT, typename... ExtraArgsT>
314 bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
315 ExtraArgsT...) {
316 return false;
317 }
318
319 template <typename CallableT>
321 if (Callbacks)
322 Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
323 }
325 if (Callbacks)
326 Callbacks->BeforeNonSkippedPassCallbacks.pop_back();
327 }
328};
329
330bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials);
331
332} // namespace llvm
333
334#endif
This file defines the StringMap class.
This file provides Any, a non-template class modeled in the spirit of std::any.
block Block Frequency Analysis
std::string Name
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:81
This file defines the SmallVector class.
static const char PassName[]
Definition: Any.h:28
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)
StringRef getPassNameForClassName(StringRef ClassName)
Get the pass name for a given pass class name.
void registerAfterAnalysisCallback(CallableT C, bool ToFront=false)
void(StringRef, const PreservedAnalyses &) AfterPassInvalidatedFunc
void(StringRef, Any) BeforeNonSkippedPassFunc
void registerBeforeNonSkippedPassCallback(CallableT C)
void registerBeforeSkippedPassCallback(CallableT C)
PassInstrumentationCallbacks(const PassInstrumentationCallbacks &)=delete
Copying PassInstrumentationCallbacks is not intended.
void addClassToPassName(StringRef ClassName, StringRef PassName)
Add a class name to pass name mapping for use by pass instrumentation.
void registerShouldRunOptionalPassCallback(CallableT C)
void(StringRef, Any) BeforeSkippedPassFunc
void operator=(const PassInstrumentationCallbacks &)=delete
void(StringRef, Any) AnalysisInvalidatedFunc
void(StringRef, Any, const PreservedAnalyses &) AfterPassFunc
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.
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:94
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:818
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:127
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)