Index: llvm/include/llvm/IR/PassInstrumentation.h =================================================================== --- llvm/include/llvm/IR/PassInstrumentation.h +++ llvm/include/llvm/IR/PassInstrumentation.h @@ -75,7 +75,10 @@ // already invalidated IRUnit is unsafe. There are ways to handle invalidated IRUnits // in a safe way, and we might pursue that as soon as there is a useful instrumentation // that needs it. + // For every Before callback called there is either After, AfterInvalidated + // or AfterSkipped call with the same pass name and IRUnit if available. using BeforePassFunc = bool(StringRef, Any); + using AfterPassSkippedFunc = void(StringRef, Any); using AfterPassFunc = void(StringRef, Any, const PreservedAnalyses &); using AfterPassInvalidatedFunc = void(StringRef, const PreservedAnalyses &); using BeforeAnalysisFunc = void(StringRef, Any); @@ -92,6 +95,11 @@ BeforePassCallbacks.emplace_back(std::move(C)); } + template + void registerAfterPassSkippedCallback(CallableT C) { + AfterPassSkippedCallbacks.emplace_back(std::move(C)); + } + template void registerAfterPassCallback(CallableT C) { AfterPassCallbacks.emplace_back(std::move(C)); } @@ -115,6 +123,8 @@ friend class PassInstrumentation; SmallVector, 4> BeforePassCallbacks; + SmallVector, 4> + AfterPassSkippedCallbacks; SmallVector, 4> AfterPassCallbacks; SmallVector, 4> AfterPassInvalidatedCallbacks; @@ -169,6 +179,11 @@ for (auto &C : Callbacks->BeforePassCallbacks) ShouldRun &= C(Pass.name(), llvm::Any(&IR)); ShouldRun = ShouldRun || isRequired(Pass); + + if (!ShouldRun) + for (auto &C : Callbacks->AfterPassSkippedCallbacks) + C(Pass.name(), llvm::Any(&IR)); + return ShouldRun; }