diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -479,7 +479,8 @@ bool isAnnotatedParallel() const { return false; } /// Print loop with all the BBs inside it. - void print(raw_ostream &OS, unsigned Depth = 0, bool Verbose = false) const; + void print(raw_ostream &OS, bool Verbose = false, bool PrintNested = true, + unsigned Depth = 0) const; protected: friend class LoopInfoBase; diff --git a/llvm/include/llvm/Analysis/LoopInfoImpl.h b/llvm/include/llvm/Analysis/LoopInfoImpl.h --- a/llvm/include/llvm/Analysis/LoopInfoImpl.h +++ b/llvm/include/llvm/Analysis/LoopInfoImpl.h @@ -381,8 +381,8 @@ } template -void LoopBase::print(raw_ostream &OS, unsigned Depth, - bool Verbose) const { +void LoopBase::print(raw_ostream &OS, bool Verbose, + bool PrintNested, unsigned Depth) const { OS.indent(Depth * 2); if (static_cast(this)->isAnnotatedParallel()) OS << "Parallel "; @@ -407,10 +407,13 @@ if (Verbose) BB->print(OS); } - OS << "\n"; - for (iterator I = begin(), E = end(); I != E; ++I) - (*I)->print(OS, Depth + 2); + if (PrintNested) { + OS << "\n"; + + for (iterator I = begin(), E = end(); I != E; ++I) + (*I)->print(OS, /*Verbose*/ false, PrintNested, Depth + 2); + } } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -662,7 +662,7 @@ LLVM_DUMP_METHOD void Loop::dump() const { print(dbgs()); } LLVM_DUMP_METHOD void Loop::dumpVerbose() const { - print(dbgs(), /*Depth=*/0, /*Verbose=*/true); + print(dbgs(), /*Verbose=*/true); } #endif 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 @@ -237,107 +237,97 @@ llvm_unreachable("Unknown IR unit"); } -void printIR(raw_ostream &OS, const Function *F, StringRef Banner, - StringRef Extra = StringRef(), bool Brief = false) { - if (Brief) { - OS << F->getName() << '\n'; - return; - } - +void printIR(raw_ostream &OS, const Function *F) { if (!isFunctionInPrintList(F->getName())) return; - OS << Banner << Extra << "\n" << static_cast(*F); + OS << *F; } -void printIR(raw_ostream &OS, const Module *M, StringRef Banner, - StringRef Extra = StringRef(), bool Brief = false, +void printIR(raw_ostream &OS, const Module *M, bool ShouldPreserveUseListOrder = false) { - if (Brief) { - OS << M->getName() << '\n'; - return; - } - if (isFunctionInPrintList("*") || forcePrintModuleIR()) { - OS << Banner << Extra << "\n"; M->print(OS, nullptr, ShouldPreserveUseListOrder); } else { for (const auto &F : M->functions()) { - printIR(OS, &F, Banner, Extra); + printIR(OS, &F); } } } -void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C, StringRef Banner, - StringRef Extra = StringRef(), bool Brief = false) { - if (Brief) { - OS << *C << '\n'; - return; - } - - bool BannerPrinted = false; +void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C) { for (const LazyCallGraph::Node &N : *C) { const Function &F = N.getFunction(); if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) { - if (!BannerPrinted) { - OS << Banner << Extra << "\n"; - BannerPrinted = true; - } F.print(OS); } } } -void printIR(raw_ostream &OS, const Loop *L, StringRef Banner, - bool Brief = false) { - if (Brief) { - OS << *L; - return; - } - +void printIR(raw_ostream &OS, const Loop *L) { const Function *F = L->getHeader()->getParent(); if (!isFunctionInPrintList(F->getName())) return; - printLoop(const_cast(*L), OS, std::string(Banner)); + printLoop(const_cast(*L), OS); +} + +bool moduleContainsFilterPrintFunc(const Module &M) { + return any_of(M.functions(), + [](const Function &F) { + return isFunctionInPrintList(F.getName()); + }) || + isFunctionInPrintList("*"); +} + +bool sccContainsFilterPrintFunc(const LazyCallGraph::SCC &C) { + return any_of(C, + [](const LazyCallGraph::Node &N) { + return isFunctionInPrintList(N.getName()); + }) || + isFunctionInPrintList("*"); } /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into /// llvm::Any and does actual print job. void unwrapAndPrint(raw_ostream &OS, Any IR, StringRef Banner, - bool ForceModule = false, bool Brief = false, bool ShouldPreserveUseListOrder = false) { - if (ForceModule) { - if (auto UnwrappedModule = unwrapModule(IR)) - printIR(OS, UnwrappedModule->first, Banner, UnwrappedModule->second, - Brief, ShouldPreserveUseListOrder); + if (forcePrintModuleIR()) { + if (auto UnwrappedModule = unwrapModule(IR)) { + OS << Banner << " " << UnwrappedModule->second << "\n"; + printIR(OS, UnwrappedModule->first, ShouldPreserveUseListOrder); + } return; } if (any_isa(IR)) { const Module *M = any_cast(IR); - assert(M && "module should be valid for printing"); - printIR(OS, M, Banner, "", Brief, ShouldPreserveUseListOrder); + if (!moduleContainsFilterPrintFunc(*M)) + return; + OS << Banner << "\n"; + printIR(OS, M, ShouldPreserveUseListOrder); return; } if (any_isa(IR)) { const Function *F = any_cast(IR); - assert(F && "function should be valid for printing"); - printIR(OS, F, Banner, "", Brief); + OS << Banner << "\n"; + printIR(OS, F); return; } if (any_isa(IR)) { const LazyCallGraph::SCC *C = any_cast(IR); - assert(C && "scc should be valid for printing"); + if (!sccContainsFilterPrintFunc(*C)) + return; std::string Extra = std::string(formatv(" (scc: {0})", C->getName())); - printIR(OS, C, Banner, Extra, Brief); + OS << Banner << " " << Extra << "\n"; + printIR(OS, C); return; } if (any_isa(IR)) { const Loop *L = any_cast(IR); - assert(L && "Loop should be valid for printing"); - printIR(OS, L, Banner, Brief); + OS << Banner << " " << *L << "\n"; + printIR(OS, L); return; } llvm_unreachable("Unknown wrapped IR type"); @@ -531,8 +521,8 @@ raw_string_ostream OS(Output); // use the after banner for all cases so it will match SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID); - unwrapAndPrint(OS, IR, Banner, forcePrintModuleIR(), - /*Brief=*/false, /*ShouldPreserveUseListOrder=*/true); + unwrapAndPrint(OS, IR, Banner, + /*ShouldPreserveUseListOrder=*/true); OS.str(); } @@ -746,7 +736,7 @@ return; SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID); - unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR()); + unwrapAndPrint(dbgs(), IR, Banner); } void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) { @@ -760,7 +750,7 @@ popModuleDesc(PassID); SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID); - unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR()); + unwrapAndPrint(dbgs(), IR, Banner); } void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) { @@ -781,8 +771,9 @@ return; SmallString<20> Banner = - formatv("*** IR Dump After {0} *** invalidated: ", PassID); - printIR(dbgs(), M, Banner, Extra); + formatv("*** IR Dump After {0} *** invalidated: {1}", PassID, Extra); + dbgs() << Banner << "\n"; + printIR(dbgs(), M); } bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) { @@ -848,19 +839,16 @@ static std::string getBisectDescription(Any IR) { if (any_isa(IR)) { const Module *M = any_cast(IR); - assert(M && "module should be valid for printing"); return "module (" + M->getName().str() + ")"; } if (any_isa(IR)) { const Function *F = any_cast(IR); - assert(F && "function should be valid for printing"); return "function (" + F->getName().str() + ")"; } if (any_isa(IR)) { const LazyCallGraph::SCC *C = any_cast(IR); - assert(C && "scc should be valid for printing"); return "SCC " + C->getName(); } @@ -881,6 +869,33 @@ }); } +static std::string getPrintPassDescription(Any IR) { + if (any_isa(IR)) { + const Module *M = any_cast(IR); + return M->getName().str(); + } + + if (any_isa(IR)) { + const Function *F = any_cast(IR); + return F->getName().str(); + } + + if (any_isa(IR)) { + const LazyCallGraph::SCC *C = any_cast(IR); + return C->getName(); + } + + if (any_isa(IR)) { + const Loop *L = any_cast(IR); + std::string S; + raw_string_ostream OS(S); + L->print(OS, /*Verbose*/ false, /*PrintNested*/ false); + return OS.str(); + } + + llvm_unreachable("Unknown wrapped IR type"); +} + void PrintPassInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { if (!DebugLogging) @@ -895,8 +910,8 @@ assert(!isSpecialPass(PassID, SpecialPasses) && "Unexpectedly skipping special pass"); - dbgs() << "Skipping pass: " << PassID << " on "; - unwrapAndPrint(dbgs(), IR, "", false, true); + dbgs() << "Skipping pass: " << PassID << " on " + << getPrintPassDescription(IR) << "\n"; }); PIC.registerBeforeNonSkippedPassCallback( @@ -904,13 +919,13 @@ if (isSpecialPass(PassID, SpecialPasses)) return; - dbgs() << "Running pass: " << PassID << " on "; - unwrapAndPrint(dbgs(), IR, "", false, true); + dbgs() << "Running pass: " << PassID << " on " + << getPrintPassDescription(IR) << "\n"; }); PIC.registerBeforeAnalysisCallback([](StringRef PassID, Any IR) { - dbgs() << "Running analysis: " << PassID << " on "; - unwrapAndPrint(dbgs(), IR, "", false, true); + dbgs() << "Running analysis: " << PassID << " on " + << getPrintPassDescription(IR) << "\n"; }); } diff --git a/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp b/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp --- a/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp +++ b/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp @@ -171,7 +171,7 @@ static void PrintLoopinfo(const MachineLoopInfo &LoopInfo) { for (MachineLoop::iterator iter = LoopInfo.begin(), iterEnd = LoopInfo.end(); iter != iterEnd; ++iter) { - (*iter)->print(dbgs(), 0); + (*iter)->print(dbgs()); } } diff --git a/llvm/test/Other/module-pass-printer.ll b/llvm/test/Other/module-pass-printer.ll --- a/llvm/test/Other/module-pass-printer.ll +++ b/llvm/test/Other/module-pass-printer.ll @@ -8,9 +8,10 @@ ; RUN: opt < %s 2>&1 -forceattrs -disable-output -print-after-all -filter-print-funcs=foo,bar | FileCheck %s -check-prefix=BOTH ; RUN: opt < %s 2>&1 -passes=forceattrs -disable-output -print-after-all -filter-print-funcs=foo,bar | FileCheck %s -check-prefix=BOTH -; Check pass name is not printed if a module doesn't include any function specified in -filter-print-funcs. +; Check pass name is not printed if a module/SCC doesn't include any function specified in -filter-print-funcs. ; RUN: opt < %s 2>&1 -forceattrs -disable-output -print-after-all -filter-print-funcs=baz | FileCheck %s -allow-empty -check-prefix=EMPTY ; RUN: opt < %s 2>&1 -passes=forceattrs -disable-output -print-after-all -filter-print-funcs=baz | FileCheck %s -allow-empty -check-prefix=EMPTY +; RUN: opt < %s 2>&1 -passes=no-op-cgscc -disable-output -print-after-all -filter-print-funcs=baz | FileCheck %s -allow-empty -check-prefix=EMPTY ; Check whole module is printed with user-specified wildcast switch -filter-print-funcs=* or -print-module-scope ; RUN: opt < %s 2>&1 -forceattrs -disable-output -print-after-all | FileCheck %s -check-prefix=ALL @@ -32,6 +33,7 @@ ; BOTH-NOT: ModuleID = ; EMPTY-NOT: IR Dump After {{Force set function attributes|ForceFunctionAttrsPass}} +; EMPTY-NOT: IR Dump After NoOp ; ALL: IR Dump After {{Force set function attributes|ForceFunctionAttrsPass}} ; ALL: ModuleID = diff --git a/llvm/test/Other/print-changed-deleted.ll b/llvm/test/Other/print-changed-deleted.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Other/print-changed-deleted.ll @@ -0,0 +1,5 @@ +; RUN: opt -passes=globaldce < %s -disable-output -print-changed | FileCheck %s --allow-empty + +; CHECK-NOT: @f + +declare void @f()