1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Move the dominator verification code out of special code embedded within

the PassManager code into a regular verifyAnalysis method.

Also, reorganize loop verification. Make the LoopPass infrastructure
call verifyLoop as needed instead of having LoopInfo::verifyAnalysis
check every loop in the function after each looop pass. Add a new
command-line argument, -verify-loop-info, to enable the expensive
full checking.

llvm-svn: 82952
This commit is contained in:
Dan Gohman 2009-09-28 00:27:48 +00:00
parent 195c5bdf41
commit bd50ec69e4
10 changed files with 80 additions and 65 deletions

View File

@ -734,6 +734,8 @@ public:
virtual bool runOnFunction(Function &F); virtual bool runOnFunction(Function &F);
virtual void verifyAnalysis() const;
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll(); AU.setPreservesAll();
} }
@ -991,6 +993,8 @@ public:
return false; return false;
} }
virtual void verifyAnalysis() const;
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll(); AU.setPreservesAll();
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();

View File

@ -280,9 +280,6 @@ public:
/// verifyPreservedAnalysis -- Verify analysis presreved by pass P. /// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
void verifyPreservedAnalysis(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 /// Remove Analysis that is not preserved by the pass
void removeNotPreservedAnalysis(Pass *P); void removeNotPreservedAnalysis(Pass *P);

View File

@ -20,11 +20,22 @@
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include <algorithm> #include <algorithm>
using namespace llvm; using namespace llvm;
// Always verify loopinfo if expensive checking is enabled.
#ifdef XDEBUG
bool VerifyLoopInfo = true;
#else
bool VerifyLoopInfo = false;
#endif
static cl::opt<bool,true>
VerifyLoopInfoX("verify-loop-info", cl::location(VerifyLoopInfo),
cl::desc("Verify loop info (time consuming)"));
char LoopInfo::ID = 0; char LoopInfo::ID = 0;
static RegisterPass<LoopInfo> static RegisterPass<LoopInfo>
X("loops", "Natural Loop Information", true, true); X("loops", "Natural Loop Information", true, true);
@ -375,10 +386,20 @@ bool LoopInfo::runOnFunction(Function &) {
} }
void LoopInfo::verifyAnalysis() const { 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) { for (iterator I = begin(), E = end(); I != E; ++I) {
assert(!(*I)->getParentLoop() && "Top-level loop has a parent!"); assert(!(*I)->getParentLoop() && "Top-level loop has a parent!");
(*I)->verifyLoopNest(); (*I)->verifyLoopNest();
} }
// TODO: check BBMap consistency.
} }
void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const { void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {

View File

@ -242,16 +242,24 @@ bool LPPassManager::runOnFunction(Function &F) {
dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, ""); dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, "");
dumpPreservedSet(P); 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); verifyPreservedAnalysis(LP);
}
removeNotPreservedAnalysis(P); removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P); recordAvailableAnalysis(P);
removeDeadPasses(P, "", ON_LOOP_MSG); removeDeadPasses(P, "", ON_LOOP_MSG);
// If dominator information is available then verify the info if requested.
verifyDomInfo(*LP, F);
if (skipThisLoop) if (skipThisLoop)
// Do not run other passes on this loop. // Do not run other passes on this loop.
break; break;

View File

@ -24,9 +24,20 @@
#include "llvm/Analysis/DominatorInternals.h" #include "llvm/Analysis/DominatorInternals.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"
#include <algorithm> #include <algorithm>
using namespace llvm; using namespace llvm;
// Always verify dominfo if expensive checking is enabled.
#ifdef XDEBUG
bool VerifyDomInfo = true;
#else
bool VerifyDomInfo = false;
#endif
static cl::opt<bool,true>
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
cl::desc("Verify dominator info (time consuming)"));
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// DominatorTree Implementation // DominatorTree Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -48,6 +59,16 @@ bool DominatorTree::runOnFunction(Function &F) {
return false; 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 { void DominatorTree::print(raw_ostream &OS, const Module *) const {
DT->print(OS); DT->print(OS);
} }
@ -87,6 +108,17 @@ char DominanceFrontier::ID = 0;
static RegisterPass<DominanceFrontier> static RegisterPass<DominanceFrontier>
G("domfrontier", "Dominance Frontier Construction", true, true); G("domfrontier", "Dominance Frontier Construction", true, true);
void DominanceFrontier::verifyAnalysis() const {
if (!VerifyDomInfo) return;
DominatorTree &DT = getAnalysis<DominatorTree>();
DominanceFrontier OtherDF;
const std::vector<BasicBlock*> &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 // NewBB is split and now it has one successor. Update dominace frontier to
// reflect this change. // reflect this change.
void DominanceFrontier::splitBlock(BasicBlock *NewBB) { void DominanceFrontier::splitBlock(BasicBlock *NewBB) {

View File

@ -13,6 +13,7 @@
#include "llvm/PassManagers.h" #include "llvm/PassManagers.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Timer.h" #include "llvm/Support/Timer.h"
#include "llvm/Module.h" #include "llvm/Module.h"
@ -22,7 +23,6 @@
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/System/Mutex.h" #include "llvm/System/Mutex.h"
#include "llvm/System/Threading.h" #include "llvm/System/Threading.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm-c/Core.h" #include "llvm-c/Core.h"
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
@ -45,16 +45,6 @@ enum PassDebugLevel {
None, Arguments, Structure, Executions, Details 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<bool,true>
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
cl::desc("Verify dominator info (time consuming)"));
static cl::opt<enum PassDebugLevel> static cl::opt<enum PassDebugLevel>
PassDebugging("debug-pass", cl::Hidden, PassDebugging("debug-pass", cl::Hidden,
cl::desc("Print PassManager debugging information"), cl::desc("Print PassManager debugging information"),
@ -703,47 +693,13 @@ void PMDataManager::verifyPreservedAnalysis(Pass *P) {
for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(),
E = PreservedSet.end(); I != E; ++I) { E = PreservedSet.end(); I != E; ++I) {
AnalysisID AID = *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(); AP->verifyAnalysis();
} if (T) T->stopTimer();
} }
/// verifyDomInfo - Verify dominator information if it is available.
void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
if (!VerifyDomInfo || !P.getResolver())
return;
DominatorTree *DT = P.getAnalysisIfAvailable<DominatorTree>();
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<DominanceFrontier>();
if (!DF)
return;
DominanceFrontier OtherDF;
std::vector<BasicBlock*> 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");
} }
} }
@ -1384,9 +1340,6 @@ bool FPPassManager::runOnFunction(Function &F) {
removeNotPreservedAnalysis(FP); removeNotPreservedAnalysis(FP);
recordAvailableAnalysis(FP); recordAvailableAnalysis(FP);
removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
// If dominator information is available then verify the info if requested.
verifyDomInfo(*FP, F);
} }
return Changed; return Changed;
} }

View File

@ -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.anchor.type = type { i32, i32 }
%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* } %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* } %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* }

View File

@ -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 ; PR977
; END. ; END.
declare i32 @opost_block() declare i32 @opost_block()

View File

@ -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() { define void @inflate() {
entry: entry:

View File

@ -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 ; Loop unswitch should be able to unswitch these loops and
; preserve LCSSA and LoopSimplify forms. ; preserve LCSSA and LoopSimplify forms.