Index: lib/Passes/StandardInstrumentations.cpp =================================================================== --- lib/Passes/StandardInstrumentations.cpp +++ lib/Passes/StandardInstrumentations.cpp @@ -37,10 +37,6 @@ /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into /// llvm::Any and does actual print job. void unwrapAndPrint(StringRef Banner, Any IR) { - if (any_isa(IR) || - any_isa(IR)) - return; - SmallString<40> Extra{"\n"}; const Module *M = nullptr; if (any_isa(IR)) { @@ -55,6 +51,32 @@ } M = F->getParent(); Extra = formatv(" (function: {0})\n", F->getName()); + } else if (any_isa(IR)) { + const LazyCallGraph::SCC *C = any_cast(IR); + assert(C); + if (!llvm::forcePrintModuleIR()) { + Extra = formatv(" (scc: {0})\n", C->getName()); + bool BannerPrinted = false; + for (const LazyCallGraph::Node &N : *C) { + const Function &F = N.getFunction(); + if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) { + if (!BannerPrinted) { + dbgs() << Banner << Extra; + BannerPrinted = true; + } + F.print(dbgs()); + } + } + return; + } + for (const LazyCallGraph::Node &N : *C) { + const Function &F = N.getFunction(); + if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) + M = F.getParent(); + } + if (!M) + return; + Extra = formatv(" (for scc: {0})\n", C->getName()); } else if (any_isa(IR)) { const Loop *L = any_cast(IR); const Function *F = L->getHeader()->getParent(); Index: test/Other/scc-pass-printer.ll =================================================================== --- /dev/null +++ test/Other/scc-pass-printer.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -inline -print-after-all | FileCheck %s -check-prefix=INL +; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -passes=inline -print-after-all | FileCheck %s -check-prefix=INL +; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -inline -print-after-all -print-module-scope | FileCheck %s -check-prefix=INL-MOD +; RUN: opt < %s 2>&1 -disable-output \ +; RUN: -passes=inline -print-after-all -print-module-scope | FileCheck %s -check-prefix=INL-MOD + +; INL: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .bar, foo}} +; INL: define void @bar() +; INL-NEXT: call void @foo() +; INL: define void @foo() +; INL-NEXT: call void @bar() +; INL: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .tester}} +; INL: define void @tester() +; INL-NEXT: call void @foo() +; INL: IR Dump After + +; INL-MOD: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .bar, foo}} +; INL-MOD: define void @tester() +; INL-MOD-NEXT: call void @foo() +; INL-MOD: define void @foo() +; INL-MOD-NEXT: call void @bar() +; INL-MOD: define void @bar() +; INL-MOD-NEXT: call void @foo() +; INL-MOD: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .tester}} +; INL-MOD: define void @tester() +; INL-MOD-NEXT: call void @foo() +; INL-MOD: define void @foo() +; INL-MOD-NEXT: call void @bar() +; INL-MOD: define void @bar() +; INL-MOD-NEXT: call void @foo() +; INL-MOD: IR Dump After + +define void @tester() noinline { + call void @foo() + ret void +} + +define void @foo() noinline { + call void @bar() + ret void +} + +define void @bar() noinline { + call void @foo() + ret void +}