Index: include/llvm/Analysis/PostDominators.h =================================================================== --- include/llvm/Analysis/PostDominators.h +++ include/llvm/Analysis/PostDominators.h @@ -32,6 +32,12 @@ /// Handle invalidation explicitly. bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &); + + /// \brief Verify the correctness of the postdomtree. + /// + /// This should only be used for debugging as it aborts the program if the + /// verification fails. + void verifyDomTree() const; }; /// \brief Analysis pass which computes a \c PostDominatorTree. @@ -75,6 +81,8 @@ bool runOnFunction(Function &F) override; + void verifyAnalysis() const override; + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } Index: include/llvm/IR/Dominators.h =================================================================== --- include/llvm/IR/Dominators.h +++ include/llvm/IR/Dominators.h @@ -174,7 +174,7 @@ /// \brief Provide an overload for a Use. bool isReachableFromEntry(const Use &U) const; - /// \brief Verify the correctness of the domtree by re-computing it. + /// \brief Verify the correctness of the domtree. /// /// This should only be used for debugging as it aborts the program if the /// verification fails. Index: include/llvm/Support/GenericDomTreeConstruction.h =================================================================== --- include/llvm/Support/GenericDomTreeConstruction.h +++ include/llvm/Support/GenericDomTreeConstruction.h @@ -1606,7 +1606,8 @@ const bool Different = DT.compare(FreshTree); if (Different) { - errs() << "DominatorTree is different than a freshly computed one!\n" + errs() << (DT.isPostDominator() ? "Post" : "") + << "DominatorTree is different than a freshly computed one!\n" << "\tCurrent:\n"; DT.print(errs()); errs() << "\n\tFreshly computed tree:\n"; Index: lib/Analysis/PostDominators.cpp =================================================================== --- lib/Analysis/PostDominators.cpp +++ lib/Analysis/PostDominators.cpp @@ -21,6 +21,12 @@ #define DEBUG_TYPE "postdomtree" +#ifdef EXPENSIVE_CHECKS +static constexpr bool ExpensiveChecksEnabled = true; +#else +static constexpr bool ExpensiveChecksEnabled = false; +#endif + //===----------------------------------------------------------------------===// // PostDominatorTree Implementation //===----------------------------------------------------------------------===// @@ -39,11 +45,33 @@ PAC.preservedSet()); } +void PostDominatorTree::verifyDomTree() const { + // Perform the expensive checks only when VerifyDomInfo is set. + VerificationLevel VL = VerificationLevel::Fast; + if (VerifyDomInfo) + VL = VerificationLevel::Full; + else if (ExpensiveChecksEnabled) + VL = VerificationLevel::Basic; + + if (!verify(VL)) { + errs() << "\n~~~~~~~~~~~\n\t\tPostDomTree verification failed!\n~~~~~~~~~~~\n"; + errs() << "\nCFG:\n"; + getRoot()->getParent()->print(errs()); + errs().flush(); + abort(); + } +} + bool PostDominatorTreeWrapperPass::runOnFunction(Function &F) { DT.recalculate(F); return false; } +void PostDominatorTreeWrapperPass::verifyAnalysis() const { + if (ExpensiveChecksEnabled || VerifyDomInfo) + DT.verifyDomTree(); +} + void PostDominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const { DT.print(OS); }