diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h --- 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 namespace llvm { @@ -75,8 +76,9 @@ // useful instrumentation that needs it. using BeforePassFunc = bool(StringRef, Any); using BeforeSkippedPassFunc = void(StringRef, Any); - using BeforeNonSkippedPassFunc = void(StringRef, Any); - using AfterPassFunc = void(StringRef, Any, const PreservedAnalyses &); + using BeforeNonSkippedPassFunc = void(StringRef, StringRef, Any); + using AfterPassFunc = void(StringRef, StringRef, Any, + const PreservedAnalyses &); using AfterPassInvalidatedFunc = void(StringRef, const PreservedAnalyses &); using BeforeAnalysisFunc = void(StringRef, Any); using AfterAnalysisFunc = void(StringRef, Any); @@ -121,6 +123,9 @@ AfterAnalysisCallbacks.emplace_back(std::move(C)); } + void addClassToPassName(StringRef ClassName, StringRef PassName); + bool hasPassName(StringRef PassName); + private: friend class PassInstrumentation; @@ -136,6 +141,8 @@ BeforeAnalysisCallbacks; SmallVector, 4> AfterAnalysisCallbacks; + + StringMap ClassToPassName; }; /// This class provides instrumentation entry points for the Pass Manager, @@ -186,7 +193,7 @@ if (ShouldRun) { for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks) - C(Pass.name(), llvm::Any(&IR)); + C(Pass.name(), Callbacks->ClassToPassName[Pass.name()], llvm::Any(&IR)); } else { for (auto &C : Callbacks->BeforeSkippedPassCallbacks) C(Pass.name(), llvm::Any(&IR)); @@ -203,7 +210,8 @@ const PreservedAnalyses &PA) const { if (Callbacks) for (auto &C : Callbacks->AfterPassCallbacks) - C(Pass.name(), llvm::Any(&IR), PA); + C(Pass.name(), Callbacks->ClassToPassName[Pass.name()], llvm::Any(&IR), + PA); } /// AfterPassInvalidated instrumentation point - takes \p Pass instance diff --git a/llvm/include/llvm/IR/PrintPasses.h b/llvm/include/llvm/IR/PrintPasses.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/IR/PrintPasses.h @@ -0,0 +1,35 @@ +//===- PrintPasses.h - Utilities for printing IR ----------------*- C++ -*-===// +// +// 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 + +namespace llvm { + +bool shouldPrintBeforePass(); +bool shouldPrintAfterPass(); + +bool shouldPrintBeforePass(StringRef PassID); +bool shouldPrintAfterPass(StringRef PassID); + +bool shouldPrintBeforeAll(); +bool shouldPrintAfterAll(); + +std::vector printBeforePasses(); +std::vector printAfterPasses(); + +bool forcePrintModuleIR(); + +bool isFunctionInPrintList(StringRef FunctionName); + +} // namespace llvm + +#endif // LLVM_IR_PRINTPASSES_H diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -262,8 +262,7 @@ explicit PassBuilder(TargetMachine *TM = nullptr, PipelineTuningOptions PTO = PipelineTuningOptions(), Optional PGOOpt = None, - PassInstrumentationCallbacks *PIC = nullptr) - : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {} + PassInstrumentationCallbacks *PIC = nullptr); /// Cross register the analysis managers through their proxies. /// @@ -826,6 +825,6 @@ return false; } -} +} // namespace llvm #endif diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -21,6 +21,7 @@ #include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/ValueHandle.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/CommandLine.h" #include @@ -42,10 +43,13 @@ void registerCallbacks(PassInstrumentationCallbacks &PIC); private: - void printBeforePass(StringRef PassID, Any IR); - void printAfterPass(StringRef PassID, Any IR); + void printBeforePass(StringRef PassID, StringRef PassShortName, Any IR); + void printAfterPass(StringRef PassID, StringRef PassShortName, Any IR); void printAfterPassInvalidated(StringRef PassID); + bool shouldPrintBeforePass(StringRef PassID); + bool shouldPrintAfterPass(StringRef PassID); + using PrintModuleDesc = std::tuple; void pushModuleDesc(StringRef PassID, Any IR); diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -305,7 +305,8 @@ appendLoopsToWorklist(LI, Worklist); #ifndef NDEBUG - PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) { + PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, StringRef, + Any IR) { if (isSpecialPass(PassID, {"PassManager"})) return; assert(any_isa(IR)); diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp --- a/llvm/lib/CodeGen/MachinePassManager.cpp +++ b/llvm/lib/CodeGen/MachinePassManager.cpp @@ -40,13 +40,14 @@ // No need to pop this callback later since MIR pipeline is flat which means // current pipeline is the top-level pipeline. Callbacks are not used after // current pipeline. - PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) { - assert(any_isa(IR)); - const MachineFunction *MF = any_cast(IR); - assert(MF && "Machine function should be valid for printing"); - std::string Banner = std::string("After ") + std::string(PassID); - verifyMachineFunction(&MFAM, Banner, *MF); - }); + PI.pushBeforeNonSkippedPassCallback( + [&MFAM](StringRef PassID, StringRef, Any IR) { + assert(any_isa(IR)); + const MachineFunction *MF = any_cast(IR); + assert(MF && "Machine function should be valid for printing"); + std::string Banner = std::string("After ") + std::string(PassID); + verifyMachineFunction(&MFAM, Banner, *MF); + }); } if (DebugLogging) { diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -45,6 +45,7 @@ PassManager.cpp PassRegistry.cpp PassTimingInfo.cpp + PrintPasses.cpp SafepointIRVerifier.cpp ProfileSummary.cpp Statepoint.cpp diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -49,7 +49,7 @@ enum PassDebugLevel { Disabled, Arguments, Structure, Executions, Details }; -} +} // namespace static cl::opt PassDebugging("debug-pass", cl::Hidden, @@ -61,80 +61,6 @@ clEnumVal(Executions, "print pass name before it is executed"), clEnumVal(Details , "print pass details when it is executed"))); -namespace { -typedef llvm::cl::list -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 PrintBeforeAll("print-before-all", - llvm::cl::desc("Print IR before each pass"), - cl::init(false), cl::Hidden); -static cl::opt PrintAfterAll("print-after-all", - llvm::cl::desc("Print IR after each pass"), - cl::init(false), cl::Hidden); - -static cl::opt - 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 - 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 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 --- a/llvm/lib/IR/PassInstrumentation.cpp +++ b/llvm/lib/IR/PassInstrumentation.cpp @@ -17,6 +17,19 @@ 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; +} + AnalysisKey PassInstrumentationAnalysis::Key; bool isSpecialPass(StringRef PassID, const std::vector &Specials) { diff --git a/llvm/lib/IR/PassTimingInfo.cpp b/llvm/lib/IR/PassTimingInfo.cpp --- a/llvm/lib/IR/PassTimingInfo.cpp +++ b/llvm/lib/IR/PassTimingInfo.cpp @@ -258,9 +258,9 @@ return; PIC.registerBeforeNonSkippedPassCallback( - [this](StringRef P, Any) { this->runBeforePass(P); }); + [this](StringRef P, StringRef, Any) { this->runBeforePass(P); }); PIC.registerAfterPassCallback( - [this](StringRef P, Any, const PreservedAnalyses &) { + [this](StringRef P, StringRef, Any, const PreservedAnalyses &) { this->runAfterPass(P); }); PIC.registerAfterPassInvalidatedCallback( diff --git a/llvm/lib/IR/PrintPasses.cpp b/llvm/lib/IR/PrintPasses.cpp new file mode 100644 --- /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 + +using namespace llvm; + +// Print IR out before/after specified passes. +static cl::list + PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes"), + cl::CommaSeparated, cl::Hidden); + +static cl::list + PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"), + cl::CommaSeparated, cl::Hidden); + +static cl::opt PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false), cl::Hidden); +static cl::opt PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false), cl::Hidden); + +static cl::opt + 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 + 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::shouldPrintBeforePass() { + return PrintBeforeAll || !PrintBefore.empty(); +} + +bool llvm::shouldPrintAfterPass() { + return PrintAfterAll || !PrintAfter.empty(); +} + +static bool shouldPrintBeforeOrAfterPass(StringRef PassID, + ArrayRef 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 llvm::printBeforePasses() { + return std::vector(PrintBefore); +} + +std::vector llvm::printAfterPasses() { + return std::vector(PrintAfter); +} + +bool llvm::forcePrintModuleIR() { return PrintModuleScope; } + +bool llvm::isFunctionInPrintList(StringRef FunctionName) { + static std::unordered_set PrintFuncNames(PrintFuncsList.begin(), + PrintFuncsList.end()); + return PrintFuncNames.empty() || + PrintFuncNames.count(std::string(FunctionName)); +} diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -224,8 +224,8 @@ StandardInstrumentations SI(Conf.DebugPassManager); SI.registerCallbacks(PIC); PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); - AAManager AA; + AAManager AA; // Parse a custom AA pipeline if asked to. if (auto Err = PB.parseAAPipeline(AA, "default")) report_fatal_error("Error parsing default AA pipeline"); @@ -720,4 +720,4 @@ OwnedImportsLifetimeManager.push_back(std::move(*MBOrErr)); } return true; -} \ No newline at end of file +} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -68,10 +68,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" @@ -430,6 +432,40 @@ } // namespace +PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO, + Optional PGOOpt, + PassInstrumentationCallbacks *PIC) + : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) { + if (PIC && (!printBeforePasses().empty() || !printAfterPasses().empty())) { + bool DebugLogging = false; +#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( FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { for (auto &C : PeepholeEPCallbacks) @@ -2836,7 +2872,7 @@ #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ if (PassName == NAME) \ return true; -#define CGSSC_ANALYSIS(NAME, CREATE_PASS) \ +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ if (PassName == NAME) \ return true; #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- 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" @@ -353,7 +354,7 @@ }); PIC.registerAfterPassCallback( - [this](StringRef P, Any IR, const PreservedAnalyses &) { + [this](StringRef P, StringRef, Any IR, const PreservedAnalyses &) { handleIRAfterPass(IR, P); }); PIC.registerAfterPassInvalidatedCallback( @@ -444,7 +445,8 @@ return ModuleDesc; } -void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) { +void PrintIRInstrumentation::printBeforePass(StringRef PassID, + StringRef PassShortName, Any IR) { if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) return; @@ -452,10 +454,10 @@ // 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(PassShortName)) pushModuleDesc(PassID, IR); - if (!llvm::shouldPrintBeforePass(PassID)) + if (!shouldPrintBeforePass(PassShortName)) return; SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID); @@ -463,11 +465,12 @@ return; } -void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) { +void PrintIRInstrumentation::printAfterPass(StringRef PassID, + StringRef PassShortName, Any IR) { if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) return; - if (!llvm::shouldPrintAfterPass(PassID)) + if (!shouldPrintAfterPass(PassShortName)) return; if (StoreModuleDesc) @@ -478,7 +481,7 @@ } void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) { - if (!StoreModuleDesc || !llvm::shouldPrintAfterPass(PassID)) + if (!StoreModuleDesc || !shouldPrintAfterPass(PassID)) return; if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) @@ -498,6 +501,26 @@ printIR(dbgs(), M, Banner, Extra); } +bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) { + if (llvm::shouldPrintBeforeAll()) + return true; + for (const auto &P : printBeforePasses()) { + if (PassID == P) + return true; + } + return false; +} + +bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) { + if (llvm::shouldPrintAfterAll()) + return true; + for (const auto &P : printAfterPasses()) { + if (PassID == P) + return true; + } + return false; +} + void PrintIRInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { // BeforePass callback is not just for printing, it also saves a Module @@ -505,12 +528,14 @@ StoreModuleDesc = llvm::forcePrintModuleIR() && llvm::shouldPrintAfterPass(); if (llvm::shouldPrintBeforePass() || StoreModuleDesc) PIC.registerBeforeNonSkippedPassCallback( - [this](StringRef P, Any IR) { this->printBeforePass(P, IR); }); + [this](StringRef C, StringRef P, Any IR) { + this->printBeforePass(C, P, IR); + }); if (llvm::shouldPrintAfterPass()) { PIC.registerAfterPassCallback( - [this](StringRef P, Any IR, const PreservedAnalyses &) { - this->printAfterPass(P, IR); + [this](StringRef C, StringRef P, Any IR, const PreservedAnalyses &) { + this->printAfterPass(C, P, IR); }); PIC.registerAfterPassInvalidatedCallback( [this](StringRef P, const PreservedAnalyses &) { @@ -556,7 +581,7 @@ }); PIC.registerBeforeNonSkippedPassCallback( - [SpecialPasses](StringRef PassID, Any IR) { + [SpecialPasses](StringRef PassID, StringRef, Any IR) { if (isSpecialPass(PassID, SpecialPasses)) return; @@ -687,12 +712,13 @@ if (!VerifyPreservedCFG) return; - PIC.registerBeforeNonSkippedPassCallback([this](StringRef P, Any IR) { - if (any_isa(IR)) - GraphStackBefore.emplace_back(P, CFG(any_cast(IR))); - else - GraphStackBefore.emplace_back(P, None); - }); + PIC.registerBeforeNonSkippedPassCallback( + [this](StringRef P, StringRef, Any IR) { + if (any_isa(IR)) + GraphStackBefore.emplace_back(P, CFG(any_cast(IR))); + else + GraphStackBefore.emplace_back(P, None); + }); PIC.registerAfterPassInvalidatedCallback( [this](StringRef P, const PreservedAnalyses &PassPA) { @@ -702,7 +728,7 @@ (void)Before; }); - PIC.registerAfterPassCallback([this](StringRef P, Any IR, + PIC.registerAfterPassCallback([this](StringRef P, StringRef, Any IR, const PreservedAnalyses &PassPA) { auto Before = GraphStackBefore.pop_back_val(); assert(Before.first == P && "Before and After callbacks must correspond"); @@ -728,7 +754,7 @@ void VerifyInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { PIC.registerAfterPassCallback( - [this](StringRef P, Any IR, const PreservedAnalyses &PassPA) { + [this](StringRef P, StringRef, Any IR, const PreservedAnalyses &PassPA) { if (isIgnored(P) || P == "VerifierPass") return; if (any_isa(IR) || any_isa(IR)) { diff --git a/llvm/test/CodeGen/Generic/print-after.ll b/llvm/test/CodeGen/Generic/print-after.ll --- a/llvm/test/CodeGen/Generic/print-after.ll +++ b/llvm/test/CodeGen/Generic/print-after.ll @@ -1,6 +1,4 @@ ; 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 --- 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,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=bar \ +; RUN: -passes='require,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,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \ +; RUN: -passes='require,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 --- /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/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp --- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp +++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp @@ -338,13 +338,12 @@ this->runBeforeSkippedPass(P, IR); }); Callbacks.registerBeforeNonSkippedPassCallback( - [this](StringRef P, llvm::Any IR) { + [this](StringRef P, StringRef, llvm::Any IR) { this->runBeforeNonSkippedPass(P, IR); }); Callbacks.registerAfterPassCallback( - [this](StringRef P, llvm::Any IR, const PreservedAnalyses &PA) { - this->runAfterPass(P, IR, PA); - }); + [this](StringRef P, StringRef, llvm::Any IR, + const PreservedAnalyses &PA) { this->runAfterPass(P, IR, PA); }); Callbacks.registerAfterPassInvalidatedCallback( [this](StringRef P, const PreservedAnalyses &PA) { this->runAfterPassInvalidated(P, PA); diff --git a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -60,6 +60,7 @@ "PassManager.cpp", "PassRegistry.cpp", "PassTimingInfo.cpp", + "PrintPasses.cpp", "ProfileSummary.cpp", "SafepointIRVerifier.cpp", "Statepoint.cpp",