Index: llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h =================================================================== --- llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h +++ llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h @@ -38,10 +38,10 @@ virtual ~BenchmarkRunner(); - InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration, - unsigned NumRepetitions, - const SnippetRepetitor &Repetitor, - bool DumpObjectToDisk) const; + Expected + runConfiguration(const BenchmarkCode &Configuration, unsigned NumRepetitions, + const SnippetRepetitor &Repetitor, + bool DumpObjectToDisk) const; // Scratch space to run instructions that touch memory. struct ScratchSpace { Index: llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp =================================================================== --- llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -52,7 +52,7 @@ CounterName = CounterName.trim(); pfm::PerfEvent PerfEvent(CounterName); if (!PerfEvent.valid()) - report_fatal_error( + return make_error( Twine("invalid perf event '").concat(CounterName).concat("'")); pfm::Counter Counter(PerfEvent); Scratch->clear(); @@ -67,7 +67,7 @@ CrashRecoveryContext::Disable(); // FIXME: Better diagnosis. if (Crashed) - return make_error("snippet crashed while running"); + return make_error("snippet crashed while running"); } CounterValue += Counter.read(); } @@ -79,7 +79,7 @@ }; } // namespace -InstructionBenchmark BenchmarkRunner::runConfiguration( +Expected BenchmarkRunner::runConfiguration( const BenchmarkCode &BC, unsigned NumRepetitions, const SnippetRepetitor &Repetitor, bool DumpObjectToDisk) const { InstructionBenchmark InstrBenchmark; @@ -138,6 +138,8 @@ Scratch.get()); auto Measurements = runMeasurements(Executor); if (Error E = Measurements.takeError()) { + if (!E.isA()) + return std::move(E); InstrBenchmark.Error = toString(std::move(E)); return InstrBenchmark; } Index: llvm/tools/llvm-exegesis/lib/Error.h =================================================================== --- llvm/tools/llvm-exegesis/lib/Error.h +++ llvm/tools/llvm-exegesis/lib/Error.h @@ -35,6 +35,20 @@ std::string Msg; }; +// A class representing failures that happened during snippet execution. +// Instead of terminating the program crashes are logged into the output. +class SnippetCrash : public ErrorInfo { +public: + static char ID; + SnippetCrash(const Twine&S) : Msg(S.str()) {} + + void log(raw_ostream &OS) const override; + + std::error_code convertToErrorCode() const override; +private: + std::string Msg; +}; + } // namespace exegesis } // namespace llvm Index: llvm/tools/llvm-exegesis/lib/Error.cpp =================================================================== --- llvm/tools/llvm-exegesis/lib/Error.cpp +++ llvm/tools/llvm-exegesis/lib/Error.cpp @@ -21,5 +21,15 @@ return inconvertibleErrorCode(); } +char SnippetCrash::ID; + +void SnippetCrash::log(raw_ostream &OS) const { + OS << Msg; +} + +std::error_code SnippetCrash::convertToErrorCode() const { + return inconvertibleErrorCode(); +} + } // namespace exegesis } // namespace llvm Index: llvm/tools/llvm-exegesis/llvm-exegesis.cpp =================================================================== --- llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -309,8 +309,8 @@ BenchmarkFile = "-"; for (const BenchmarkCode &Conf : Configurations) { - InstructionBenchmark Result = Runner->runConfiguration( - Conf, NumRepetitions, *Repetitor, DumpObjectToDisk); + InstructionBenchmark Result = ExitOnErr(Runner->runConfiguration( + Conf, NumRepetitions, *Repetitor, DumpObjectToDisk)); ExitOnFileError(BenchmarkFile, Result.writeYaml(State, BenchmarkFile)); } exegesis::pfm::pfmTerminate();