Author: Arthur Eubanks Date: 2020-12-03T16:52:14-08:00 New Revision: 2f0de582949d1c9b5beff591b3735b6c02c45033
URL: https://github.com/llvm/llvm-project/commit/2f0de582949d1c9b5beff591b3735b6c02c45033 DIFF: https://github.com/llvm/llvm-project/commit/2f0de582949d1c9b5beff591b3735b6c02c45033.diff LOG: [NewPM] Support --print-before/after in NPM This changes --print-before/after to be a list of strings rather than legacy passes. (this also has the effect of not showing the entire list of passes in --help-hidden after --print-before/after, which IMO is great for making it less verbose). Currently PrintIRInstrumentation passes the class name rather than pass name to llvm::shouldPrintBeforePass(), meaning llvm::shouldPrintBeforePass() never functions as intended in the NPM. There is no easy way of converting class names to pass names outside of within an instance of PassBuilder. This adds a map of pass class names to their short names in PassRegistry.def within PassInstrumentationCallbacks. It is populated inside the constructor of PassBuilder, which takes a PassInstrumentationCallbacks. Add a pointer to PassInstrumentationCallbacks inside PrintIRInstrumentation and use the newly created map. This is a bit hacky, but I can't think of a better way since the short id to class name only exists within PassRegistry.def. This also doesn't handle passes not in PassRegistry.def but rather added via PassBuilder::registerPipelineParsingCallback(). llvm/test/CodeGen/Generic/print-after.ll doesn't seem very useful now with this change. Reviewed By: ychen, jamieschmeiser Differential Revision: https://reviews.llvm.org/D87216 Added: llvm/include/llvm/IR/PrintPasses.h llvm/lib/IR/PrintPasses.cpp llvm/test/Other/print-before-after.ll Modified: llvm/include/llvm/IR/IRPrintingPasses.h llvm/include/llvm/IR/PassInstrumentation.h llvm/include/llvm/Passes/StandardInstrumentations.h llvm/lib/Analysis/CallGraphSCCPass.cpp llvm/lib/Analysis/LoopInfo.cpp llvm/lib/Analysis/LoopPass.cpp llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp llvm/lib/IR/CMakeLists.txt llvm/lib/IR/IRPrintingPasses.cpp llvm/lib/IR/LegacyPassManager.cpp llvm/lib/IR/PassInstrumentation.cpp llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/StandardInstrumentations.cpp llvm/test/Other/loop-pass-printer.ll llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn Removed: llvm/test/CodeGen/Generic/print-after.ll ################################################################################ diff --git a/llvm/include/llvm/IR/IRPrintingPasses.h b/llvm/include/llvm/IR/IRPrintingPasses.h index 1cfd27af59be..2e62be7cd1ec 100644 --- a/llvm/include/llvm/IR/IRPrintingPasses.h +++ b/llvm/include/llvm/IR/IRPrintingPasses.h @@ -45,22 +45,6 @@ void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name); /// Return true if a pass is for IR printing. bool isIRPrintingPass(Pass *P); -/// isFunctionInPrintList - returns true if a function should be printed via -// debugging options like -print-after-all/-print-before-all. -// Tells if the function IR should be printed by PrinterPass. -extern bool isFunctionInPrintList(StringRef FunctionName); - -/// forcePrintModuleIR - returns true if IR printing passes should -// be printing module IR (even for local-pass printers e.g. function-pass) -// to provide more context, as enabled by debugging option -print-module-scope -// Tells if IR printer should be printing module IR -extern bool forcePrintModuleIR(); - -extern bool shouldPrintBeforePass(); -extern bool shouldPrintBeforePass(StringRef); -extern bool shouldPrintAfterPass(); -extern bool shouldPrintAfterPass(StringRef); - /// Pass for printing a Module as LLVM's text IR assembly. /// /// Note: This pass is for use with the new pass manager. Use the create...Pass @@ -95,6 +79,6 @@ class PrintFunctionPass : public PassInfoMixin<PrintFunctionPass> { static bool isRequired() { return true; } }; -} // End llvm namespace +} // namespace llvm #endif diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h index 2cc3e74214e4..98b3fd451e4f 100644 --- a/llvm/include/llvm/IR/PassInstrumentation.h +++ b/llvm/include/llvm/IR/PassInstrumentation.h @@ -52,6 +52,7 @@ #include "llvm/ADT/Any.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include <type_traits> namespace llvm { @@ -122,6 +123,13 @@ class PassInstrumentationCallbacks { AfterAnalysisCallbacks.emplace_back(std::move(C)); } + /// Add a class name to pass name mapping for use by pass instrumentation. + void addClassToPassName(StringRef ClassName, StringRef PassName); + /// Get the pass name for a given pass class name. + StringRef getPassNameForClassName(StringRef ClassName); + /// Whether or not the class to pass name map contains the pass name. + bool hasPassName(StringRef PassName); + private: friend class PassInstrumentation; @@ -146,6 +154,8 @@ class PassInstrumentationCallbacks { /// These are run on analyses that have been run. SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4> AfterAnalysisCallbacks; + + StringMap<std::string> ClassToPassName; }; /// This class provides instrumentation entry points for the Pass Manager, diff --git a/llvm/include/llvm/IR/PrintPasses.h b/llvm/include/llvm/IR/PrintPasses.h new file mode 100644 index 000000000000..1fa7c1893e20 --- /dev/null +++ b/llvm/include/llvm/IR/PrintPasses.h @@ -0,0 +1,44 @@ +//===- PrintPasses.h - Determining whether/when to print IR ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_PRINTPASSES_H +#define LLVM_IR_PRINTPASSES_H + +#include "llvm/ADT/StringRef.h" +#include <vector> + +namespace llvm { + +// Returns true if printing before/after some pass is enabled, whether all +// passes or a specific pass. +bool shouldPrintBeforeSomePass(); +bool shouldPrintAfterSomePass(); + +// Returns true if we should print before/after a specific pass. The argument +// should be the pass ID, e.g. "instcombine". +bool shouldPrintBeforePass(StringRef PassID); +bool shouldPrintAfterPass(StringRef PassID); + +// Returns true if we should print before/after all passes. +bool shouldPrintBeforeAll(); +bool shouldPrintAfterAll(); + +// The list of passes to print before/after, if we only want to print +// before/after specific passes. +std::vector<std::string> printBeforePasses(); +std::vector<std::string> printAfterPasses(); + +// Returns true if we should always print the entire module. +bool forcePrintModuleIR(); + +// Returns true if we should print the function. +bool isFunctionInPrintList(StringRef FunctionName); + +} // namespace llvm + +#endif // LLVM_IR_PRINTPASSES_H diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h index d4acd9c9b1c4..c816c3fc2ab9 100644 --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -19,7 +19,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/OptBisect.h" -#include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/CommandLine.h" @@ -31,6 +30,7 @@ namespace llvm { class Module; class Function; +class PassInstrumentationCallbacks; /// Instrumentation to print IR before/after passes. /// @@ -47,11 +47,15 @@ class PrintIRInstrumentation { void printAfterPass(StringRef PassID, Any IR); void printAfterPassInvalidated(StringRef PassID); + bool shouldPrintBeforePass(StringRef PassID); + bool shouldPrintAfterPass(StringRef PassID); + using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>; void pushModuleDesc(StringRef PassID, Any IR); PrintModuleDesc popModuleDesc(StringRef PassID); + PassInstrumentationCallbacks *PIC; /// Stack of Module description, enough to print the module after a given /// pass. SmallVector<PrintModuleDesc, 2> ModuleDescStack; diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp index de5cada85fe2..38057d44e2b8 100644 --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -21,13 +21,13 @@ #include "llvm/Analysis/CallGraph.h" #include "llvm/IR/AbstractCallSite.h" #include "llvm/IR/Function.h" -#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManagers.h" #include "llvm/IR/Module.h" #include "llvm/IR/OptBisect.h" #include "llvm/IR/PassTimingInfo.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/IR/StructuralHash.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 1a6cb50e1e5d..e925e0d20647 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -34,6 +34,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/InitializePasses.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index f668a8ed6c35..13e744f02665 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -15,11 +15,11 @@ #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/IR/Dominators.h" -#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OptBisect.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/PassTimingInfo.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/IR/StructuralHash.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" diff --git a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp index 3645a4e3466b..c31c065b1976 100644 --- a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp +++ b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp @@ -14,7 +14,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SlotIndexes.h" -#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -44,7 +44,7 @@ struct MachineFunctionPrinterPass : public MachineFunctionPass { } bool runOnMachineFunction(MachineFunction &MF) override { - if (!llvm::isFunctionInPrintList(MF.getName())) + if (!isFunctionInPrintList(MF.getName())) return false; OS << "# " << Banner << ":\n"; MF.print(OS, getAnalysisIfAvailable<SlotIndexes>()); diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 0bba18e90bbc..91a018af7459 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -44,6 +44,7 @@ add_llvm_component_library(LLVMCore PassManager.cpp PassRegistry.cpp PassTimingInfo.cpp + PrintPasses.cpp SafepointIRVerifier.cpp ProfileSummary.cpp Statepoint.cpp diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp index 7c73d2ab9871..8d6fe1eb6134 100644 --- a/llvm/lib/IR/IRPrintingPasses.cpp +++ b/llvm/lib/IR/IRPrintingPasses.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index 544c56a789a3..f6050d063303 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/LegacyPassNameParser.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassTimingInfo.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/IR/StructuralHash.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/CommandLine.h" @@ -49,7 +50,7 @@ namespace { enum PassDebugLevel { Disabled, Arguments, Structure, Executions, Details }; -} +} // namespace static cl::opt<enum PassDebugLevel> PassDebugging("debug-pass", cl::Hidden, @@ -61,80 +62,6 @@ PassDebugging("debug-pass", cl::Hidden, clEnumVal(Executions, "print pass name before it is executed"), clEnumVal(Details , "print pass details when it is executed"))); -namespace { -typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> -PassOptionList; -} - -// Print IR out before/after specified passes. -static PassOptionList -PrintBefore("print-before", - llvm::cl::desc("Print IR before specified passes"), - cl::Hidden); - -static PassOptionList -PrintAfter("print-after", - llvm::cl::desc("Print IR after specified passes"), - cl::Hidden); - -static cl::opt<bool> PrintBeforeAll("print-before-all", - llvm::cl::desc("Print IR before each pass"), - cl::init(false), cl::Hidden); -static cl::opt<bool> PrintAfterAll("print-after-all", - llvm::cl::desc("Print IR after each pass"), - cl::init(false), cl::Hidden); - -static cl::opt<bool> - PrintModuleScope("print-module-scope", - cl::desc("When printing IR for print-[before|after]{-all} " - "and change reporters, always print a module IR"), - cl::init(false), cl::Hidden); - -static cl::list<std::string> - PrintFuncsList("filter-print-funcs", cl::value_desc("function names"), - cl::desc("Only print IR for functions whose name " - "match this for all print-[before|after][-all] " - "and change reporter options"), - cl::CommaSeparated, cl::Hidden); - -/// This is a helper to determine whether to print IR before or -/// after a pass. - -bool llvm::shouldPrintBeforePass() { - return PrintBeforeAll || !PrintBefore.empty(); -} - -bool llvm::shouldPrintAfterPass() { - return PrintAfterAll || !PrintAfter.empty(); -} - -static bool ShouldPrintBeforeOrAfterPass(StringRef PassID, - PassOptionList &PassesToPrint) { - for (auto *PassInf : PassesToPrint) { - if (PassInf) - if (PassInf->getPassArgument() == PassID) { - return true; - } - } - return false; -} - -bool llvm::shouldPrintBeforePass(StringRef PassID) { - return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore); -} - -bool llvm::shouldPrintAfterPass(StringRef PassID) { - return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter); -} - -bool llvm::forcePrintModuleIR() { return PrintModuleScope; } - -bool llvm::isFunctionInPrintList(StringRef FunctionName) { - static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(), - PrintFuncsList.end()); - return PrintFuncNames.empty() || - PrintFuncNames.count(std::string(FunctionName)); -} /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions /// or higher is specified. bool PMDataManager::isPassDebuggingExecutionsOrMore() const { diff --git a/llvm/lib/IR/PassInstrumentation.cpp b/llvm/lib/IR/PassInstrumentation.cpp index a0004a812147..6a2defcf6b0e 100644 --- a/llvm/lib/IR/PassInstrumentation.cpp +++ b/llvm/lib/IR/PassInstrumentation.cpp @@ -17,6 +17,24 @@ namespace llvm { +void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName, + StringRef PassName) { + ClassToPassName[ClassName] = PassName.str(); +} + +bool PassInstrumentationCallbacks::hasPassName(StringRef PassName) { + for (const auto &E : ClassToPassName) { + if (E.getValue() == PassName) + return true; + } + return false; +} + +StringRef +PassInstrumentationCallbacks::getPassNameForClassName(StringRef ClassName) { + return ClassToPassName[ClassName]; +} + AnalysisKey PassInstrumentationAnalysis::Key; bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) { diff --git a/llvm/lib/IR/PrintPasses.cpp b/llvm/lib/IR/PrintPasses.cpp new file mode 100644 index 000000000000..4cf2a1a7e7cc --- /dev/null +++ b/llvm/lib/IR/PrintPasses.cpp @@ -0,0 +1,92 @@ +//===- PrintPasses.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/PrintPasses.h" +#include "llvm/Support/CommandLine.h" +#include <unordered_set> + +using namespace llvm; + +// Print IR out before/after specified passes. +static cl::list<std::string> + PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes"), + cl::CommaSeparated, cl::Hidden); + +static cl::list<std::string> + PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"), + cl::CommaSeparated, cl::Hidden); + +static cl::opt<bool> PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false), cl::Hidden); +static cl::opt<bool> PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false), cl::Hidden); + +static cl::opt<bool> + PrintModuleScope("print-module-scope", + cl::desc("When printing IR for print-[before|after]{-all} " + "always print a module IR"), + cl::init(false), cl::Hidden); + +static cl::list<std::string> + PrintFuncsList("filter-print-funcs", cl::value_desc("function names"), + cl::desc("Only print IR for functions whose name " + "match this for all print-[before|after][-all] " + "options"), + cl::CommaSeparated, cl::Hidden); + +/// This is a helper to determine whether to print IR before or +/// after a pass. + +bool llvm::shouldPrintBeforeSomePass() { + return PrintBeforeAll || !PrintBefore.empty(); +} + +bool llvm::shouldPrintAfterSomePass() { + return PrintAfterAll || !PrintAfter.empty(); +} + +static bool shouldPrintBeforeOrAfterPass(StringRef PassID, + ArrayRef<std::string> PassesToPrint) { + for (auto &Pass : PassesToPrint) { + if (Pass == PassID) + return true; + } + return false; +} + +bool llvm::shouldPrintBeforeAll() { return PrintBeforeAll; } + +bool llvm::shouldPrintAfterAll() { return PrintAfterAll; } + +bool llvm::shouldPrintBeforePass(StringRef PassID) { + return PrintBeforeAll || shouldPrintBeforeOrAfterPass(PassID, PrintBefore); +} + +bool llvm::shouldPrintAfterPass(StringRef PassID) { + return PrintAfterAll || shouldPrintBeforeOrAfterPass(PassID, PrintAfter); +} + +std::vector<std::string> llvm::printBeforePasses() { + return std::vector<std::string>(PrintBefore); +} + +std::vector<std::string> llvm::printAfterPasses() { + return std::vector<std::string>(PrintAfter); +} + +bool llvm::forcePrintModuleIR() { return PrintModuleScope; } + +bool llvm::isFunctionInPrintList(StringRef FunctionName) { + static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(), + PrintFuncsList.end()); + return PrintFuncNames.empty() || + PrintFuncNames.count(std::string(FunctionName)); +} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index d9710bb5b67e..796f6abfb9e9 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -70,10 +70,12 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/IR/SafepointIRVerifier.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetMachine.h" @@ -415,6 +417,16 @@ AnalysisKey NoOpCGSCCAnalysis::Key; AnalysisKey NoOpFunctionAnalysis::Key; AnalysisKey NoOpLoopAnalysis::Key; +/// Whether or not we should populate a PassInstrumentationCallbacks's class to +/// pass name map. +/// +/// This is for optimization purposes so we don't populate it if we never use +/// it. This should be updated if new pass instrumentation wants to use the map. +/// We currently only use this for --print-before/after. +bool shouldPopulateClassToPassNames() { + return !printBeforePasses().empty() || !printAfterPasses().empty(); +} + } // namespace PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM, @@ -423,6 +435,33 @@ PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM, : DebugLogging(DebugLogging), TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) { if (TM) TM->registerPassBuilderCallbacks(*this, DebugLogging); + if (PIC && shouldPopulateClassToPassNames()) { +#define MODULE_PASS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define FUNCTION_PASS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define LOOP_PASS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define CGSCC_PASS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#include "PassRegistry.def" + for (const auto &P : printBeforePasses()) { + if (!PIC->hasPassName(P)) + report_fatal_error("unrecognized pass name: " + P); + } + for (const auto &P : printAfterPasses()) { + if (!PIC->hasPassName(P)) + report_fatal_error("unrecognized pass name: " + P); + } + } } void PassBuilder::invokePeepholeEPCallbacks( diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp index 445b9d289ad5..abbab4959fe4 100644 --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -15,13 +15,14 @@ #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/ADT/Any.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/Function.h" -#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" +#include "llvm/IR/PrintPasses.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -94,7 +95,7 @@ unwrapModule(Any IR, bool Force = false) { if (any_isa<const Function *>(IR)) { const Function *F = any_cast<const Function *>(IR); - if (!Force && !llvm::isFunctionInPrintList(F->getName())) + if (!Force && !isFunctionInPrintList(F->getName())) return None; const Module *M = F->getParent(); @@ -136,7 +137,7 @@ void printIR(raw_ostream &OS, const Function *F, StringRef Banner, return; } - if (!llvm::isFunctionInPrintList(F->getName())) + if (!isFunctionInPrintList(F->getName())) return; OS << Banner << Extra << "\n" << static_cast<const Value &>(*F); } @@ -149,7 +150,7 @@ void printIR(raw_ostream &OS, const Module *M, StringRef Banner, return; } - if (llvm::isFunctionInPrintList("*") || llvm::forcePrintModuleIR()) { + if (isFunctionInPrintList("*") || forcePrintModuleIR()) { OS << Banner << Extra << "\n"; M->print(OS, nullptr, ShouldPreserveUseListOrder); } else { @@ -169,7 +170,7 @@ void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C, StringRef Banner, bool BannerPrinted = false; for (const LazyCallGraph::Node &N : *C) { const Function &F = N.getFunction(); - if (!F.isDeclaration() && llvm::isFunctionInPrintList(F.getName())) { + if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) { if (!BannerPrinted) { OS << Banner << Extra << "\n"; BannerPrinted = true; @@ -187,9 +188,9 @@ void printIR(raw_ostream &OS, const Loop *L, StringRef Banner, } const Function *F = L->getHeader()->getParent(); - if (!llvm::isFunctionInPrintList(F->getName())) + if (!isFunctionInPrintList(F->getName())) return; - llvm::printLoop(const_cast<Loop &>(*L), OS, std::string(Banner)); + printLoop(const_cast<Loop &>(*L), OS, std::string(Banner)); } /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into @@ -250,7 +251,7 @@ ChangeReporter<IRUnitT>::~ChangeReporter<IRUnitT>() { template <typename IRUnitT> bool ChangeReporter<IRUnitT>::isInterestingFunction(const Function &F) { - return llvm::isFunctionInPrintList(F.getName()); + return isFunctionInPrintList(F.getName()); } template <typename IRUnitT> @@ -430,7 +431,7 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name, Out << "*** IR Dump Before" << Banner.substr(17); // LazyCallGraph::SCC already has "(scc:..." in banner so only add // in the name if it isn't already there. - if (Name.substr(0, 6) != " (scc:" && !llvm::forcePrintModuleIR()) + if (Name.substr(0, 6) != " (scc:" && !forcePrintModuleIR()) Out << Name; StringRef BeforeRef = Before; @@ -441,7 +442,7 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name, // LazyCallGraph::SCC already has "(scc:..." in banner so only add // in the name if it isn't already there. - if (Name.substr(0, 6) != " (scc:" && !llvm::forcePrintModuleIR()) + if (Name.substr(0, 6) != " (scc:" && !forcePrintModuleIR()) Out << Name; Out << After.substr(Banner.size()); @@ -480,14 +481,14 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) { // Note: here we rely on a fact that we do not change modules while // traversing the pipeline, so the latest captured module is good // for all print operations that has not happen yet. - if (StoreModuleDesc && llvm::shouldPrintAfterPass(PassID)) + if (StoreModuleDesc && shouldPrintAfterPass(PassID)) pushModuleDesc(PassID, IR); - if (!llvm::shouldPrintBeforePass(PassID)) + if (!shouldPrintBeforePass(PassID)) return; SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID); - unwrapAndPrint(dbgs(), IR, Banner, llvm::forcePrintModuleIR()); + unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR()); return; } @@ -495,18 +496,19 @@ void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) { if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) return; - if (!llvm::shouldPrintAfterPass(PassID)) + if (!shouldPrintAfterPass(PassID)) return; if (StoreModuleDesc) popModuleDesc(PassID); SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID); - unwrapAndPrint(dbgs(), IR, Banner, llvm::forcePrintModuleIR()); + unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR()); } void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) { - if (!StoreModuleDesc || !llvm::shouldPrintAfterPass(PassID)) + StringRef PassName = PIC->getPassNameForClassName(PassID); + if (!StoreModuleDesc || !shouldPrintAfterPass(PassName)) return; if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) @@ -526,16 +528,42 @@ void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) { printIR(dbgs(), M, Banner, Extra); } +bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) { + if (shouldPrintBeforeAll()) + return true; + + StringRef PassName = PIC->getPassNameForClassName(PassID); + for (const auto &P : printBeforePasses()) { + if (PassName == P) + return true; + } + return false; +} + +bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) { + if (shouldPrintAfterAll()) + return true; + + StringRef PassName = PIC->getPassNameForClassName(PassID); + for (const auto &P : printAfterPasses()) { + if (PassName == P) + return true; + } + return false; +} + void PrintIRInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { + this->PIC = &PIC; + // BeforePass callback is not just for printing, it also saves a Module // for later use in AfterPassInvalidated. - StoreModuleDesc = llvm::forcePrintModuleIR() && llvm::shouldPrintAfterPass(); - if (llvm::shouldPrintBeforePass() || StoreModuleDesc) + StoreModuleDesc = forcePrintModuleIR() && shouldPrintAfterSomePass(); + if (shouldPrintBeforeSomePass() || StoreModuleDesc) PIC.registerBeforeNonSkippedPassCallback( [this](StringRef P, Any IR) { this->printBeforePass(P, IR); }); - if (llvm::shouldPrintAfterPass()) { + if (shouldPrintAfterSomePass()) { PIC.registerAfterPassCallback( [this](StringRef P, Any IR, const PreservedAnalyses &) { this->printAfterPass(P, IR); diff --git a/llvm/test/CodeGen/Generic/print-after.ll b/llvm/test/CodeGen/Generic/print-after.ll deleted file mode 100644 index 1b7ce84a8a54..000000000000 --- a/llvm/test/CodeGen/Generic/print-after.ll +++ /dev/null @@ -1,6 +0,0 @@ -; RUN: llc --help-hidden 2>&1 | FileCheck %s - -; CHECK: -print-after -; CHECK-NOT: -print-after-all -; CHECK: =simple-register-coalescing -; CHECK: -print-after-all diff --git a/llvm/test/Other/loop-pass-printer.ll b/llvm/test/Other/loop-pass-printer.ll index c74d202f2621..de2cf3d38a68 100644 --- a/llvm/test/Other/loop-pass-printer.ll +++ b/llvm/test/Other/loop-pass-printer.ll @@ -1,23 +1,23 @@ ; This test checks -print-after/before on loop passes ; Besides of the loop itself it should be dumping loop pre-header and exits. ; -; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ +; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -loop-deletion -print-before=loop-deletion \ ; RUN: | FileCheck %s -check-prefix=DEL ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -passes='loop(loop-deletion)' -print-before-all \ +; RUN: -passes='loop(loop-deletion)' -print-before=loop-deletion \ ; RUN: | FileCheck %s -check-prefix=DEL ; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ ; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \ ; RUN: | FileCheck %s -check-prefix=BAR -check-prefix=BAR-OLD ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=bar \ +; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after=loop-unroll-full -filter-print-funcs=bar \ ; RUN: | FileCheck %s -check-prefix=BAR ; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ ; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-scope \ ; RUN: | FileCheck %s -check-prefix=FOO-MODULE -check-prefix=FOO-MODULE-OLD ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \ +; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after=loop-unroll-full -filter-print-funcs=foo -print-module-scope \ ; RUN: | FileCheck %s -check-prefix=FOO-MODULE ; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}} diff --git a/llvm/test/Other/print-before-after.ll b/llvm/test/Other/print-before-after.ll new file mode 100644 index 000000000000..c0b929d70c1b --- /dev/null +++ b/llvm/test/Other/print-before-after.ll @@ -0,0 +1,33 @@ +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-before=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-after=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE + +; NONE-NOT: @foo +; NONE-NOT: @bar + +; ONCE: @foo +; ONCE: @bar +; ONCE-NOT: @foo +; ONCE-NOT: @bar + +; TWICE: @foo +; TWICE: @bar +; TWICE: @foo +; TWICE: @bar +; TWICE-NOT: @foo +; TWICE-NOT: @bar + +define void @foo() { + ret void +} + +define void @bar() { + ret void +} diff --git a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn index aa2631a9d229..b2d81b2b7134 100644 --- a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -59,6 +59,7 @@ static_library("IR") { "PassManager.cpp", "PassRegistry.cpp", "PassTimingInfo.cpp", + "PrintPasses.cpp", "ProfileSummary.cpp", "SafepointIRVerifier.cpp", "Statepoint.cpp", _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits