Index: include/llvm/Analysis/PrintIR.h =================================================================== --- /dev/null +++ include/llvm/Analysis/PrintIR.h @@ -0,0 +1,40 @@ +//===- PrintIR.h - routines to print IR/Analysis constructs ---*- C++ ---*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file defines functions to print out IR in various granularities. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PRINTIR_H +#define LLVM_ANALYSIS_PRINTIR_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/PassInstrumentation.h" + +namespace llvm { + +// TODO: Do we need state for our printers? +// Then we need a class and some way to manage its instances. + +namespace PrintIR { + +/// IR-printing wrapper to be installed into PassInstrumentation as BeforePass +/// callback +bool printBeforePass(StringRef PassID, Any, PassExecutionCounter); + +/// IR-printing wrapper to be installed into PassInstrumentation as AfterPass +/// callback +bool printAfterPass(StringRef PassID, Any, PassExecutionCounter); + +} // namespace PrintIR + +} // namespace llvm + +#endif Index: include/llvm/IR/IRPrintingPasses.h =================================================================== --- include/llvm/IR/IRPrintingPasses.h +++ include/llvm/IR/IRPrintingPasses.h @@ -58,6 +58,22 @@ /// 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 Index: include/llvm/IR/PassInstrumentation.h =================================================================== --- include/llvm/IR/PassInstrumentation.h +++ include/llvm/IR/PassInstrumentation.h @@ -47,10 +47,12 @@ class PassInstrumentationImpl { public: - // Before/After Pass callbacks accept IRUnits, so they need to take them + // Before/After callbacks accept IRUnits, so they need to take them // as pointers, wrapped with llvm::Any using BeforePassFunc = bool(StringRef, Any, PassExecutionCounter); using AfterPassFunc = void(StringRef, Any, PassExecutionCounter); + using BeforeAnalysisFunc = void(StringRef, Any, PassExecutionCounter); + using AfterAnalysisFunc = void(StringRef, Any, PassExecutionCounter); public: PassInstrumentationImpl() {} @@ -61,6 +63,12 @@ template void runAfterPass(StringRef PassID, IRUnitT &) const; + template + void runBeforeAnalysis(StringRef PassID, IRUnitT &) const; + + template + void runAfterAnalysis(StringRef PassID, IRUnitT &) const; + void runStartPipeline() const; void runEndPipeline() const; @@ -73,6 +81,16 @@ AfterPassCallbacks.push_back(C); } + void + registerBeforeAnalysisCallback(const std::function &C) { + BeforeAnalysisCallbacks.push_back(C); + } + + void + registerAfterAnalysisCallback(const std::function &C) { + AfterAnalysisCallbacks.push_back(C); + } + void registerStartPipelineCallback(const std::function &C) { StartPipelineCallbacks.push_back(C); } @@ -89,6 +107,8 @@ SmallVector, 4> BeforePassCallbacks; SmallVector, 4> AfterPassCallbacks; + SmallVector, 4> BeforeAnalysisCallbacks; + SmallVector, 4> AfterAnalysisCallbacks; SmallVector, 2> StartPipelineCallbacks; SmallVector, 2> EndPipelineCallbacks; }; @@ -130,6 +150,16 @@ Impl->runAfterPass(PassID, IR); } + void runBeforeAnalysis(StringRef PassID, IRUnitT &IR) { + if (Impl) + Impl->runBeforeAnalysis(PassID, IR); + } + + void runAfterAnalysis(StringRef PassID, IRUnitT &IR) { + if (Impl) + Impl->runAfterAnalysis(PassID, IR); + } + void runStartPipeline() { if (Impl) Impl->runStartPipeline(); @@ -152,6 +182,18 @@ Impl->registerAfterPassCallback(C); } + void registerBeforeAnalysisCallback( + const std::function &C) { + assert(Impl); + Impl->registerBeforeAnalysisCallback(C); + } + + void registerAfterAnalysisCallback( + const std::function &C) { + assert(Impl); + Impl->registerAfterAnalysisCallback(C); + } + void registerStartPipelineCallback(const std::function &C) { assert(Impl); Impl->registerStartPipelineCallback(C); Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -905,9 +905,22 @@ if (DebugLogging) dbgs() << "Running analysis: " << P.name() << " on " << IR.getName() << "\n"; + + PassInstrumentation PI; + bool IsInstrumentationAnalysis = + (ID == PassInstrumentationAnalysis::ID()); + if (!IsInstrumentationAnalysis) { + PI = + getPassInstrumentation(IR, std::tuple(ExtraArgs...)); + PI.runBeforeAnalysis(P.name(), IR); + } + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); + if (!IsInstrumentationAnalysis) + PI.runAfterAnalysis(P.name(), IR); + // P.run may have inserted elements into AnalysisResults and invalidated // RI. RI = AnalysisResults.find({ID, &IR}); Index: include/llvm/Pass.h =================================================================== --- include/llvm/Pass.h +++ include/llvm/Pass.h @@ -356,17 +356,6 @@ /// This is the storage for the -time-passes option. extern bool TimePassesIsEnabled; -/// 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(); - } // end namespace llvm // Include support files that contain important APIs commonly used by Passes, Index: lib/Analysis/CMakeLists.txt =================================================================== --- lib/Analysis/CMakeLists.txt +++ lib/Analysis/CMakeLists.txt @@ -67,6 +67,7 @@ PHITransAddr.cpp PhiValues.cpp PostDominators.cpp + PrintIR.cpp ProfileSummaryInfo.cpp PtrUseVisitor.cpp RegionInfo.cpp Index: lib/Analysis/CallGraphSCCPass.cpp =================================================================== --- lib/Analysis/CallGraphSCCPass.cpp +++ lib/Analysis/CallGraphSCCPass.cpp @@ -22,6 +22,7 @@ #include "llvm/Analysis/CallGraph.h" #include "llvm/IR/CallSite.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" Index: lib/Analysis/LoopInfo.cpp =================================================================== --- lib/Analysis/LoopInfo.cpp +++ lib/Analysis/LoopInfo.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" Index: lib/Analysis/PrintIR.cpp =================================================================== --- /dev/null +++ lib/Analysis/PrintIR.cpp @@ -0,0 +1,96 @@ +//===--- PrintIR.cpp - routines to print IR/Analysis constructs -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// PrintIR routines implementation +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/PrintIR.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "printir" + +namespace llvm { + +/// Generic IR-printing helper that unpacks IRUnit wrapped into llvm::Any and +/// does actual print job. +static void unwrapAndPrint(StringRef Banner, Any IR) { + SmallString<40> Extra{"\n"}; + Module *M = nullptr; + if (any_isa(IR)) { + M = any_cast(IR); + } else if (any_isa(IR)) { + Function *F = any_cast(IR); + if (!llvm::isFunctionInPrintList(F->getName())) + return; + if (!llvm::forcePrintModuleIR()) { + dbgs() << Banner << Extra << static_cast(*F); + return; + } + M = F->getParent(); + Extra = formatv(" (function: {0})\n", F->getName()); + } else if (any_isa(IR)) { + Loop *L = any_cast(IR); + Function *F = L->getHeader()->getParent(); + if (!isFunctionInPrintList(F->getName())) + return; + if (!llvm::forcePrintModuleIR()) { + llvm::printLoop(*L, dbgs(), Banner); + return; + } + M = F->getParent(); + { + std::string LoopName; + raw_string_ostream ss(LoopName); + L->getHeader()->printAsOperand(ss, false); + Extra = formatv(" (loop: {0})\n", ss.str()); + } + } + if (M) { + dbgs() << Banner << Extra; + M->print(dbgs(), nullptr, false); + } else { + llvm_unreachable("Unknown wrapped IR type"); + } +} + +bool PrintIR::printBeforePass(StringRef PassID, Any IR, + PassExecutionCounter PC) { + if (!llvm::shouldPrintBeforePass(PassID)) + return true; + + if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) + return true; + + SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID); + unwrapAndPrint(Banner, IR); + return true; +} + +bool PrintIR::printAfterPass(StringRef PassID, Any IR, + PassExecutionCounter PC) { + if (!llvm::shouldPrintAfterPass(PassID)) + return false; + + if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<")) + return true; + + SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID); + unwrapAndPrint(Banner, IR); + return true; +} + +} // namespace llvm Index: lib/CodeGen/MachineFunctionPrinterPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPrinterPass.cpp +++ lib/CodeGen/MachineFunctionPrinterPass.cpp @@ -15,6 +15,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" Index: lib/IR/LegacyPassManager.cpp =================================================================== --- lib/IR/LegacyPassManager.cpp +++ lib/IR/LegacyPassManager.cpp @@ -99,27 +99,31 @@ /// This is a helper to determine whether to print IR before or /// after a pass. -static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, +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() == PI->getPassArgument()) { + if (PassInf->getPassArgument() == PassID) { return true; } } return false; } -/// This is a utility to check whether a pass should have IR dumped -/// before it. -static bool ShouldPrintBeforePass(const PassInfo *PI) { - return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); +bool llvm::shouldPrintBeforePass(StringRef PassID) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore); } -/// This is a utility to check whether a pass should have IR dumped -/// after it. -static bool ShouldPrintAfterPass(const PassInfo *PI) { - return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); +bool llvm::shouldPrintAfterPass(StringRef PassID) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter); } bool llvm::forcePrintModuleIR() { return PrintModuleScope; } @@ -749,7 +753,7 @@ return; } - if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) { + if (PI && !PI->isAnalysis() && shouldPrintBeforePass(PI->getPassArgument())) { Pass *PP = P->createPrinterPass( dbgs(), ("*** IR Dump Before " + P->getPassName() + " ***").str()); PP->assignPassManager(activeStack, getTopLevelPassManagerType()); @@ -758,7 +762,7 @@ // Add the requested pass to the best available pass manager. P->assignPassManager(activeStack, getTopLevelPassManagerType()); - if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) { + if (PI && !PI->isAnalysis() && shouldPrintAfterPass(PI->getPassArgument())) { Pass *PP = P->createPrinterPass( dbgs(), ("*** IR Dump After " + P->getPassName() + " ***").str()); PP->assignPassManager(activeStack, getTopLevelPassManagerType()); Index: lib/IR/PassInstrumentation.cpp =================================================================== --- lib/IR/PassInstrumentation.cpp +++ lib/IR/PassInstrumentation.cpp @@ -33,6 +33,20 @@ C(PassID, llvm::Any(&IR), PC); } +template +void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + IRUnitT &IR) const { + for (auto &C : BeforeAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +template +void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + IRUnitT &IR) const { + for (auto &C : AfterAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + void PassInstrumentationImpl::runStartPipeline() const { for (auto &C : StartPipelineCallbacks) C(); @@ -62,6 +76,25 @@ PassInstrumentationImpl::runAfterPass(StringRef PassID, LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Module &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Function &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Loop &IR) const; +template void +PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Module &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Function &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Loop &IR) const; +template void +PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + LazyCallGraph::SCC &IR) const; + template class PassInstrumentationAnalysis; template class PassInstrumentationAnalysis; Index: test/Other/loop-pass-printer.ll =================================================================== --- test/Other/loop-pass-printer.ll +++ test/Other/loop-pass-printer.ll @@ -5,14 +5,22 @@ ; 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: | FileCheck %s -check-prefix=DEL +; RUN: opt < %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(unroll-full)' -print-after-all -filter-print-funcs=bar \ ; RUN: | FileCheck %s -check-prefix=BAR ; RUN: opt < %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(unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \ ; RUN: | FileCheck %s -check-prefix=FOO-MODULE -; DEL: IR Dump Before -; DEL-SAME: dead loops +; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}} ; DEL: ; Preheader: ; DEL-NEXT: %idx = alloca i32, align 4 ; DEL: ; Loop: @@ -20,8 +28,7 @@ ; DEL: cont: ; DEL: ; Exit blocks ; DEL: done: -; DEL: IR Dump Before -; DEL-SAME: dead loops +; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}} ; DEL: ; Preheader: ; DEL-NEXT: br label %loop ; DEL: ; Loop: @@ -29,24 +36,22 @@ ; DEL: ; Exit blocks ; DEL: end: -; BAR: IR Dump After -; BAR-SAME: Unroll +; BAR: IR Dump After {{Unroll|LoopFullUnrollPass}} ; BAR: ; Preheader: ; BAR-NEXT: br label %loop ; BAR: ; Loop: ; BAR-NEXT: loop: ; BAR: ; Exit blocks ; BAR: end: -; BAR-NOT: IR Dump -; BAR-NOT: ; Loop +; BAR-OLD-NOT: IR Dump +; BAR-OLD-NOT: ; Loop -; FOO-MODULE: IR Dump After -; FOO-MODULE-SAME: Unroll +; FOO-MODULE: IR Dump After {{Unroll|LoopFullUnrollPass}} ; FOO-MODULE-SAME: loop: %loop ; FOO-MODULE-NEXT: ModuleID = ; FOO-MODULE: define void @foo ; FOO-MODULE: define void @bar -; FOO-MODULE-NOT: IR Dump +; FOO-MODULE-OLD-NOT: IR Dump define void @foo(){ %idx = alloca i32, align 4 Index: test/Other/new-pm-lto-defaults.ll =================================================================== --- test/Other/new-pm-lto-defaults.ll +++ test/Other/new-pm-lto-defaults.ll @@ -50,8 +50,10 @@ ; CHECK-O1-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Function ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: AAManager +; CHECK-O1-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: CallGraphAnalysis Index: test/Other/new-pm-thinlto-defaults.ll =================================================================== --- test/Other/new-pm-thinlto-defaults.ll +++ test/Other/new-pm-thinlto-defaults.ll @@ -58,13 +58,14 @@ ; CHECK-POSTLINK-O-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-POSTLINK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-POSTLINK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis +; CHECK-POSTLINK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy -; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> +; CHECK-PRELINK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis Index: test/Other/print-module-scope.ll =================================================================== --- test/Other/print-module-scope.ll +++ test/Other/print-module-scope.ll @@ -7,10 +7,16 @@ ; RUN: -simplifycfg -print-after=simplifycfg -print-module-scope \ ; RUN: | FileCheck %s -check-prefix=CFG ; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -passes=simplify-cfg -print-after-all -print-module-scope \ +; RUN: | FileCheck %s -check-prefix=CFG +; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -simplifycfg -print-after=simplifycfg -filter-print-funcs=foo -print-module-scope \ ; RUN: | FileCheck %s -check-prefix=FOO +; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -passes=simplify-cfg -print-after-all -filter-print-funcs=foo -print-module-scope \ +; RUN: | FileCheck %s -check-prefix=FOO -; CFG: IR Dump After +; CFG: IR Dump After {{Simplify the CFG|SimplifyCFGPass}} ; CFG-SAME: function: foo ; CFG-NEXT: ModuleID = ; CFG: define void @foo @@ -23,7 +29,7 @@ ; CFG: define void @bar ; CFG: declare void @baz -; FOO: IR Dump After +; FOO: IR Dump After {{Simplify the CFG|SimplifyCFGPass}} ; FOO-NOT: function: bar ; FOO-SAME: function: foo ; FOO-NEXT: ModuleID = @@ -52,4 +58,4 @@ ; FOO: attributes #{{[0-9]}} = { nounwind readnone ssp "use-soft-float"="false" } -; FOO-NOT: IR Dump +; FOO-NOT: IR Dump After {{Simplify the CFG|SimplifyCFGPass}} Index: test/Other/printer.ll =================================================================== --- test/Other/printer.ll +++ test/Other/printer.ll @@ -1,4 +1,5 @@ -; RUN: opt -mem2reg -instcombine -print-after-all -S < %s 2>&1 | FileCheck %s +; RUN: opt -mem2reg -instcombine -print-after-all -disable-output < %s 2>&1 | FileCheck %s +; RUN: opt -passes='mem2reg,instcombine' -print-after-all -disable-output < %s 2>&1 | FileCheck %s define void @tester(){ ret void } @@ -7,7 +8,21 @@ ret void } -;CHECK: IR Dump After Promote Memory to Register -;CHECK: IR Dump After Combine redundant instructions -;CHECK: IR Dump After Module Verifier +;CHECK-NOT: IR Dump After PassManager +;CHECK-NOT: IR Dump After ModuleToFunctionPassAdaptor +; +;CHECK: *** IR Dump After {{Promote Memory to Register|PromotePass}} +;CHECK: define void @tester +;CHECK-NOT: define void @foo +;CHECK: *** IR Dump After {{Combine redundant instructions|InstCombinePass}} +;CHECK: define void @tester +;CHECK-NOT: define void @foo +;CHECK: *** IR Dump After {{Promote Memory to Register|PromotePass}} +;CHECK: define void @foo +;CHECK-NOT: define void @tester +;CHECK: *** IR Dump After {{Combine redundant instructions|InstCombinePass}} +;CHECK: define void @foo +;CHECK-NOT: define void @tester +;CHECK: *** IR Dump After {{Module Verifier|VerifierPass}} +; ;CHECK-NOT: IR Dump After Print Module IR Index: tools/opt/NewPMDriver.cpp =================================================================== --- tools/opt/NewPMDriver.cpp +++ tools/opt/NewPMDriver.cpp @@ -13,12 +13,13 @@ /// //===----------------------------------------------------------------------===// -#include "Debugify.h" #include "NewPMDriver.h" +#include "Debugify.h" #include "PassPrinters.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/PrintIR.h" #include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Dominators.h" @@ -179,6 +180,17 @@ }); } +static void registerInstrumentation(PassBuilder &PB) { + if (llvm::shouldPrintBeforePass()) + PB.registerPassInstrumentation([](PassInstrumentationImpl &PI) { + PI.registerBeforePassCallback(PrintIR::printBeforePass); + }); + if (llvm::shouldPrintAfterPass()) + PB.registerPassInstrumentation([](PassInstrumentationImpl &PI) { + PI.registerAfterPassCallback(PrintIR::printAfterPass); + }); +} + #ifdef LINK_POLLY_INTO_TOOLS namespace polly { void RegisterPollyPasses(PassBuilder &); @@ -215,6 +227,7 @@ } PassBuilder PB(TM, P); registerEPCallbacks(PB, VerifyEachPass, DebugPM); + registerInstrumentation(PB); // Load requested pass plugins and let them register pass builder callbacks for (auto &PluginFN : PassPlugins) {