diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h --- a/llvm/include/llvm/IR/PassInstrumentation.h +++ b/llvm/include/llvm/IR/PassInstrumentation.h @@ -67,11 +67,14 @@ // to take them as constant pointers, wrapped with llvm::Any. // For the case when IRUnit has been invalidated there is a different // callback to use - AfterPassInvalidated. + // BeforeNonSkippedPassFunc is called when we know for sure that the pass + // would be run. BeforePassFunc could not make such assumption. // TODO: currently AfterPassInvalidated does not accept IRUnit, since passing - // 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. + // 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. using BeforePassFunc = bool(StringRef, Any); + using BeforeNonSkippedPassFunc = void(StringRef, Any); using AfterPassFunc = void(StringRef, Any); using AfterPassInvalidatedFunc = void(StringRef); using BeforeAnalysisFunc = void(StringRef, Any); @@ -88,6 +91,11 @@ BeforePassCallbacks.emplace_back(std::move(C)); } + template + void registerBeforeNonSkippedPassCallback(CallableT C) { + BeforeNonSkippedPassCallbacks.emplace_back(std::move(C)); + } + template void registerAfterPassCallback(CallableT C) { AfterPassCallbacks.emplace_back(std::move(C)); } @@ -111,6 +119,8 @@ friend class PassInstrumentation; SmallVector, 4> BeforePassCallbacks; + SmallVector, 4> + BeforeNonSkippedPassCallbacks; SmallVector, 4> AfterPassCallbacks; SmallVector, 4> AfterPassInvalidatedCallbacks; @@ -165,6 +175,12 @@ for (auto &C : Callbacks->BeforePassCallbacks) ShouldRun &= C(Pass.name(), llvm::Any(&IR)); ShouldRun = ShouldRun || isRequired(Pass); + + if (ShouldRun) { + for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks) + C(Pass.name(), llvm::Any(&IR)); + } + return ShouldRun; }