@@ -96,11 +96,16 @@ static cl::opt<std::string> DotCfgDir(
9696 cl::desc (" Generate dot files into specified directory for changed IRs" ),
9797 cl::Hidden, cl::init(" ./" ));
9898
99- // An option to print the IR that was being processed when a pass crashes.
100- static cl::opt<bool >
101- PrintCrashIR (" print-on-crash" ,
102- cl::desc (" Print the last form of the IR before crash" ),
103- cl::Hidden);
99+ // Options to print the IR that was being processed when a pass crashes.
100+ static cl::opt<std::string> PrintOnCrashPath (
101+ " print-on-crash-path" ,
102+ cl::desc (" Print the last form of the IR before crash to a file" ),
103+ cl::Hidden);
104+
105+ static cl::opt<bool > PrintOnCrash (
106+ " print-on-crash" ,
107+ cl::desc (" Print the last form of the IR before crash (use -print-on-crash-path to dump to a file)" ),
108+ cl::Hidden);
104109
105110static cl::opt<std::string> OptBisectPrintIRPath (
106111 " opt-bisect-print-ir-path" ,
@@ -2186,47 +2191,59 @@ StandardInstrumentations::StandardInstrumentations(
21862191PrintCrashIRInstrumentation *PrintCrashIRInstrumentation::CrashReporter =
21872192 nullptr ;
21882193
2189- void PrintCrashIRInstrumentation::reportCrashIR () { dbgs () << SavedIR; }
2194+ void PrintCrashIRInstrumentation::reportCrashIR () {
2195+ if (!PrintOnCrashPath.empty ()) {
2196+ std::error_code EC;
2197+ raw_fd_ostream Out (PrintOnCrashPath, EC);
2198+ if (EC)
2199+ report_fatal_error (errorCodeToError (EC));
2200+ Out << SavedIR;
2201+ } else {
2202+ dbgs () << SavedIR;
2203+ }
2204+ }
21902205
21912206void PrintCrashIRInstrumentation::SignalHandler (void *) {
21922207 // Called by signal handlers so do not lock here
21932208 // Is the PrintCrashIRInstrumentation still alive?
21942209 if (!CrashReporter)
21952210 return ;
21962211
2197- assert (PrintCrashIR && " Did not expect to get here without option set." );
2212+ assert ((PrintOnCrash || !PrintOnCrashPath.empty ()) &&
2213+ " Did not expect to get here without option set." );
21982214 CrashReporter->reportCrashIR ();
21992215}
22002216
22012217PrintCrashIRInstrumentation::~PrintCrashIRInstrumentation () {
22022218 if (!CrashReporter)
22032219 return ;
22042220
2205- assert (PrintCrashIR && " Did not expect to get here without option set." );
2221+ assert ((PrintOnCrash || !PrintOnCrashPath.empty ()) &&
2222+ " Did not expect to get here without option set." );
22062223 CrashReporter = nullptr ;
22072224}
22082225
22092226void PrintCrashIRInstrumentation::registerCallbacks (
22102227 PassInstrumentationCallbacks &PIC) {
2211- if (!PrintCrashIR || CrashReporter)
2228+ if ((!PrintOnCrash && PrintOnCrashPath. empty ()) || CrashReporter)
22122229 return ;
22132230
22142231 sys::AddSignalHandler (SignalHandler, nullptr );
22152232 CrashReporter = this ;
22162233
2217- PIC.registerBeforeNonSkippedPassCallback ([&PIC, this ](StringRef PassID,
2218- Any IR) {
2219- SavedIR.clear ();
2220- raw_string_ostream OS (SavedIR);
2221- OS << formatv (" *** Dump of {0}IR Before Last Pass {1}" ,
2222- llvm::forcePrintModuleIR () ? " Module " : " " , PassID);
2223- if (!isInteresting (IR, PassID, PIC.getPassNameForClassName (PassID))) {
2224- OS << " Filtered Out ***\n " ;
2225- return ;
2226- }
2227- OS << " Started ***\n " ;
2228- unwrapAndPrint (OS, IR);
2229- });
2234+ PIC.registerBeforeNonSkippedPassCallback (
2235+ [&PIC, this ](StringRef PassID, Any IR) {
2236+ SavedIR.clear ();
2237+ raw_string_ostream OS (SavedIR);
2238+ OS << formatv (" *** Dump of {0}IR Before Last Pass {1}" ,
2239+ llvm::forcePrintModuleIR () ? " Module " : " " , PassID);
2240+ if (!isInteresting (IR, PassID, PIC.getPassNameForClassName (PassID))) {
2241+ OS << " Filtered Out ***\n " ;
2242+ return ;
2243+ }
2244+ OS << " Started ***\n " ;
2245+ unwrapAndPrint (OS, IR);
2246+ });
22302247}
22312248
22322249void StandardInstrumentations::registerCallbacks (
0 commit comments