diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -152,7 +152,7 @@ // 8. To compare two IR representations (of type \p T). template class ChangeReporter { protected: - ChangeReporter() {} + ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {} public: virtual ~ChangeReporter(); @@ -204,6 +204,9 @@ std::vector BeforeStack; // Is this the first IR seen? bool InitialIR = true; + + // Run in verbose mode, printing everything? + const bool VerboseMode; }; // An abstract template base class that handles printing banners and @@ -211,7 +214,7 @@ template class TextChangeReporter : public ChangeReporter { protected: - TextChangeReporter(); + TextChangeReporter(bool Verbose); // Print a module dump of the first IR that is changed. void handleInitialIR(Any IR) override; @@ -235,7 +238,8 @@ // included in this representation but it is massaged before reporting. class IRChangedPrinter : public TextChangeReporter { public: - IRChangedPrinter() {} + IRChangedPrinter(bool VerboseMode) + : TextChangeReporter(VerboseMode) {} ~IRChangedPrinter() override; void registerCallbacks(PassInstrumentationCallbacks &PIC); @@ -274,9 +278,7 @@ 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); 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 @@ -64,10 +64,17 @@ // can be combined, allowing only changed IRs for certain passes on certain // functions to be reported in different formats, with the rest being // reported as filtered out. The -print-before-changed option will print -// the IR as it was before each pass that changed it. -static cl::opt PrintChanged("print-changed", - cl::desc("Print changed IRs"), - cl::init(false), cl::Hidden); +// the IR as it was before each pass that changed it. The optional +// value of quiet will only report when the IR changes, suppressing +// all other messages, including the initial IR. +enum ChangePrinter { NoChangePrinter, PrintChangedVerbose, PrintChangedQuiet }; +static cl::opt PrintChanged( + "print-changed", cl::desc("Print changed IRs"), cl::Hidden, + cl::ValueOptional, cl::init(NoChangePrinter), + cl::values(clEnumValN(PrintChangedQuiet, "quiet", "Run in quiet mode"), + // Sentinel value for unspecified option. + clEnumValN(PrintChangedVerbose, "", ""))); + // An option that supports the -print-changed option. See // the description for -print-changed for an explanation of the use // of this option. Note that this option has no effect without -print-changed. @@ -287,7 +294,8 @@ // Is this the initial IR? if (InitialIR) { InitialIR = false; - handleInitialIR(IR); + if (VerboseMode) + handleInitialIR(IR); } // Save the IR representation on the stack. @@ -311,11 +319,13 @@ if (Name == "") Name = " (module)"; - if (isIgnored(PassID)) - handleIgnored(PassID, Name); - else if (!isInteresting(IR, PassID)) - handleFiltered(PassID, Name); - else { + if (isIgnored(PassID)) { + if (VerboseMode) + handleIgnored(PassID, Name); + } else if (!isInteresting(IR, PassID)) { + if (VerboseMode) + handleFiltered(PassID, Name); + } else { // Get the before rep from the stack IRUnitT &Before = BeforeStack.back(); // Create the after rep @@ -323,9 +333,10 @@ generateIRRepresentation(IR, PassID, After); // Was there a change in IR? - if (same(Before, After)) - omitAfter(PassID, Name); - else + if (same(Before, After)) { + if (VerboseMode) + omitAfter(PassID, Name); + } else handleAfter(PassID, Name, Before, After, IR); } BeforeStack.pop_back(); @@ -339,7 +350,8 @@ // a pass for a filtered function is invalidated since we do not // get the IR in the call. Also, the output is just alternate // forms of the banner anyway. - handleInvalidated(PassID); + if (VerboseMode) + handleInvalidated(PassID); BeforeStack.pop_back(); } @@ -360,8 +372,8 @@ } template -TextChangeReporter::TextChangeReporter() - : ChangeReporter(), Out(dbgs()) {} +TextChangeReporter::TextChangeReporter(bool Verbose) + : ChangeReporter(Verbose), Out(dbgs()) {} template void TextChangeReporter::handleInitialIR(Any IR) { @@ -403,7 +415,7 @@ IRChangedPrinter::~IRChangedPrinter() {} void IRChangedPrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) { - if (PrintChanged) + if (PrintChanged != NoChangePrinter) TextChangeReporter::registerRequiredCallbacks(PIC); } @@ -856,6 +868,12 @@ }); } +StandardInstrumentations::StandardInstrumentations(bool DebugLogging, + bool VerifyEach) + : PrintPass(DebugLogging), OptNone(DebugLogging), + PrintChangedIR(PrintChanged != PrintChangedQuiet), Verify(DebugLogging), + VerifyEach(VerifyEach) {} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); diff --git a/llvm/test/Other/change-printer.ll b/llvm/test/Other/change-printer.ll --- a/llvm/test/Other/change-printer.ll +++ b/llvm/test/Other/change-printer.ll @@ -5,6 +5,9 @@ ; Simple functionality check. ; RUN: opt -S -print-changed -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-SIMPLE ; +; Simple functionality check. +; RUN: opt -S -print-changed= -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-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 -passes=instsimplify -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-FUNC-FILTER @@ -44,6 +47,53 @@ ; 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=quiet functionality +; +; Simple functionality check. +; RUN: opt -S -print-changed=quiet -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-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=quiet -passes=instsimplify -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FUNC-FILTER +; +; Check that the reporting of IRs respects -print-module-scope +; RUN: opt -S -print-changed=quiet -passes=instsimplify -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-PRINT-MOD-SCOPE +; +; Check that the reporting of IRs respects -print-module-scope +; RUN: opt -S -print-changed=quiet -passes=instsimplify -filter-print-funcs=f -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FUNC-FILTER-MOD-SCOPE +; +; Check that reporting of multiple functions happens +; RUN: opt -S -print-changed=quiet -passes=instsimplify -filter-print-funcs="f,g" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FILTER-MULT-FUNC +; +; Check that the reporting of IRs respects -filter-passes +; RUN: opt -S -print-changed=quiet -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FILTER-PASSES-NONE --allow-empty +; +; Check that the reporting of IRs respects -filter-passes with multiple passes +; RUN: opt -S -print-changed=quiet -passes="instsimplify" -filter-passes="NoOpFunctionPass,InstSimplifyPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FILTER-PASSES +; +; Check that the reporting of IRs respects -filter-passes with multiple passes +; RUN: opt -S -print-changed=quiet -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FILTER-MULT-PASSES +; +; Check that the reporting of IRs respects both -filter-passes and -filter-print-funcs +; RUN: opt -S -print-changed=quiet -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-FILTER-FUNC-PASSES +; +; Check that the reporting of IRs respects -filter-passes, -filter-print-funcs and -print-module-scope +; RUN: opt -S -print-changed=quiet -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-QUIET-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=quiet -passes="instsimplify,instsimplify" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-QUIET-MULT-PASSES-FILTER-FUNC +; +; Simple print-before-changed functionality check. +; RUN: opt -S -print-changed=quiet -print-before-changed -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-SIMPLE-BEFORE-QUIET +; +; Check print-before-changed obeys the function filtering +; RUN: opt -S -print-changed=quiet -print-before-changed -passes=instsimplify -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-FUNC-FILTER-BEFORE-QUIET +; +; Check that the reporting of IRs with -print-before-changed respects -print-module-scope +; RUN: opt -S -print-changed=quiet -print-before-changed -passes=instsimplify -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET +; define i32 @g() { entry: @@ -173,3 +223,104 @@ ; 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-QUIET-SIMPLE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-SIMPLE: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-QUIET-SIMPLE-NEXT: define i32 @g() +; CHECK-QUIET-SIMPLE-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-QUIET-SIMPLE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-SIMPLE-NEXT: define i32 @f() +; CHECK-QUIET-SIMPLE-NOT: *** IR + +; CHECK-QUIET-FUNC-FILTER-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FUNC-FILTER: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FUNC-FILTER-NEXT: define i32 @f() +; CHECK-QUIET-FUNC-FILTER-NOT: *** IR + +; CHECK-QUIET-PRINT-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-PRINT-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-QUIET-PRINT-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-QUIET-PRINT-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-PRINT-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-QUIET-PRINT-MOD-SCOPE-NOT: *** IR + +; CHECK-QUIET-FUNC-FILTER-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FUNC-FILTER-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FUNC-FILTER-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-QUIET-FUNC-FILTER-MOD-SCOPE-NOT: *** IR + +; CHECK-QUIET-FILTER-MULT-FUNC-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-MULT-FUNC: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-QUIET-FILTER-MULT-FUNC-NEXT: define i32 @g() +; CHECK-QUIET-FILTER-MULT-FUNC: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FILTER-MULT-FUNC-NEXT: define i32 @f() +; CHECK-QUIET-FILTER-MULT-FUNC-NOT: *** IR + +; CHECK-QUIET-FILTER-PASSES-NONE-NOT: *** IR + +; CHECK-QUIET-FILTER-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-PASSES: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-QUIET-FILTER-PASSES-NEXT: define i32 @g() +; CHECK-QUIET-FILTER-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FILTER-PASSES-NEXT: define i32 @f() +; CHECK-QUIET-FILTER-PASSES-NOT: *** IR + +; CHECK-QUIET-FILTER-MULT-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-MULT-PASSES: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-QUIET-FILTER-MULT-PASSES-NEXT: define i32 @g() +; CHECK-QUIET-FILTER-MULT-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-MULT-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FILTER-MULT-PASSES-NEXT: define i32 @f() +; CHECK-QUIET-FILTER-MULT-PASSES-NOT: *** IR + +; CHECK-QUIET-FILTER-FUNC-PASSES-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-FUNC-PASSES: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FILTER-FUNC-PASSES-NEXT: define i32 @f() +; CHECK-QUIET-FILTER-FUNC-PASSES-NOT: *** IR + +; CHECK-QUIET-FILTER-FUNC-PASSES-MOD-SCOPE-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-FILTER-FUNC-PASSES-MOD-SCOPE: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-FILTER-FUNC-PASSES-MOD-SCOPE-NEXT: ModuleID = {{.+}} +; CHECK-QUIET-FILTER-FUNC-PASSES-MOD-SCOPE-NOT: *** IR + +; CHECK-QUIET-MULT-PASSES-FILTER-FUNC-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-QUIET-MULT-PASSES-FILTER-FUNC: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-QUIET-MULT-PASSES-FILTER-FUNC-NEXT: define i32 @f() +; CHECK-QUIET-MULT-PASSES-FILTER-FUNC-NOT: *** IR + +; CHECK-SIMPLE-BEFORE-QUIET-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-SIMPLE-BEFORE-QUIET: *** IR Dump Before InstSimplifyPass *** (function: g) +; CHECK-SIMPLE-BEFORE-QUIET-NEXT: define i32 @g() +; CHECK-SIMPLE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-SIMPLE-BEFORE-QUIET: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-SIMPLE-BEFORE-QUIET-NEXT: define i32 @g() +; CHECK-SIMPLE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-SIMPLE-BEFORE-QUIET: *** IR Dump Before InstSimplifyPass *** (function: f) +; CHECK-SIMPLE-BEFORE-QUIET-NEXT: define i32 @f() +; CHECK-SIMPLE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-SIMPLE-BEFORE-QUIET: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-SIMPLE-BEFORE-QUIET-NEXT: define i32 @f() +; CHECK-SIMPLE-BEFORE-QUIET-NOT: *** IR + +; CHECK-FUNC-FILTER-BEFORE-QUIET-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-FUNC-FILTER-BEFORE-QUIET: *** IR Dump Before InstSimplifyPass *** (function: f) +; CHECK-FUNC-FILTER-BEFORE-QUIET-NEXT: define i32 @f() +; CHECK-FUNC-FILTER-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-FUNC-FILTER-BEFORE-QUIET: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-FUNC-FILTER-BEFORE-QUIET-NEXT: define i32 @f() +; CHECK-FUNC-FILTER-BEFORE-QUIET-NOT: *** IR + +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NOT: *** IR Dump {{.*(At Start:|no change|ignored|filtered out)}} *** +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET: *** IR Dump Before InstSimplifyPass *** (function: g) +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NEXT: ModuleID = {{.+}} +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET: *** IR Dump After InstSimplifyPass *** (function: g) +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NEXT: ModuleID = {{.+}} +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET: *** IR Dump Before InstSimplifyPass *** (function: f) +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NEXT: ModuleID = {{.+}} +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NOT: *** IR Dump {{.*(no change|ignored|filtered out)}} *** +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET: *** IR Dump After InstSimplifyPass *** (function: f) +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NEXT: ModuleID = {{.+}} +; CHECK-PRINT-MOD-SCOPE-BEFORE-QUIET-NOT: *** IR