Index: include/llvm/Pass.h =================================================================== --- include/llvm/Pass.h +++ include/llvm/Pass.h @@ -369,6 +369,10 @@ /// @brief 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. +// @brief Tells if the function IR should be printed by PrinterPass. +extern bool isFunctionInPrintList(StringRef FunctionName); } // End llvm namespace // Include support files that contain important APIs commonly used by Passes, Index: lib/Analysis/CallGraphSCCPass.cpp =================================================================== --- lib/Analysis/CallGraphSCCPass.cpp +++ lib/Analysis/CallGraphSCCPass.cpp @@ -612,9 +612,10 @@ bool runOnSCC(CallGraphSCC &SCC) override { Out << Banner; for (CallGraphNode *CGN : SCC) { - if (CGN->getFunction()) - CGN->getFunction()->print(Out); - else + if (CGN->getFunction()) { + if (isFunctionInPrintList(CGN->getFunction()->getName())) + CGN->getFunction()->print(Out); + } else Out << "\nPrinting Function\n"; } return false; Index: lib/Analysis/LoopPass.cpp =================================================================== --- lib/Analysis/LoopPass.cpp +++ lib/Analysis/LoopPass.cpp @@ -42,7 +42,9 @@ } bool runOnLoop(Loop *L, LPPassManager &) override { - P.run(*L); + if (L->getHeader() && + isFunctionInPrintList(L->getHeader()->getParent()->getName())) + P.run(*L); return false; } }; Index: lib/CodeGen/MachineFunctionPrinterPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPrinterPass.cpp +++ lib/CodeGen/MachineFunctionPrinterPass.cpp @@ -31,7 +31,7 @@ const std::string Banner; MachineFunctionPrinterPass() : MachineFunctionPass(ID), OS(dbgs()) { } - MachineFunctionPrinterPass(raw_ostream &os, const std::string &banner) + MachineFunctionPrinterPass(raw_ostream &os, const std::string &banner) : MachineFunctionPass(ID), OS(os), Banner(banner) {} const char *getPassName() const override { return "MachineFunction Printer"; } @@ -42,6 +42,8 @@ } bool runOnMachineFunction(MachineFunction &MF) override { + if (!llvm::isFunctionInPrintList(MF.getName())) + return false; OS << "# " << Banner << ":\n"; MF.print(OS, getAnalysisIfAvailable()); return false; Index: lib/IR/IRPrintingPasses.cpp =================================================================== --- lib/IR/IRPrintingPasses.cpp +++ lib/IR/IRPrintingPasses.cpp @@ -27,8 +27,14 @@ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} PreservedAnalyses PrintModulePass::run(Module &M) { - OS << Banner; - M.print(OS, nullptr, ShouldPreserveUseListOrder); + OS << Banner << "\n"; + if (llvm::isFunctionInPrintList("*")) + M.print(OS, nullptr, ShouldPreserveUseListOrder); + else { + for(const auto &F : M.functions()) + if (llvm::isFunctionInPrintList(F.getName())) + F.print(OS); + } return PreservedAnalyses::all(); } @@ -37,7 +43,8 @@ : OS(OS), Banner(Banner) {} PreservedAnalyses PrintFunctionPass::run(Function &F) { - OS << Banner << static_cast(F); + if (isFunctionInPrintList(F.getName())) + OS << Banner << static_cast(F); return PreservedAnalyses::all(); } Index: lib/IR/LegacyPassManager.cpp =================================================================== --- lib/IR/LegacyPassManager.cpp +++ lib/IR/LegacyPassManager.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/raw_ostream.h" #include #include +#include using namespace llvm; using namespace llvm::legacy; @@ -83,6 +84,11 @@ llvm::cl::desc("Print IR after each pass"), cl::init(false)); +static cl::list + PrintFuncsList("print-funcs", cl::value_desc("function names"), + cl::desc("Print IR only for specified functions"), + cl::CommaSeparated); + /// This is a helper to determine whether to print IR before or /// after a pass. @@ -109,6 +115,20 @@ return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); } +bool llvm::isFunctionInPrintList(StringRef FunctionName) { + static std::set PrintFuncNames; + // Initialization. + if (PrintFuncNames.empty()) { + PrintFuncNames.insert(PrintFuncsList.begin(), PrintFuncsList.end()); + // Put "*" to indicate that all functions/whole module will be printed. + if (PrintFuncNames.empty()) + PrintFuncNames.insert("*"); + } + + if (PrintFuncNames.count("*")) + return true; + return PrintFuncNames.count(FunctionName); +} /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions /// or higher is specified. bool PMDataManager::isPassDebuggingExecutionsOrMore() const { Index: test/Other/2010-05-06-Printer.ll =================================================================== --- test/Other/2010-05-06-Printer.ll +++ test/Other/2010-05-06-Printer.ll @@ -1,7 +1,19 @@ ; RUN: llc -O2 -print-after-all < %s 2>/dev/null +; RUN: llc -O2 -print-after-all < %s 2>&1 | FileCheck %s --check-prefix=ALL +; RUN: llc -O2 -print-after-all -print-funcs=foo < %s 2>&1 | FileCheck %s --check-prefix=FOO ; REQUIRES: default_triple define void @tester(){ ret void } +define void @foo(){ + ret void +} + +;ALL: define void @tester() +;ALL: define void @foo() + +;FOO: IR Dump After +;FOO-NEXT: define void @foo() +;FOO-NOT: define void @tester