diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 0b2a0c4ab7b..26257684926 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -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 DebugPM; - -} // End detail namespace - /// \brief An abstract set of preserved analyses following a transformation pass /// run. /// @@ -185,12 +178,18 @@ template class AnalysisManager; /// runs. template 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 *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> 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(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(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. diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index 3e6efb70260..a5f407c00e8 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -12,11 +12,6 @@ #include "llvm/IR/PassManager.h" using namespace llvm; -using llvm::detail::DebugPM; - -cl::opt llvm::detail::DebugPM( - "debug-pass-manager", cl::Hidden, - cl::desc("Print pass management debugging information")); char FunctionAnalysisManagerModuleProxy::PassID; diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp index 9e24f30c188..d37211faf6d 100644 --- a/tools/opt/NewPMDriver.cpp +++ b/tools/opt/NewPMDriver.cpp @@ -30,12 +30,16 @@ using namespace llvm; using namespace opt_tool; +static cl::opt + 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; } diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 69301256f89..c81c5633684 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -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))); diff --git a/tools/opt/Passes.h b/tools/opt/Passes.h index f8273be1e9d..9e58e8b8ac3 100644 --- a/tools/opt/Passes.h +++ b/tools/opt/Passes.h @@ -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