diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2017-01-13 06:09:54 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2017-01-13 06:09:54 +0000 |
commit | d409411ef195329a24cea00589e9853ab6a5ace8 (patch) | |
tree | 31459227034048c2e1e5274200e73d075317eb6e /llvm/lib | |
parent | d30e6f7421f4b319f1203d660bbc89f09d8944f7 (diff) | |
download | bcm5719-llvm-d409411ef195329a24cea00589e9853ab6a5ace8.tar.gz bcm5719-llvm-d409411ef195329a24cea00589e9853ab6a5ace8.zip |
Track validity of pass results
Running tests with expensive checks enabled exhibits some problems with
verification of pass results.
First, the pass verification may require results of analysis that are not
available. For instance, verification of loop info requires results of dominator
tree analysis. A pass may be marked as conserving loop info but does not need to
be dependent on DominatorTreePass. When a pass manager tries to verify that loop
info is valid, it needs dominator tree, but corresponding analysis may be
already destroyed as no user of it remained.
Another case is a pass that is skipped. For instance, entities with linkage
available_externally do not need code generation and such passes are skipped for
them. In this case result verification must also be skipped.
To solve these problems this change introduces a special flag to the Pass
structure to mark passes that have valid results. If this flag is reset,
verifications dependent on the pass result are skipped.
Differential Revision: https://reviews.llvm.org/D27190
llvm-svn: 291882
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/CallGraphSCCPass.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopPass.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineDominators.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineFunctionPass.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/LegacyPassManager.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/IR/Pass.cpp | 7 |
7 files changed, 30 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp index 9cef7814415..290fd34cff5 100644 --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -414,6 +414,7 @@ bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG, initializeAnalysisImpl(P); // Actually run this pass on the current SCC. + P->setExecuted(true); Changed |= RunPassOnSCC(P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall); diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index f449ce94d57..1b5d6e5d1b7 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -722,8 +722,10 @@ void LoopInfoWrapperPass::verifyAnalysis() const { // checking by default, LoopPass has been taught to call verifyLoop manually // during loop pass sequences. if (VerifyLoopInfo) { - auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - LI.verify(DT); + if (auto *Analysis = getAnalysisIfAvailable<DominatorTreeWrapperPass>()) { + auto &DT = Analysis->getDomTree(); + LI.verify(DT); + } } } diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index 3f4a0794215..d3e697e5c61 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -198,6 +198,7 @@ bool LPPassManager::runOnFunction(Function &F) { PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader()); TimeRegion PassTimer(getPassTimer(P)); + P->setExecuted(true); Changed |= P->runOnLoop(CurrentLoop, *this); } LoopWasDeleted = CurrentLoop->isInvalid(); diff --git a/llvm/lib/CodeGen/MachineDominators.cpp b/llvm/lib/CodeGen/MachineDominators.cpp index 303a6a9263b..a548480044e 100644 --- a/llvm/lib/CodeGen/MachineDominators.cpp +++ b/llvm/lib/CodeGen/MachineDominators.cpp @@ -69,7 +69,7 @@ void MachineDominatorTree::releaseMemory() { } void MachineDominatorTree::verifyAnalysis() const { - if (VerifyMachineDomInfo) + if (VerifyMachineDomInfo && isExecuted()) verifyDomTree(); } diff --git a/llvm/lib/CodeGen/MachineFunctionPass.cpp b/llvm/lib/CodeGen/MachineFunctionPass.cpp index 2265676ff8b..a7ece36a1e5 100644 --- a/llvm/lib/CodeGen/MachineFunctionPass.cpp +++ b/llvm/lib/CodeGen/MachineFunctionPass.cpp @@ -38,8 +38,10 @@ Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O, bool MachineFunctionPass::runOnFunction(Function &F) { // Do not codegen any 'available_externally' functions at all, they have // definitions outside the translation unit. - if (F.hasAvailableExternallyLinkage()) + if (F.hasAvailableExternallyLinkage()) { + setExecuted(false); return false; + } MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); MachineFunction &MF = MMI.getMachineFunction(F); diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index 628a67bd639..0b2c40b742a 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -955,6 +955,9 @@ void PMDataManager::freePass(Pass *P, StringRef Msg, AvailableAnalysis.erase(Pos); } } + + if (!P->getAsImmutablePass()) + P->setExecuted(false); } /// Add pass P into the PassVector. Update @@ -1293,6 +1296,7 @@ bool BBPassManager::runOnFunction(Function &F) { PassManagerPrettyStackEntry X(BP, *I); TimeRegion PassTimer(getPassTimer(BP)); + BP->setExecuted(true); LocalChanged |= BP->runOnBasicBlock(*I); } @@ -1459,7 +1463,9 @@ bool FunctionPassManagerImpl::run(Function &F) { initializeAllAnalysisInfo(); for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { - Changed |= getContainedManager(Index)->runOnFunction(F); + FPPassManager *P = getContainedManager(Index); + P->setExecuted(true); + Changed |= P->runOnFunction(F); F.getContext().yield(); } @@ -1510,6 +1516,7 @@ bool FPPassManager::runOnFunction(Function &F) { PassManagerPrettyStackEntry X(FP, F); TimeRegion PassTimer(getPassTimer(FP)); + FP->setExecuted(true); LocalChanged |= FP->runOnFunction(F); } @@ -1530,8 +1537,10 @@ bool FPPassManager::runOnFunction(Function &F) { bool FPPassManager::runOnModule(Module &M) { bool Changed = false; - for (Function &F : M) + for (Function &F : M) { + setExecuted(true); Changed |= runOnFunction(F); + } return Changed; } @@ -1587,6 +1596,7 @@ MPPassManager::runOnModule(Module &M) { PassManagerPrettyStackEntry X(MP, M); TimeRegion PassTimer(getPassTimer(MP)); + MP->setExecuted(true); LocalChanged |= MP->runOnModule(M); } @@ -1690,7 +1700,9 @@ bool PassManagerImpl::run(Module &M) { initializeAllAnalysisInfo(); for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { - Changed |= getContainedManager(Index)->runOnModule(M); + MPPassManager *P = getContainedManager(Index); + P->setExecuted(true); + Changed |= P->runOnModule(M); M.getContext().yield(); } diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp index a42945ef3ff..6e22c1d4641 100644 --- a/llvm/lib/IR/Pass.cpp +++ b/llvm/lib/IR/Pass.cpp @@ -146,13 +146,16 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const { return PMT_FunctionPassManager; } -bool FunctionPass::skipFunction(const Function &F) const { - if (!F.getContext().getOptBisect().shouldRunPass(this, F)) +bool FunctionPass::skipFunction(const Function &F) { + if (!F.getContext().getOptBisect().shouldRunPass(this, F)) { + setExecuted(false); return true; + } if (F.hasFnAttribute(Attribute::OptimizeNone)) { DEBUG(dbgs() << "Skipping pass '" << getPassName() << "' on function " << F.getName() << "\n"); + setExecuted(false); return true; } return false; |