aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Passes/StandardInstrumentations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Passes/StandardInstrumentations.cpp')
-rw-r--r--llvm/lib/Passes/StandardInstrumentations.cpp84
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>;