diff --git a/llvm/include/llvm/Analysis/Dominators.h b/llvm/include/llvm/Analysis/Dominators.h index e8aceaa6226f..f63e31c36bab 100644 --- a/llvm/include/llvm/Analysis/Dominators.h +++ b/llvm/include/llvm/Analysis/Dominators.h @@ -734,6 +734,8 @@ public: virtual bool runOnFunction(Function &F); + virtual void verifyAnalysis() const; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } @@ -991,6 +993,8 @@ public: return false; } + virtual void verifyAnalysis() const; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); diff --git a/llvm/include/llvm/PassManagers.h b/llvm/include/llvm/PassManagers.h index a067294e9fa4..5a8f55570a82 100644 --- a/llvm/include/llvm/PassManagers.h +++ b/llvm/include/llvm/PassManagers.h @@ -280,9 +280,6 @@ public: /// verifyPreservedAnalysis -- Verify analysis presreved by pass P. void verifyPreservedAnalysis(Pass *P); - /// verifyDomInfo -- Verify dominator information if it is available. - void verifyDomInfo(Pass &P, Function &F); - /// Remove Analysis that is not preserved by the pass void removeNotPreservedAnalysis(Pass *P); diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 665e53df6dcc..ce2d29f331b6 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -20,11 +20,22 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/CommandLine.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include using namespace llvm; +// Always verify loopinfo if expensive checking is enabled. +#ifdef XDEBUG +bool VerifyLoopInfo = true; +#else +bool VerifyLoopInfo = false; +#endif +static cl::opt +VerifyLoopInfoX("verify-loop-info", cl::location(VerifyLoopInfo), + cl::desc("Verify loop info (time consuming)")); + char LoopInfo::ID = 0; static RegisterPass X("loops", "Natural Loop Information", true, true); @@ -375,10 +386,20 @@ bool LoopInfo::runOnFunction(Function &) { } void LoopInfo::verifyAnalysis() const { + // LoopInfo is a FunctionPass, but verifying every loop in the function + // each time verifyAnalysis is called is very expensive. The + // -verify-loop-info option can enable this. In order to perform some + // checking by default, LoopPass has been taught to call verifyLoop + // manually during loop pass sequences. + + if (!VerifyLoopInfo) return; + for (iterator I = begin(), E = end(); I != E; ++I) { assert(!(*I)->getParentLoop() && "Top-level loop has a parent!"); (*I)->verifyLoopNest(); } + + // TODO: check BBMap consistency. } void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const { diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index e297ab420731..22466ae3d061 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -242,16 +242,24 @@ bool LPPassManager::runOnFunction(Function &F) { dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, ""); dumpPreservedSet(P); - if (!skipThisLoop) + if (!skipThisLoop) { + // Manually check that this loop is still healthy. This is done + // instead of relying on LoopInfo::verifyLoop since LoopInfo + // is a function pass and it's really expensive to verify every + // loop in the function every time. That level of checking can be + // enabled with the -verify-loop-info option. + Timer *T = StartPassTimer(LI); + CurrentLoop->verifyLoop(); + StopPassTimer(LI, T); + + // Then call the regular verifyAnalysis functions. verifyPreservedAnalysis(LP); + } removeNotPreservedAnalysis(P); recordAvailableAnalysis(P); removeDeadPasses(P, "", ON_LOOP_MSG); - // If dominator information is available then verify the info if requested. - verifyDomInfo(*LP, F); - if (skipThisLoop) // Do not run other passes on this loop. break; diff --git a/llvm/lib/VMCore/Dominators.cpp b/llvm/lib/VMCore/Dominators.cpp index 1f172145c3b1..40e4c4bc4c8d 100644 --- a/llvm/lib/VMCore/Dominators.cpp +++ b/llvm/lib/VMCore/Dominators.cpp @@ -24,9 +24,20 @@ #include "llvm/Analysis/DominatorInternals.h" #include "llvm/Instructions.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/CommandLine.h" #include using namespace llvm; +// Always verify dominfo if expensive checking is enabled. +#ifdef XDEBUG +bool VerifyDomInfo = true; +#else +bool VerifyDomInfo = false; +#endif +static cl::opt +VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), + cl::desc("Verify dominator info (time consuming)")); + //===----------------------------------------------------------------------===// // DominatorTree Implementation //===----------------------------------------------------------------------===// @@ -48,6 +59,16 @@ bool DominatorTree::runOnFunction(Function &F) { return false; } +void DominatorTree::verifyAnalysis() const { + if (!VerifyDomInfo || true /* fixme */) return; + + Function &F = *getRoot()->getParent(); + + DominatorTree OtherDT; + OtherDT.getBase().recalculate(F); + assert(!compare(OtherDT) && "Invalid DominatorTree info!"); +} + void DominatorTree::print(raw_ostream &OS, const Module *) const { DT->print(OS); } @@ -87,6 +108,17 @@ char DominanceFrontier::ID = 0; static RegisterPass G("domfrontier", "Dominance Frontier Construction", true, true); +void DominanceFrontier::verifyAnalysis() const { + if (!VerifyDomInfo) return; + + DominatorTree &DT = getAnalysis(); + + DominanceFrontier OtherDF; + const std::vector &DTRoots = DT.getRoots(); + OtherDF.calculate(DT, DT.getNode(DTRoots[0])); + assert(!compare(OtherDF) && "Invalid DominanceFrontier info!"); +} + // NewBB is split and now it has one successor. Update dominace frontier to // reflect this change. void DominanceFrontier::splitBlock(BasicBlock *NewBB) { diff --git a/llvm/lib/VMCore/PassManager.cpp b/llvm/lib/VMCore/PassManager.cpp index a3496ed9b4f9..f10bc6f5ef6f 100644 --- a/llvm/lib/VMCore/PassManager.cpp +++ b/llvm/lib/VMCore/PassManager.cpp @@ -13,6 +13,7 @@ #include "llvm/PassManagers.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Timer.h" #include "llvm/Module.h" @@ -22,7 +23,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" -#include "llvm/Analysis/Dominators.h" #include "llvm-c/Core.h" #include #include @@ -45,16 +45,6 @@ enum PassDebugLevel { None, Arguments, Structure, Executions, Details }; -// Always verify dominfo if expensive checking is enabled. -#ifdef XDEBUG -bool VerifyDomInfo = true; -#else -bool VerifyDomInfo = false; -#endif -static cl::opt -VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), - cl::desc("Verify dominator info (time consuming)")); - static cl::opt PassDebugging("debug-pass", cl::Hidden, cl::desc("Print PassManager debugging information"), @@ -703,47 +693,13 @@ void PMDataManager::verifyPreservedAnalysis(Pass *P) { for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), E = PreservedSet.end(); I != E; ++I) { AnalysisID AID = *I; - if (Pass *AP = findAnalysisPass(AID, true)) + if (Pass *AP = findAnalysisPass(AID, true)) { + + Timer *T = 0; + if (TheTimeInfo) T = TheTimeInfo->passStarted(AP); AP->verifyAnalysis(); - } -} - -/// verifyDomInfo - Verify dominator information if it is available. -void PMDataManager::verifyDomInfo(Pass &P, Function &F) { - if (!VerifyDomInfo || !P.getResolver()) - return; - - DominatorTree *DT = P.getAnalysisIfAvailable(); - if (!DT) - return; - - DominatorTree OtherDT; - OtherDT.getBase().recalculate(F); - if (DT->compare(OtherDT)) { - errs() << "Dominator Information for " << F.getName() << "\n"; - errs() << "Pass '" << P.getPassName() << "'\n"; - errs() << "----- Valid -----\n"; - OtherDT.dump(); - errs() << "----- Invalid -----\n"; - DT->dump(); - llvm_unreachable("Invalid dominator info"); - } - - DominanceFrontier *DF = P.getAnalysisIfAvailable(); - if (!DF) - return; - - DominanceFrontier OtherDF; - std::vector DTRoots = DT->getRoots(); - OtherDF.calculate(*DT, DT->getNode(DTRoots[0])); - if (DF->compare(OtherDF)) { - errs() << "Dominator Information for " << F.getName() << "\n"; - errs() << "Pass '" << P.getPassName() << "'\n"; - errs() << "----- Valid -----\n"; - OtherDF.dump(); - errs() << "----- Invalid -----\n"; - DF->dump(); - llvm_unreachable("Invalid dominator info"); + if (T) T->stopTimer(); + } } } @@ -1384,9 +1340,6 @@ bool FPPassManager::runOnFunction(Function &F) { removeNotPreservedAnalysis(FP); recordAvailableAnalysis(FP); removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); - - // If dominator information is available then verify the info if requested. - verifyDomInfo(*FP, F); } return Changed; } diff --git a/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll b/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll index 42fb54ce7c8f..cee4d724bf4b 100644 --- a/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll +++ b/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll @@ -1,4 +1,4 @@ -; RUN: llc %s -o /dev/null -verify-dom-info +; RUN: llc %s -o /dev/null -verify-dom-info -verify-loop-info %llvm.dbg.anchor.type = type { i32, i32 } %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* } %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } diff --git a/llvm/test/Transforms/LCSSA/2006-10-31-UnreachableBlock-2.ll b/llvm/test/Transforms/LCSSA/2006-10-31-UnreachableBlock-2.ll index 6f583f47ce89..3ba8d18b00cf 100644 --- a/llvm/test/Transforms/LCSSA/2006-10-31-UnreachableBlock-2.ll +++ b/llvm/test/Transforms/LCSSA/2006-10-31-UnreachableBlock-2.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -lcssa -disable-output -verify-dom-info +; RUN: opt < %s -lcssa -disable-output -verify-dom-info -verify-loop-info ; PR977 ; END. declare i32 @opost_block() diff --git a/llvm/test/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll b/llvm/test/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll index f4ecbea3ab07..4fe6e2156f97 100644 --- a/llvm/test/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll +++ b/llvm/test/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -scalarrepl -loopsimplify -licm -disable-output -verify-dom-info +; RUN: opt < %s -scalarrepl -loopsimplify -licm -disable-output -verify-dom-info -verify-loop-info define void @inflate() { entry: diff --git a/llvm/test/Transforms/LoopUnswitch/preserve-analyses.ll b/llvm/test/Transforms/LoopUnswitch/preserve-analyses.ll index 8d3f1382f3cc..3364fb274109 100644 --- a/llvm/test/Transforms/LoopUnswitch/preserve-analyses.ll +++ b/llvm/test/Transforms/LoopUnswitch/preserve-analyses.ll @@ -1,4 +1,4 @@ -; RUN: opt -loop-unswitch %s -disable-output +; RUN: opt -loop-unswitch -verify-loop-info -verify-dom-info %s -disable-output ; Loop unswitch should be able to unswitch these loops and ; preserve LCSSA and LoopSimplify forms.