forked from OSchip/llvm-project
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:
parent
2963777d0c
commit
4dbb301f17
|
@ -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<DominatorTree>();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 <algorithm>
|
||||
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;
|
||||
static RegisterPass<LoopInfo>
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <algorithm>
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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<DominanceFrontier>
|
||||
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
|
||||
// reflect this change.
|
||||
void DominanceFrontier::splitBlock(BasicBlock *NewBB) {
|
||||
|
|
|
@ -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 <algorithm>
|
||||
#include <cstdio>
|
||||
|
@ -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<bool,true>
|
||||
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
|
||||
cl::desc("Verify dominator info (time consuming)"));
|
||||
|
||||
static cl::opt<enum PassDebugLevel>
|
||||
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<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");
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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* }
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue