diff options
Diffstat (limited to 'llvm/lib/Passes/StandardInstrumentations.cpp')
| -rw-r--r-- | llvm/lib/Passes/StandardInstrumentations.cpp | 84 |
1 files changed, 68 insertions, 16 deletions
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp index c42b1cb26f13..ab9f8bf9c957 100644 --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -27,12 +28,14 @@ #include "llvm/IR/PrintPasses.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Program.h" #include "llvm/Support/Regex.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" #include <unordered_map> #include <unordered_set> @@ -164,6 +167,12 @@ static cl::opt<std::string> DotCfgDir( cl::desc("Generate dot files into specified directory for changed IRs"), cl::Hidden, cl::init("./")); +// An option to print the IR that was being processed when a pass crashes. +static cl::opt<bool> + PrintCrashIR("print-on-crash", + cl::desc("Print the last form of the IR before crash"), + cl::init(false), cl::Hidden); + namespace { // Perform a system based diff between \p Before and \p After, using @@ -439,19 +448,11 @@ const Module *getModuleForComparison(Any IR) { return nullptr; } -} // namespace - -template <typename T> ChangeReporter<T>::~ChangeReporter() { - assert(BeforeStack.empty() && "Problem with Change Printer stack."); -} - -template <typename T> -bool ChangeReporter<T>::isInterestingFunction(const Function &F) { +bool isInterestingFunction(const Function &F) { return isFunctionInPrintList(F.getName()); } -template <typename T> -bool ChangeReporter<T>::isInterestingPass(StringRef PassID) { +bool isInterestingPass(StringRef PassID) { if (isIgnored(PassID)) return false; @@ -462,8 +463,7 @@ bool ChangeReporter<T>::isInterestingPass(StringRef PassID) { // Return true when this is a pass on IR for which printing // of changes is desired. -template <typename T> -bool ChangeReporter<T>::isInteresting(Any IR, StringRef PassID) { +bool isInteresting(Any IR, StringRef PassID) { if (!isInterestingPass(PassID)) return false; if (any_isa<const Function *>(IR)) @@ -471,6 +471,12 @@ bool ChangeReporter<T>::isInteresting(Any IR, StringRef PassID) { return true; } +} // namespace + +template <typename T> ChangeReporter<T>::~ChangeReporter() { + assert(BeforeStack.empty() && "Problem with Change Printer stack."); +} + template <typename T> void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID) { // Always need to place something on the stack because invalidated passes @@ -587,7 +593,7 @@ void TextChangeReporter<T>::handleIgnored(StringRef PassID, std::string &Name) { Out << formatv("*** IR Pass {0} on {1} ignored ***\n", PassID, Name); } -IRChangedPrinter::~IRChangedPrinter() {} +IRChangedPrinter::~IRChangedPrinter() = default; void IRChangedPrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) { if (PrintChanged == ChangePrinter::PrintChangedVerbose || @@ -1186,7 +1192,7 @@ void VerifyInstrumentation::registerCallbacks( if (DebugLogging) dbgs() << "Verifying function " << F->getName() << "\n"; - if (verifyFunction(*F)) + if (verifyFunction(*F, &errs())) report_fatal_error("Broken function found, compilation aborted!"); } else if (any_isa<const Module *>(IR) || any_isa<const LazyCallGraph::SCC *>(IR)) { @@ -1201,13 +1207,13 @@ void VerifyInstrumentation::registerCallbacks( if (DebugLogging) dbgs() << "Verifying module " << M->getName() << "\n"; - if (verifyModule(*M)) + if (verifyModule(*M, &errs())) report_fatal_error("Broken module found, compilation aborted!"); } }); } -InLineChangePrinter::~InLineChangePrinter() {} +InLineChangePrinter::~InLineChangePrinter() = default; void InLineChangePrinter::generateIRRepresentation(Any IR, StringRef PassID, IRDataT<EmptyData> &D) { @@ -2117,6 +2123,51 @@ StandardInstrumentations::StandardInstrumentations( ChangePrinter::PrintChangedDotCfgVerbose), Verify(DebugLogging), VerifyEach(VerifyEach) {} +PrintCrashIRInstrumentation *PrintCrashIRInstrumentation::CrashReporter = + nullptr; + +void PrintCrashIRInstrumentation::reportCrashIR() { dbgs() << SavedIR; } + +void PrintCrashIRInstrumentation::SignalHandler(void *) { + // Called by signal handlers so do not lock here + // Is the PrintCrashIRInstrumentation still alive? + if (!CrashReporter) + return; + + assert(PrintCrashIR && "Did not expect to get here without option set."); + CrashReporter->reportCrashIR(); +} + +PrintCrashIRInstrumentation::~PrintCrashIRInstrumentation() { + if (!CrashReporter) + return; + + assert(PrintCrashIR && "Did not expect to get here without option set."); + CrashReporter = nullptr; +} + +void PrintCrashIRInstrumentation::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + if (!PrintCrashIR || CrashReporter) + return; + + sys::AddSignalHandler(SignalHandler, nullptr); + CrashReporter = this; + + PIC.registerBeforeNonSkippedPassCallback([this](StringRef PassID, Any IR) { + SavedIR.clear(); + raw_string_ostream OS(SavedIR); + OS << formatv("*** Dump of {0}IR Before Last Pass {1}", + llvm::forcePrintModuleIR() ? "Module " : "", PassID); + if (!isInteresting(IR, PassID)) { + OS << " Filtered Out ***\n"; + return; + } + OS << " Started ***\n"; + unwrapAndPrint(OS, IR); + }); +} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC, FunctionAnalysisManager *FAM) { PrintIR.registerCallbacks(PIC); @@ -2132,6 +2183,7 @@ void StandardInstrumentations::registerCallbacks( Verify.registerCallbacks(PIC); PrintChangedDiff.registerCallbacks(PIC); WebsiteChangeReporter.registerCallbacks(PIC); + PrintCrashIR.registerCallbacks(PIC); } template class ChangeReporter<std::string>; |
