File indexing completed on 2026-05-10 08:44:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #ifndef LLVM_IR_PASSINSTRUMENTATION_H
0050 #define LLVM_IR_PASSINSTRUMENTATION_H
0051
0052 #include "llvm/ADT/Any.h"
0053 #include "llvm/ADT/DenseMap.h"
0054 #include "llvm/ADT/FunctionExtras.h"
0055 #include "llvm/ADT/SmallVector.h"
0056 #include "llvm/IR/PassManager.h"
0057 #include "llvm/Support/Compiler.h"
0058 #include <type_traits>
0059 #include <vector>
0060
0061 namespace llvm {
0062
0063 class PreservedAnalyses;
0064 class StringRef;
0065 class Module;
0066 class Loop;
0067 class Function;
0068
0069 extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Module *>;
0070 extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Function *>;
0071 extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Loop *>;
0072
0073
0074
0075 class PassInstrumentationCallbacks {
0076 public:
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 using BeforePassFunc = bool(StringRef, Any);
0088 using BeforeSkippedPassFunc = void(StringRef, Any);
0089 using BeforeNonSkippedPassFunc = void(StringRef, Any);
0090 using AfterPassFunc = void(StringRef, Any, const PreservedAnalyses &);
0091 using AfterPassInvalidatedFunc = void(StringRef, const PreservedAnalyses &);
0092 using BeforeAnalysisFunc = void(StringRef, Any);
0093 using AfterAnalysisFunc = void(StringRef, Any);
0094 using AnalysisInvalidatedFunc = void(StringRef, Any);
0095 using AnalysesClearedFunc = void(StringRef);
0096
0097 public:
0098 PassInstrumentationCallbacks() = default;
0099
0100
0101 PassInstrumentationCallbacks(const PassInstrumentationCallbacks &) = delete;
0102 void operator=(const PassInstrumentationCallbacks &) = delete;
0103
0104 template <typename CallableT>
0105 void registerShouldRunOptionalPassCallback(CallableT C) {
0106 ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
0107 }
0108
0109 template <typename CallableT>
0110 void registerBeforeSkippedPassCallback(CallableT C) {
0111 BeforeSkippedPassCallbacks.emplace_back(std::move(C));
0112 }
0113
0114 template <typename CallableT>
0115 void registerBeforeNonSkippedPassCallback(CallableT C) {
0116 BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
0117 }
0118
0119 template <typename CallableT>
0120 void registerAfterPassCallback(CallableT C, bool ToFront = false) {
0121 if (ToFront)
0122 AfterPassCallbacks.insert(AfterPassCallbacks.begin(), std::move(C));
0123 else
0124 AfterPassCallbacks.emplace_back(std::move(C));
0125 }
0126
0127 template <typename CallableT>
0128 void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront = false) {
0129 if (ToFront)
0130 AfterPassInvalidatedCallbacks.insert(
0131 AfterPassInvalidatedCallbacks.begin(), std::move(C));
0132 else
0133 AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
0134 }
0135
0136 template <typename CallableT>
0137 void registerBeforeAnalysisCallback(CallableT C) {
0138 BeforeAnalysisCallbacks.emplace_back(std::move(C));
0139 }
0140
0141 template <typename CallableT>
0142 void registerAfterAnalysisCallback(CallableT C, bool ToFront = false) {
0143 if (ToFront)
0144 AfterAnalysisCallbacks.insert(AfterAnalysisCallbacks.begin(),
0145 std::move(C));
0146 else
0147 AfterAnalysisCallbacks.emplace_back(std::move(C));
0148 }
0149
0150 template <typename CallableT>
0151 void registerAnalysisInvalidatedCallback(CallableT C) {
0152 AnalysisInvalidatedCallbacks.emplace_back(std::move(C));
0153 }
0154
0155 template <typename CallableT>
0156 void registerAnalysesClearedCallback(CallableT C) {
0157 AnalysesClearedCallbacks.emplace_back(std::move(C));
0158 }
0159
0160 template <typename CallableT>
0161 void registerClassToPassNameCallback(CallableT C) {
0162 ClassToPassNameCallbacks.emplace_back(std::move(C));
0163 }
0164
0165
0166 void addClassToPassName(StringRef ClassName, StringRef PassName);
0167
0168 StringRef getPassNameForClassName(StringRef ClassName);
0169
0170 private:
0171 friend class PassInstrumentation;
0172
0173
0174
0175 SmallVector<llvm::unique_function<BeforePassFunc>, 4>
0176 ShouldRunOptionalPassCallbacks;
0177
0178 SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
0179 BeforeSkippedPassCallbacks;
0180
0181 SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
0182 BeforeNonSkippedPassCallbacks;
0183
0184 SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
0185
0186 SmallVector<llvm::unique_function<AfterPassInvalidatedFunc>, 4>
0187 AfterPassInvalidatedCallbacks;
0188
0189 SmallVector<llvm::unique_function<BeforeAnalysisFunc>, 4>
0190 BeforeAnalysisCallbacks;
0191
0192 SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
0193 AfterAnalysisCallbacks;
0194
0195 SmallVector<llvm::unique_function<AnalysisInvalidatedFunc>, 4>
0196 AnalysisInvalidatedCallbacks;
0197
0198 SmallVector<llvm::unique_function<AnalysesClearedFunc>, 4>
0199 AnalysesClearedCallbacks;
0200
0201 SmallVector<llvm::unique_function<void ()>, 4> ClassToPassNameCallbacks;
0202 DenseMap<StringRef, std::string> ClassToPassName;
0203 };
0204
0205
0206
0207 class PassInstrumentation {
0208 PassInstrumentationCallbacks *Callbacks;
0209
0210
0211
0212
0213
0214
0215
0216 template <typename PassT>
0217 using has_required_t = decltype(std::declval<PassT &>().isRequired());
0218
0219 template <typename PassT>
0220 static std::enable_if_t<is_detected<has_required_t, PassT>::value, bool>
0221 isRequired(const PassT &Pass) {
0222 return Pass.isRequired();
0223 }
0224 template <typename PassT>
0225 static std::enable_if_t<!is_detected<has_required_t, PassT>::value, bool>
0226 isRequired(const PassT &Pass) {
0227 return false;
0228 }
0229
0230 public:
0231
0232
0233
0234
0235 PassInstrumentation(PassInstrumentationCallbacks *CB = nullptr)
0236 : Callbacks(CB) {}
0237
0238
0239
0240
0241
0242
0243 template <typename IRUnitT, typename PassT>
0244 bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
0245 if (!Callbacks)
0246 return true;
0247
0248 bool ShouldRun = true;
0249 if (!isRequired(Pass)) {
0250 for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
0251 ShouldRun &= C(Pass.name(), llvm::Any(&IR));
0252 }
0253
0254 if (ShouldRun) {
0255 for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
0256 C(Pass.name(), llvm::Any(&IR));
0257 } else {
0258 for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
0259 C(Pass.name(), llvm::Any(&IR));
0260 }
0261
0262 return ShouldRun;
0263 }
0264
0265
0266
0267
0268 template <typename IRUnitT, typename PassT>
0269 void runAfterPass(const PassT &Pass, const IRUnitT &IR,
0270 const PreservedAnalyses &PA) const {
0271 if (Callbacks)
0272 for (auto &C : Callbacks->AfterPassCallbacks)
0273 C(Pass.name(), llvm::Any(&IR), PA);
0274 }
0275
0276
0277
0278
0279 template <typename IRUnitT, typename PassT>
0280 void runAfterPassInvalidated(const PassT &Pass,
0281 const PreservedAnalyses &PA) const {
0282 if (Callbacks)
0283 for (auto &C : Callbacks->AfterPassInvalidatedCallbacks)
0284 C(Pass.name(), PA);
0285 }
0286
0287
0288
0289 template <typename IRUnitT, typename PassT>
0290 void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
0291 if (Callbacks)
0292 for (auto &C : Callbacks->BeforeAnalysisCallbacks)
0293 C(Analysis.name(), llvm::Any(&IR));
0294 }
0295
0296
0297
0298 template <typename IRUnitT, typename PassT>
0299 void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
0300 if (Callbacks)
0301 for (auto &C : Callbacks->AfterAnalysisCallbacks)
0302 C(Analysis.name(), llvm::Any(&IR));
0303 }
0304
0305
0306
0307
0308 template <typename IRUnitT, typename PassT>
0309 void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const {
0310 if (Callbacks)
0311 for (auto &C : Callbacks->AnalysisInvalidatedCallbacks)
0312 C(Analysis.name(), llvm::Any(&IR));
0313 }
0314
0315
0316
0317 void runAnalysesCleared(StringRef Name) const {
0318 if (Callbacks)
0319 for (auto &C : Callbacks->AnalysesClearedCallbacks)
0320 C(Name);
0321 }
0322
0323
0324
0325
0326
0327
0328 template <typename IRUnitT, typename... ExtraArgsT>
0329 bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
0330 ExtraArgsT...) {
0331 return false;
0332 }
0333
0334 template <typename CallableT>
0335 void pushBeforeNonSkippedPassCallback(CallableT C) {
0336 if (Callbacks)
0337 Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
0338 }
0339 void popBeforeNonSkippedPassCallback() {
0340 if (Callbacks)
0341 Callbacks->BeforeNonSkippedPassCallbacks.pop_back();
0342 }
0343
0344
0345 StringRef getPassNameForClassName(StringRef ClassName) const {
0346 if (Callbacks)
0347 return Callbacks->getPassNameForClassName(ClassName);
0348 return {};
0349 }
0350 };
0351
0352 bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials);
0353
0354
0355
0356 class PassInstrumentationAnalysis
0357 : public AnalysisInfoMixin<PassInstrumentationAnalysis> {
0358 friend AnalysisInfoMixin<PassInstrumentationAnalysis>;
0359 static AnalysisKey Key;
0360
0361 PassInstrumentationCallbacks *Callbacks;
0362
0363 public:
0364
0365
0366 PassInstrumentationAnalysis(PassInstrumentationCallbacks *Callbacks = nullptr)
0367 : Callbacks(Callbacks) {}
0368
0369 using Result = PassInstrumentation;
0370
0371 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
0372 Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
0373 return PassInstrumentation(Callbacks);
0374 }
0375 };
0376
0377
0378 }
0379
0380 #endif