Index: llvm/include/llvm/Passes/StandardInstrumentations.h =================================================================== --- llvm/include/llvm/Passes/StandardInstrumentations.h +++ llvm/include/llvm/Passes/StandardInstrumentations.h @@ -146,12 +146,12 @@ // 6. When a pass is run on an IR that is not interesting (based on options). // 7. When a pass is ignored (pass manager or adapter pass). // 8. To compare two IR representations (of type \p T). -template class ChangePrinter { +template class ChangeReporter { protected: - ChangePrinter() {} + ChangeReporter() {} public: - virtual ~ChangePrinter(); + virtual ~ChangeReporter(); // Determine if this pass/IR is interesting and if so, save the IR // otherwise it is left on the stack without data. @@ -162,6 +162,20 @@ void handleInvalidatedPass(StringRef PassID); protected: + // Register required callbacks. + void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC); + + // Return true when this is a defined function for which printing + // of changes is desired. + bool isInterestingFunction(const Function &F); + + // Return true when this is a pass for which printing of changes is desired. + bool isInterestingPass(StringRef PassID); + + // Return true when this is a pass on IR for which printing + // of changes is desired. + bool isInteresting(Any IR, StringRef PassID); + // Called on the first IR processed. virtual void handleInitialIR(Any IR) = 0; // Called before and after a pass to get the representation of the IR. @@ -188,38 +202,49 @@ bool InitialIR = true; }; +// An abstract template base class that handles printing banners and +// reporting when things have not changed or are filtered out. +template +class TextChangeReporter : public ChangeReporter { +protected: + TextChangeReporter(); + + // Print a module dump of the first IR that is changed. + void handleInitialIR(Any IR) override; + // Report that the IR was omitted because it did not change. + void omitAfter(StringRef PassID, std::string &Name) override; + // Report that the pass was invalidated. + void handleInvalidated(StringRef PassID) override; + // Report that the IR was filtered out. + void handleFiltered(StringRef PassID, std::string &Name) override; + // Report that the pass was ignored. + void handleIgnored(StringRef PassID, std::string &Name) override; + // Make substitutions in \p S suitable for reporting changes + // after the pass and then print it. + + raw_ostream &Out; +}; + // A change printer based on the string representation of the IR as created // by unwrapAndPrint. The string representation is stored in a std::string // to preserve it as the IR changes in each pass. Note that the banner is // included in this representation but it is massaged before reporting. -class IRChangePrinter : public ChangePrinter { +class IRChangedPrinter : public TextChangeReporter { public: - IRChangePrinter(); - ~IRChangePrinter() override; + IRChangedPrinter() {} + ~IRChangedPrinter() override; void registerCallbacks(PassInstrumentationCallbacks &PIC); protected: - // Called on the first IR processed. - void handleInitialIR(Any IR) override; // Called before and after a pass to get the representation of the IR. void generateIRRepresentation(Any IR, StringRef PassID, std::string &Output) override; - // Called when the pass is not iteresting. - void omitAfter(StringRef PassID, std::string &Name) override; // Called when an interesting IR has changed. void handleAfter(StringRef PassID, std::string &Name, const std::string &Before, const std::string &After, Any) override; - // Called when an interesting pass is invalidated. - void handleInvalidated(StringRef PassID) override; - // Called when the IR or pass is not interesting. - void handleFiltered(StringRef PassID, std::string &Name) override; - // Called when an ignored pass is encountered. - void handleIgnored(StringRef PassID, std::string &Name) override; // Called to compare the before and after representations of the IR. bool same(const std::string &Before, const std::string &After) override; - - raw_ostream &Out; }; class VerifyInstrumentation { @@ -239,7 +264,7 @@ OptNoneInstrumentation OptNone; OptBisectInstrumentation OptBisect; PreservedCFGCheckerInstrumentation PreservedCFGChecker; - IRChangePrinter PrintChangedIR; + IRChangedPrinter PrintChangedIR; VerifyInstrumentation Verify; bool VerifyEach; @@ -253,6 +278,10 @@ TimePassesHandler &getTimePasses() { return TimePasses; } }; + +extern template class ChangeReporter; +extern template class TextChangeReporter; + } // namespace llvm #endif Index: llvm/lib/Passes/StandardInstrumentations.cpp =================================================================== --- llvm/lib/Passes/StandardInstrumentations.cpp +++ llvm/lib/Passes/StandardInstrumentations.cpp @@ -241,14 +241,20 @@ {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}); } -// Return true when this is a defined function for which printing -// of changes is desired. -bool isInterestingFunction(const Function &F) { +} // namespace + +template +ChangeReporter::~ChangeReporter() { + assert(BeforeStack.empty() && "Problem with Change Printer stack."); +} + +template +bool ChangeReporter::isInterestingFunction(const Function &F) { return llvm::isFunctionInPrintList(F.getName()); } -// Return true when this is a pass for which printing of changes is desired. -bool isInterestingPass(StringRef PassID) { +template +bool ChangeReporter::isInterestingPass(StringRef PassID) { if (isIgnored(PassID)) return false; @@ -259,7 +265,8 @@ // Return true when this is a pass on IR for which printing // of changes is desired. -bool isInteresting(Any IR, StringRef PassID) { +template +bool ChangeReporter::isInteresting(Any IR, StringRef PassID) { if (!isInterestingPass(PassID)) return false; if (any_isa(IR)) @@ -267,10 +274,8 @@ return true; } -} // namespace - template -void ChangePrinter::saveIRBeforePass(Any IR, StringRef PassID) { +void ChangeReporter::saveIRBeforePass(Any IR, StringRef PassID) { // Always need to place something on the stack because invalidated passes // are not given the IR so it cannot be determined whether the pass was for // something that was filtered out. @@ -290,7 +295,7 @@ } template -void ChangePrinter::handleIRAfterPass(Any IR, StringRef PassID) { +void ChangeReporter::handleIRAfterPass(Any IR, StringRef PassID) { assert(!BeforeStack.empty() && "Unexpected empty stack encountered."); std::string Name; @@ -302,7 +307,7 @@ if (auto UM = unwrapModule(IR)) Name = UM->second; } - if (Name.empty()) + if (Name == "") Name = " (module)"; if (isIgnored(PassID)) @@ -326,7 +331,7 @@ } template -void ChangePrinter::handleInvalidatedPass(StringRef PassID) { +void ChangeReporter::handleInvalidatedPass(StringRef PassID) { assert(!BeforeStack.empty() && "Unexpected empty stack encountered."); // Always flag it as invalidated as we cannot determine when @@ -337,18 +342,9 @@ BeforeStack.pop_back(); } -template ChangePrinter::~ChangePrinter() { - assert(BeforeStack.empty() && "Problem with Change Printer stack."); -} - -IRChangePrinter::IRChangePrinter() : Out(dbgs()) {} - -IRChangePrinter::~IRChangePrinter() {} - -void IRChangePrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) { - if (!PrintChanged) - return; - +template +void ChangeReporter::registerRequiredCallbacks( + PassInstrumentationCallbacks &PIC) { PIC.registerBeforeNonSkippedPassCallback( [this](StringRef P, Any IR) { saveIRBeforePass(IR, P); }); @@ -362,7 +358,12 @@ }); } -void IRChangePrinter::handleInitialIR(Any IR) { +template +TextChangeReporter::TextChangeReporter() + : ChangeReporter(), Out(dbgs()) {} + +template +void TextChangeReporter::handleInitialIR(Any IR) { // Always print the module. // Unwrap and print directly to avoid filtering problems in general routines. auto UnwrappedModule = unwrapModule(IR, /*Force=*/true); @@ -372,24 +373,53 @@ /*ShouldPreserveUseListOrder=*/true); } -void IRChangePrinter::generateIRRepresentation(Any IR, StringRef PassID, - std::string &Output) { +template +void TextChangeReporter::omitAfter(StringRef PassID, + std::string &Name) { + Out << formatv("*** IR Dump After {0}{1} omitted because no change ***\n", + PassID, Name); +} + +template +void TextChangeReporter::handleInvalidated(StringRef PassID) { + Out << formatv("*** IR Pass {0} invalidated ***\n", PassID); +} + +template +void TextChangeReporter::handleFiltered(StringRef PassID, + std::string &Name) { + SmallString<20> Banner = + formatv("*** IR Dump After {0}{1} filtered out ***\n", PassID, Name); + Out << Banner; +} + +template +void TextChangeReporter::handleIgnored(StringRef PassID, + std::string &Name) { + Out << formatv("*** IR Pass {0}{1} ignored ***\n", PassID, Name); +} + +IRChangedPrinter::~IRChangedPrinter() {} + +void IRChangedPrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) { + if (PrintChanged) + TextChangeReporter::registerRequiredCallbacks(PIC); +} + +void IRChangedPrinter::generateIRRepresentation(Any IR, StringRef PassID, + std::string &Output) { 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, llvm::forcePrintModuleIR(), + unwrapAndPrint(OS, IR, Banner, forcePrintModuleIR(), /*Brief=*/false, /*ShouldPreserveUseListOrder=*/true); - OS.str(); -} -void IRChangePrinter::omitAfter(StringRef PassID, std::string &Name) { - Out << formatv("*** IR Dump After {0}{1} omitted because no change ***\n", - PassID, Name); + OS.str(); } -void IRChangePrinter::handleAfter(StringRef PassID, std::string &Name, - const std::string &Before, - const std::string &After, Any) { +void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name, + const std::string &Before, + const std::string &After, Any) { assert(After.find("*** IR Dump") == 0 && "Unexpected banner format."); StringRef AfterRef = After; StringRef Banner = @@ -417,23 +447,8 @@ Out << After.substr(Banner.size()); } -void IRChangePrinter::handleInvalidated(StringRef PassID) { - Out << formatv("*** IR Pass {0} invalidated ***\n", PassID); -} - -void IRChangePrinter::handleFiltered(StringRef PassID, std::string &Name) { - SmallString<20> Banner = - formatv("*** IR Dump After {0}{1} filtered out ***\n", PassID, Name); - Out << Banner; -} - -void IRChangePrinter::handleIgnored(StringRef PassID, std::string &Name) { - Out << formatv("*** IR Pass {0}{1} ignored ***\n", PassID, Name); -} - -bool IRChangePrinter::same(const std::string &Before, - const std::string &After) { - return Before == After; +bool IRChangedPrinter::same(const std::string &S1, const std::string &S2) { + return S1 == S2; } PrintIRInstrumentation::~PrintIRInstrumentation() { @@ -829,3 +844,10 @@ if (VerifyEach) Verify.registerCallbacks(PIC); } + +namespace llvm { + +template class ChangeReporter; +template class TextChangeReporter; + +} // namespace llvm