[PM] Add names to passes under the new pass manager, and a debug output

mode that can be used to debug the execution of everything.

No support for analyses here, that will come later. This already helps
show parts of the opt commandline integration that isn't working. Tests
of that will start using it as the bugs are fixed.

llvm-svn: 199004
This commit is contained in:
Chandler Carruth 2014-01-11 11:52:05 +00:00
parent d7693d8444
commit a13f27cc34
4 changed files with 51 additions and 1 deletions

View File

@ -168,6 +168,9 @@ template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
/// desired. Also that the analysis manager may be null if there is no /// desired. Also that the analysis manager may be null if there is no
/// analysis manager in the pass pipeline. /// analysis manager in the pass pipeline.
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0; virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
/// \brief Polymorphic method to access the name of a pass.
virtual StringRef name() = 0;
}; };
/// \brief SFINAE metafunction for computing whether \c PassT has a run method /// \brief SFINAE metafunction for computing whether \c PassT has a run method
@ -208,6 +211,7 @@ struct PassModel<IRUnitT, AnalysisManagerT, PassT,
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) { virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) {
return Pass.run(IR, AM); return Pass.run(IR, AM);
} }
virtual StringRef name() { return PassT::name(); }
PassT Pass; PassT Pass;
}; };
@ -221,6 +225,7 @@ struct PassModel<IRUnitT, AnalysisManagerT, PassT,
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) { virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) {
return Pass.run(IR); return Pass.run(IR);
} }
virtual StringRef name() { return PassT::name(); }
PassT Pass; PassT Pass;
}; };
@ -403,6 +408,8 @@ public:
Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass))); Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass)));
} }
static StringRef name() { return "ModulePassManager"; }
private: private:
// Pull in the concept type and model template specialized for modules. // Pull in the concept type and model template specialized for modules.
typedef detail::PassConcept<Module *, ModuleAnalysisManager> ModulePassConcept; typedef detail::PassConcept<Module *, ModuleAnalysisManager> ModulePassConcept;
@ -428,6 +435,8 @@ public:
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0); PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0);
static StringRef name() { return "FunctionPassManager"; }
private: private:
// Pull in the concept type and model template specialized for functions. // Pull in the concept type and model template specialized for functions.
typedef detail::PassConcept<Function *, FunctionAnalysisManager> typedef detail::PassConcept<Function *, FunctionAnalysisManager>
@ -808,6 +817,8 @@ public:
return PA; return PA;
} }
static StringRef name() { return "ModuleToFunctionPassAdaptor"; }
private: private:
FunctionPassT Pass; FunctionPassT Pass;
}; };

View File

@ -7,19 +7,36 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/IR/PassManager.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
using namespace llvm; using namespace llvm;
static cl::opt<bool>
DebugPM("debug-pass-manager", cl::Hidden,
cl::desc("Print pass management debugging information"));
PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
PreservedAnalyses PA = PreservedAnalyses::all(); PreservedAnalyses PA = PreservedAnalyses::all();
if (DebugPM)
dbgs() << "Starting module pass manager run.\n";
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
if (DebugPM)
dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n";
PreservedAnalyses PassPA = Passes[Idx]->run(M, AM); PreservedAnalyses PassPA = Passes[Idx]->run(M, AM);
if (AM) if (AM)
AM->invalidate(M, PassPA); AM->invalidate(M, PassPA);
PA.intersect(llvm_move(PassPA)); PA.intersect(llvm_move(PassPA));
} }
if (DebugPM)
dbgs() << "Finished module pass manager run.\n";
return PA; return PA;
} }
@ -61,12 +78,23 @@ void ModuleAnalysisManager::invalidateImpl(Module *M,
PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager *AM) { PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager *AM) {
PreservedAnalyses PA = PreservedAnalyses::all(); PreservedAnalyses PA = PreservedAnalyses::all();
if (DebugPM)
dbgs() << "Starting function pass manager run.\n";
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
if (DebugPM)
dbgs() << "Running function pass: " << Passes[Idx]->name() << "\n";
PreservedAnalyses PassPA = Passes[Idx]->run(F, AM); PreservedAnalyses PassPA = Passes[Idx]->run(F, AM);
if (AM) if (AM)
AM->invalidate(F, PassPA); AM->invalidate(F, PassPA);
PA.intersect(llvm_move(PassPA)); PA.intersect(llvm_move(PassPA));
} }
if (DebugPM)
dbgs() << "Finished function pass manager run.\n";
return PA; return PA;
} }

View File

@ -24,6 +24,7 @@ namespace {
/// \brief No-op module pass which does nothing. /// \brief No-op module pass which does nothing.
struct NoOpModulePass { struct NoOpModulePass {
PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); } PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
static StringRef name() { return "NoOpModulePass"; }
}; };
} // End anonymous namespace. } // End anonymous namespace.

View File

@ -86,6 +86,8 @@ struct TestModulePass {
return PreservedAnalyses::none(); return PreservedAnalyses::none();
} }
static StringRef name() { return "TestModulePass"; }
int &RunCount; int &RunCount;
}; };
@ -93,6 +95,8 @@ struct TestPreservingModulePass {
PreservedAnalyses run(Module *M) { PreservedAnalyses run(Module *M) {
return PreservedAnalyses::all(); return PreservedAnalyses::all();
} }
static StringRef name() { return "TestPreservingModulePass"; }
}; };
struct TestMinPreservingModulePass { struct TestMinPreservingModulePass {
@ -105,6 +109,8 @@ struct TestMinPreservingModulePass {
PA.preserve<FunctionAnalysisManagerModuleProxy>(); PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA; return PA;
} }
static StringRef name() { return "TestMinPreservingModulePass"; }
}; };
struct TestFunctionPass { struct TestFunctionPass {
@ -138,6 +144,8 @@ struct TestFunctionPass {
return PreservedAnalyses::all(); return PreservedAnalyses::all();
} }
static StringRef name() { return "TestFunctionPass"; }
int &RunCount; int &RunCount;
int &AnalyzedInstrCount; int &AnalyzedInstrCount;
int &AnalyzedFunctionCount; int &AnalyzedFunctionCount;
@ -154,6 +162,8 @@ struct TestInvalidationFunctionPass {
: PreservedAnalyses::all(); : PreservedAnalyses::all();
} }
static StringRef name() { return "TestInvalidationFunctionPass"; }
StringRef Name; StringRef Name;
}; };