mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[PM] Push the debug option for the new pass manager into the opt tool
and expose the necessary hooks in the API directly. This makes it much cleaner for example to log the usage of a pass manager from a library. It also makes it more obvious that this functionality isn't "optional" or "asserts-only" for the pass manager. llvm-svn: 225841
This commit is contained in:
parent
847eb51105
commit
d227b42252
@ -56,13 +56,6 @@ namespace llvm {
|
||||
class Module;
|
||||
class Function;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Declare our debug option here so we can refer to it from templates.
|
||||
extern cl::opt<bool> DebugPM;
|
||||
|
||||
} // End detail namespace
|
||||
|
||||
/// \brief An abstract set of preserved analyses following a transformation pass
|
||||
/// run.
|
||||
///
|
||||
@ -185,12 +178,18 @@ template <typename IRUnitT> class AnalysisManager;
|
||||
/// runs.
|
||||
template <typename IRUnitT> class PassManager {
|
||||
public:
|
||||
/// \brief Construct a pass manager.
|
||||
///
|
||||
/// It can be passed a flag to get debug logging as the passes are run.
|
||||
PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
|
||||
// We have to explicitly define all the special member functions because MSVC
|
||||
// refuses to generate them.
|
||||
PassManager() {}
|
||||
PassManager(PassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
|
||||
PassManager(PassManager &&Arg)
|
||||
: Passes(std::move(Arg.Passes)),
|
||||
DebugLogging(std::move(Arg.DebugLogging)) {}
|
||||
PassManager &operator=(PassManager &&RHS) {
|
||||
Passes = std::move(RHS.Passes);
|
||||
DebugLogging = std::move(RHS.DebugLogging);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -198,11 +197,11 @@ public:
|
||||
PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
|
||||
PreservedAnalyses PA = PreservedAnalyses::all();
|
||||
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Starting pass manager run.\n";
|
||||
|
||||
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Running pass: " << Passes[Idx]->name() << "\n";
|
||||
|
||||
PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
|
||||
@ -226,7 +225,7 @@ public:
|
||||
//IR.getContext().yield();
|
||||
}
|
||||
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Finished pass manager run.\n";
|
||||
|
||||
return PA;
|
||||
@ -246,6 +245,9 @@ private:
|
||||
PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
std::vector<std::unique_ptr<PassConceptT>> Passes;
|
||||
|
||||
/// \brief Flag indicating whether we should do debug logging.
|
||||
bool DebugLogging;
|
||||
};
|
||||
|
||||
/// \brief Convenience typedef for a pass manager over modules.
|
||||
@ -412,15 +414,22 @@ class AnalysisManager
|
||||
public:
|
||||
// Most public APIs are inherited from the CRTP base class.
|
||||
|
||||
/// \brief Construct an empty analysis manager.
|
||||
///
|
||||
/// A flag can be passed to indicate that the manager should perform debug
|
||||
/// logging.
|
||||
AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
|
||||
|
||||
// We have to explicitly define all the special member functions because MSVC
|
||||
// refuses to generate them.
|
||||
AnalysisManager() {}
|
||||
AnalysisManager(AnalysisManager &&Arg)
|
||||
: BaseT(std::move(static_cast<BaseT &>(Arg))),
|
||||
AnalysisResults(std::move(Arg.AnalysisResults)) {}
|
||||
AnalysisResults(std::move(Arg.AnalysisResults)),
|
||||
DebugLogging(std::move(Arg.DebugLogging)) {}
|
||||
AnalysisManager &operator=(AnalysisManager &&RHS) {
|
||||
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
|
||||
AnalysisResults = std::move(RHS.AnalysisResults);
|
||||
DebugLogging = std::move(RHS.DebugLogging);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -458,7 +467,7 @@ private:
|
||||
// run it to produce a result, which we then add to the cache.
|
||||
if (Inserted) {
|
||||
auto &P = this->lookupPass(PassID);
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Running analysis: " << P.name() << "\n";
|
||||
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
|
||||
ResultList.emplace_back(PassID, P.run(IR, this));
|
||||
@ -482,7 +491,7 @@ private:
|
||||
if (RI == AnalysisResults.end())
|
||||
return;
|
||||
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
|
||||
<< "\n";
|
||||
AnalysisResultLists[&IR].erase(RI->second);
|
||||
@ -495,7 +504,7 @@ private:
|
||||
if (PA.areAllPreserved())
|
||||
return std::move(PA);
|
||||
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Invalidating all non-preserved analyses for: "
|
||||
<< IR.getName() << "\n";
|
||||
|
||||
@ -512,7 +521,7 @@ private:
|
||||
// necessary. The analysis pass can return false if no action on the part
|
||||
// of the analysis manager is required for this invalidation event.
|
||||
if (I->second->invalidate(IR, PA)) {
|
||||
if (detail::DebugPM)
|
||||
if (DebugLogging)
|
||||
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
|
||||
<< "\n";
|
||||
|
||||
@ -562,6 +571,9 @@ private:
|
||||
/// \brief Map from an analysis ID and function to a particular cached
|
||||
/// analysis result.
|
||||
AnalysisResultMapT AnalysisResults;
|
||||
|
||||
/// \brief A flag indicating whether debug logging is enabled.
|
||||
bool DebugLogging;
|
||||
};
|
||||
|
||||
/// \brief Convenience typedef for the Module analysis manager.
|
||||
|
@ -12,11 +12,6 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
using namespace llvm;
|
||||
using llvm::detail::DebugPM;
|
||||
|
||||
cl::opt<bool> llvm::detail::DebugPM(
|
||||
"debug-pass-manager", cl::Hidden,
|
||||
cl::desc("Print pass management debugging information"));
|
||||
|
||||
char FunctionAnalysisManagerModuleProxy::PassID;
|
||||
|
||||
|
@ -30,12 +30,16 @@
|
||||
using namespace llvm;
|
||||
using namespace opt_tool;
|
||||
|
||||
static cl::opt<bool>
|
||||
DebugPM("debug-pass-manager", cl::Hidden,
|
||||
cl::desc("Print pass management debugging information"));
|
||||
|
||||
bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
|
||||
tool_output_file *Out, StringRef PassPipeline,
|
||||
OutputKind OK, VerifierKind VK) {
|
||||
FunctionAnalysisManager FAM;
|
||||
CGSCCAnalysisManager CGAM;
|
||||
ModuleAnalysisManager MAM;
|
||||
FunctionAnalysisManager FAM(DebugPM);
|
||||
CGSCCAnalysisManager CGAM(DebugPM);
|
||||
ModuleAnalysisManager MAM(DebugPM);
|
||||
|
||||
// Register all the basic analyses with the managers.
|
||||
registerModuleAnalyses(MAM);
|
||||
@ -50,11 +54,11 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
|
||||
FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM));
|
||||
FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
|
||||
|
||||
ModulePassManager MPM;
|
||||
ModulePassManager MPM(DebugPM);
|
||||
if (VK > VK_NoVerifier)
|
||||
MPM.addPass(VerifierPass());
|
||||
|
||||
if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
|
||||
if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass, DebugPM)) {
|
||||
errs() << Arg0 << ": unable to parse pass pipeline description.\n";
|
||||
return false;
|
||||
}
|
||||
|
@ -196,15 +196,16 @@ static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
|
||||
|
||||
static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
|
||||
StringRef &PipelineText,
|
||||
bool VerifyEachPass) {
|
||||
bool VerifyEachPass, bool DebugLogging) {
|
||||
for (;;) {
|
||||
// Parse nested pass managers by recursing.
|
||||
if (PipelineText.startswith("function(")) {
|
||||
FunctionPassManager NestedFPM;
|
||||
FunctionPassManager NestedFPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline inte the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("function("));
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -232,16 +233,17 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
|
||||
}
|
||||
|
||||
static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
|
||||
StringRef &PipelineText,
|
||||
bool VerifyEachPass) {
|
||||
StringRef &PipelineText, bool VerifyEachPass,
|
||||
bool DebugLogging) {
|
||||
for (;;) {
|
||||
// Parse nested pass managers by recursing.
|
||||
if (PipelineText.startswith("cgscc(")) {
|
||||
CGSCCPassManager NestedCGPM;
|
||||
CGSCCPassManager NestedCGPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline into the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("cgscc("));
|
||||
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -250,11 +252,12 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
|
||||
// Add the nested pass manager with the appropriate adaptor.
|
||||
CGPM.addPass(std::move(NestedCGPM));
|
||||
} else if (PipelineText.startswith("function(")) {
|
||||
FunctionPassManager NestedFPM;
|
||||
FunctionPassManager NestedFPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline inte the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("function("));
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -282,15 +285,16 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
|
||||
|
||||
static bool parseModulePassPipeline(ModulePassManager &MPM,
|
||||
StringRef &PipelineText,
|
||||
bool VerifyEachPass) {
|
||||
bool VerifyEachPass, bool DebugLogging) {
|
||||
for (;;) {
|
||||
// Parse nested pass managers by recursing.
|
||||
if (PipelineText.startswith("module(")) {
|
||||
ModulePassManager NestedMPM;
|
||||
ModulePassManager NestedMPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline into the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("module("));
|
||||
if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -299,11 +303,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
|
||||
// Now add the nested manager as a module pass.
|
||||
MPM.addPass(std::move(NestedMPM));
|
||||
} else if (PipelineText.startswith("cgscc(")) {
|
||||
CGSCCPassManager NestedCGPM;
|
||||
CGSCCPassManager NestedCGPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline inte the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("cgscc("));
|
||||
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -313,11 +318,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
|
||||
MPM.addPass(
|
||||
createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
|
||||
} else if (PipelineText.startswith("function(")) {
|
||||
FunctionPassManager NestedFPM;
|
||||
FunctionPassManager NestedFPM(DebugLogging);
|
||||
|
||||
// Parse the inner pipeline inte the nested manager.
|
||||
PipelineText = PipelineText.substr(strlen("function("));
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
|
||||
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
PipelineText.empty())
|
||||
return false;
|
||||
assert(PipelineText[0] == ')');
|
||||
@ -348,11 +354,11 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
|
||||
// FIXME: Should this routine accept a TargetMachine or require the caller to
|
||||
// pre-populate the analysis managers with target-specific stuff?
|
||||
bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
|
||||
bool VerifyEachPass) {
|
||||
bool VerifyEachPass, bool DebugLogging) {
|
||||
// By default, try to parse the pipeline as-if it were within an implicit
|
||||
// 'module(...)' pass pipeline. If this will parse at all, it needs to
|
||||
// consume the entire string.
|
||||
if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass))
|
||||
if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
|
||||
return PipelineText.empty();
|
||||
|
||||
// This isn't parsable as a module pipeline, look for the end of a pass name
|
||||
@ -365,8 +371,9 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
|
||||
// If this looks like a CGSCC pass, parse the whole thing as a CGSCC
|
||||
// pipeline.
|
||||
if (isCGSCCPassName(FirstName)) {
|
||||
CGSCCPassManager CGPM;
|
||||
if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
|
||||
CGSCCPassManager CGPM(DebugLogging);
|
||||
if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
!PipelineText.empty())
|
||||
return false;
|
||||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
|
||||
@ -376,8 +383,9 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
|
||||
// Similarly, if this looks like a Function pass, parse the whole thing as
|
||||
// a Function pipelien.
|
||||
if (isFunctionPassName(FirstName)) {
|
||||
FunctionPassManager FPM;
|
||||
if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
|
||||
FunctionPassManager FPM(DebugLogging);
|
||||
if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
|
||||
DebugLogging) ||
|
||||
!PipelineText.empty())
|
||||
return false;
|
||||
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
||||
|
@ -72,8 +72,7 @@ void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
|
||||
/// an error. You cannot mix different levels implicitly, you must explicitly
|
||||
/// form a pass manager in which to nest passes.
|
||||
bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
|
||||
bool VerifyEachPass = true);
|
||||
|
||||
bool VerifyEachPass = true, bool DebugLogging = false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user