Index: llvm/include/llvm/Passes/StandardInstrumentations.h =================================================================== --- llvm/include/llvm/Passes/StandardInstrumentations.h +++ llvm/include/llvm/Passes/StandardInstrumentations.h @@ -231,7 +231,7 @@ // included in this representation but it is massaged before reporting. class IRChangedPrinter : public TextChangeReporter { public: - IRChangedPrinter() {} + IRChangedPrinter(bool PrintBefore) : PrintBefore(PrintBefore) {} ~IRChangedPrinter() override; void registerCallbacks(PassInstrumentationCallbacks &PIC); @@ -245,6 +245,26 @@ Any) override; // Called to compare the before and after representations of the IR. bool same(const std::string &Before, const std::string &After) override; + + bool PrintBefore; +}; + +// A change printer that only reports the before and after IR representations +// when the IR changes, suppressing all other messages, including the +// initial IR. Normal filtering options for change reporters apply. +class IRChangedOnlyPrinter : public IRChangedPrinter { +public: + IRChangedOnlyPrinter() : IRChangedPrinter(true) {} + ~IRChangedOnlyPrinter() override; + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +protected: + // Suppress these messages + void handleInitialIR(Any IR) override; + void omitAfter(StringRef PassID, std::string &Name) override; + void handleInvalidated(StringRef PassID) override; + void handleFiltered(StringRef PassID, std::string &Name) override; + void handleIgnored(StringRef PassID, std::string &Name) override; }; class VerifyInstrumentation { @@ -265,14 +285,13 @@ OptBisectInstrumentation OptBisect; PreservedCFGCheckerInstrumentation PreservedCFGChecker; IRChangedPrinter PrintChangedIR; + IRChangedOnlyPrinter PrintChangedIROnly; VerifyInstrumentation Verify; bool VerifyEach; public: - StandardInstrumentations(bool DebugLogging, bool VerifyEach = false) - : PrintPass(DebugLogging), OptNone(DebugLogging), Verify(DebugLogging), - VerifyEach(VerifyEach) {} + StandardInstrumentations(bool DebugLogging, bool VerifyEach = false); void registerCallbacks(PassInstrumentationCallbacks &PIC); Index: llvm/lib/Passes/StandardInstrumentations.cpp =================================================================== --- llvm/lib/Passes/StandardInstrumentations.cpp +++ llvm/lib/Passes/StandardInstrumentations.cpp @@ -82,6 +82,15 @@ PrintChangedBefore("print-before-changed", cl::desc("Print before passes that change them"), cl::init(false), cl::Hidden); +// A change printer that only prints the before and after version of the IR +// when the IR changes. All messages about non-reporting passes and the +// initial IR are suppressed. Output is modified by the usual modifying +// options (filter-print-funcs, filter-passes, print-module-scope). +static cl::opt + PrintChangedOnly("print-changed-only", + cl::desc("Only print before and after passes that" + "change them"), + cl::init(false), cl::Hidden); namespace { @@ -426,7 +435,7 @@ AfterRef.take_until([](char C) -> bool { return C == '\n'; }); // Report the IR before the changes when requested. - if (PrintChangedBefore) { + if (PrintBefore) { Out << "*** IR Dump Before" << Banner.substr(17); // LazyCallGraph::SCC already has "(scc:..." in banner so only add // in the name if it isn't already there. @@ -451,6 +460,19 @@ return S1 == S2; } +IRChangedOnlyPrinter::~IRChangedOnlyPrinter() {} +void IRChangedOnlyPrinter::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + if (PrintChangedOnly) + TextChangeReporter::registerRequiredCallbacks(PIC); +} +// Suppress these messages for this change reporter. +void IRChangedOnlyPrinter::handleInitialIR(Any) {} +void IRChangedOnlyPrinter::omitAfter(StringRef, std::string &) {} +void IRChangedOnlyPrinter::handleInvalidated(StringRef) {} +void IRChangedOnlyPrinter::handleFiltered(StringRef, std::string &) {} +void IRChangedOnlyPrinter::handleIgnored(StringRef, std::string &) {} + PrintIRInstrumentation::~PrintIRInstrumentation() { assert(ModuleDescStack.empty() && "ModuleDescStack is not empty at exit"); } @@ -832,6 +854,12 @@ }); } +StandardInstrumentations::StandardInstrumentations(bool DebugLogging, + bool VerifyEach) + : PrintPass(DebugLogging), OptNone(DebugLogging), + PrintChangedIR(PrintChangedBefore), Verify(DebugLogging), + VerifyEach(VerifyEach) {} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); @@ -841,6 +869,7 @@ OptBisect.registerCallbacks(PIC); PreservedCFGChecker.registerCallbacks(PIC); PrintChangedIR.registerCallbacks(PIC); + PrintChangedIROnly.registerCallbacks(PIC); if (VerifyEach) Verify.registerCallbacks(PIC); } Index: llvm/test/Other/change-printer.ll =================================================================== --- llvm/test/Other/change-printer.ll +++ llvm/test/Other/change-printer.ll @@ -44,6 +44,44 @@ ; Check that the reporting of IRs with -print-before-changed respects -print-module-scope ; RUN: opt -S -print-changed -print-before-changed -passes=instsimplify -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-PRINT-MOD-SCOPE-BEFORE ; +; Simple checks of -print-changed-only functionality +; +; Simple functionality check. +; RUN: opt -S -print-changed-only -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-SIMPLE +; +; Check that only the passes that change the IR are printed and that the +; others (including g) are filtered out. +; RUN: opt -S -print-changed-only -passes=instsimplify -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FUNC-FILTER +; +; Check that the reporting of IRs respects -print-module-scope +; RUN: opt -S -print-changed-only -passes=instsimplify -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE +; +; Check that the reporting of IRs respects -print-module-scope +; RUN: opt -S -print-changed-only -passes=instsimplify -filter-print-funcs=f -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FUNC-FILTER-MOD-SCOPE +; +; Check that reporting of multiple functions happens +; RUN: opt -S -print-changed-only -passes=instsimplify -filter-print-funcs="f,g" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-MULT-FUNC +; +; Check that the reporting of IRs respects -filter-passes +; RUN: opt -S -print-changed-only -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-PASSES-NONE --allow-empty +; +; Check that the reporting of IRs respects -filter-passes with multiple passes +; RUN: opt -S -print-changed-only -passes="instsimplify" -filter-passes="NoOpFunctionPass,InstSimplifyPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-PASSES +; +; Check that the reporting of IRs respects -filter-passes with multiple passes +; RUN: opt -S -print-changed-only -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-MULT-PASSES +; +; Check that the reporting of IRs respects both -filter-passes and -filter-print-funcs +; RUN: opt -S -print-changed-only -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES +; +; Check that the reporting of IRs respects -filter-passes, -filter-print-funcs and -print-module-scope +; RUN: opt -S -print-changed-only -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" -filter-print-funcs=f -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-MOD-SCOPE +; +; Check that repeated passes that change the IR are printed and that the +; others (including g) are filtered out. Note that the second time +; instsimplify is run on f, it does not change the IR +; RUN: opt -S -print-changed-only -passes="instsimplify,instsimplify" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-CHANGED-ONLY-MULT-PASSES-FILTER-FUNC +; define i32 @g() { entry: @@ -173,3 +211,68 @@ ; CHECK-PRINT-MOD-SCOPE-BEFORE-NEXT: ModuleID = {{.+}} ; CHECK-PRINT-MOD-SCOPE-BEFORE: *** IR Dump After InstSimplifyPass *** (function: f) ; CHECK-PRINT-MOD-SCOPE-BEFORE-NEXT: ModuleID = {{.+}} + +; CHECK-CHANGED-ONLY-SIMPLE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-SIMPLE: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-CHANGED-ONLY-SIMPLE-NEXT: define i32 @g() +; CHECK-CHANGED-ONLY-SIMPLE-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-SIMPLE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-SIMPLE-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-SIMPLE-NOT: *** IR + +; CHECK-CHANGED-ONLY-FUNC-FILTER-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FUNC-FILTER: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FUNC-FILTER-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-FUNC-FILTER-NOT: *** IR + +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-CHANGED-ONLY-PRINT-MOD-SCOPE-NOT: *** IR + +; CHECK-CHANGED-ONLY-FUNC-FILTER-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FUNC-FILTER-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FUNC-FILTER-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-CHANGED-ONLY-FUNC-FILTER-MOD-SCOPE-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC-NEXT: define i32 @g() +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-FILTER-MULT-FUNC-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-PASSES-NONE-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-PASSES: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-CHANGED-ONLY-FILTER-PASSES-NEXT: define i32 @g() +; CHECK-CHANGED-ONLY-FILTER-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FILTER-PASSES-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-FILTER-PASSES-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES-NEXT: define i32 @g() +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-FILTER-MULT-PASSES-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-NOT: *** IR + +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-CHANGED-ONLY-FILTER-FUNC-PASSES-MOD-SCOPE-NOT: *** IR + +; CHECK-CHANGED-ONLY-MULT-PASSES-FILTER-FUNC-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-CHANGED-ONLY-MULT-PASSES-FILTER-FUNC: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-CHANGED-ONLY-MULT-PASSES-FILTER-FUNC-NEXT: define i32 @f() +; CHECK-CHANGED-ONLY-MULT-PASSES-FILTER-FUNC-NOT: *** IR