diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h +++ b/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 { diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/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; } diff --git a/llvm/tools/llvm-exegesis/lib/Error.h b/llvm/tools/llvm-exegesis/lib/Error.h --- a/llvm/tools/llvm-exegesis/lib/Error.h +++ b/llvm/tools/llvm-exegesis/lib/Error.h @@ -26,13 +26,29 @@ class ClusteringError : public ErrorInfo { public: static char ID; - ClusteringError(const Twine&S) : Msg(S.str()) {} + ClusteringError(const Twine &S) : Msg(S.str()) {} void log(raw_ostream &OS) const override; std::error_code convertToErrorCode() const override; + +private: + 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; + std::string Msg; }; } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/Error.cpp b/llvm/tools/llvm-exegesis/lib/Error.cpp --- a/llvm/tools/llvm-exegesis/lib/Error.cpp +++ b/llvm/tools/llvm-exegesis/lib/Error.cpp @@ -13,13 +13,19 @@ char ClusteringError::ID; -void ClusteringError::log(raw_ostream &OS) const { - OS << Msg; -} +void ClusteringError::log(raw_ostream &OS) const { OS << Msg; } std::error_code ClusteringError::convertToErrorCode() const { 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 diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/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();