diff --git a/include/llvm/IR/PassInstrumentation.h b/include/llvm/IR/PassInstrumentation.h index 8bee51e8d51..137053854fc 100644 --- a/include/llvm/IR/PassInstrumentation.h +++ b/include/llvm/IR/PassInstrumentation.h @@ -243,6 +243,16 @@ public: ExtraArgsT...) { return false; } + + template + void pushBeforeNonSkippedPassCallback(CallableT C) { + if (Callbacks) + Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C)); + } + void popBeforeNonSkippedPassCallback() { + if (Callbacks) + Callbacks->BeforeNonSkippedPassCallbacks.pop_back(); + } }; bool isSpecialPass(StringRef PassID, const std::vector &Specials); diff --git a/include/llvm/Transforms/Scalar/LoopPassManager.h b/include/llvm/Transforms/Scalar/LoopPassManager.h index aff80ef1dcf..edc27b7f8a1 100644 --- a/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -50,6 +50,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassManager.h" #include "llvm/Transforms/Utils/LCSSA.h" #include "llvm/Transforms/Utils/LoopSimplify.h" @@ -296,6 +297,21 @@ public: // declaration. appendLoopsToWorklist(LI, Worklist); +#ifndef NDEBUG + PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) { + if (isSpecialPass(PassID, {"PassManager"})) + return; + assert(any_isa(IR)); + const Loop *L = any_cast(IR); + assert(L && "Loop should be valid for printing"); + + // Verify the loop structure and LCSSA form before visiting the loop. + L->verifyLoop(); + assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) && + "Loops must remain in LCSSA form!"); + }); +#endif + do { Loop *L = Worklist.pop_back_val(); @@ -306,11 +322,6 @@ public: #ifndef NDEBUG // Save a parent loop pointer for asserts. Updater.ParentL = L->getParentLoop(); - - // Verify the loop structure and LCSSA form before visiting the loop. - L->verifyLoop(); - assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) && - "Loops must remain in LCSSA form!"); #endif // Check the PassInstrumentation's BeforePass callbacks before running the // pass, skip its execution completely if asked to (callback returns @@ -345,6 +356,10 @@ public: PA.intersect(std::move(PassPA)); } while (!Worklist.empty()); +#ifndef NDEBUG + PI.popBeforeNonSkippedPassCallback(); +#endif + // By definition we preserve the proxy. We also preserve all analyses on // Loops. This precludes *any* invalidation of loop analyses by the proxy, // but that's OK because we've taken care to invalidate analyses in the diff --git a/lib/Transforms/Scalar/LoopPassManager.cpp b/lib/Transforms/Scalar/LoopPassManager.cpp index 91de5715a6a..2b0ac78f52d 100644 --- a/lib/Transforms/Scalar/LoopPassManager.cpp +++ b/lib/Transforms/Scalar/LoopPassManager.cpp @@ -57,13 +57,6 @@ PassManager