diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp index bb89655435a8a..523cb913885e7 100644 --- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp +++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp @@ -167,11 +167,11 @@ BitVector getFunctionReservedRegs(const TargetMachine &TM) { return MF.getSubtarget().getRegisterInfo()->getReservedRegs(MF); } -void assembleToStream(const ExegesisTarget &ET, - std::unique_ptr TM, - ArrayRef LiveIns, - ArrayRef RegisterInitialValues, - const FillFunction &Fill, raw_pwrite_stream &AsmStream) { +Error assembleToStream(const ExegesisTarget &ET, + std::unique_ptr TM, + ArrayRef LiveIns, + ArrayRef RegisterInitialValues, + const FillFunction &Fill, raw_pwrite_stream &AsmStream) { auto Context = std::make_unique(); std::unique_ptr Module = createModule(Context, TM->createDataLayout()); @@ -234,15 +234,15 @@ void assembleToStream(const ExegesisTarget &ET, for (const char *PassName : {"postrapseudos", "machineverifier", "prologepilog"}) if (addPass(PM, PassName, *TPC)) - report_fatal_error("Unable to add a mandatory pass"); + return make_error("Unable to add a mandatory pass"); TPC->setInitialized(); // AsmPrinter is responsible for generating the assembly into AsmBuffer. - if (TM->addAsmPrinter(PM, AsmStream, nullptr, CGFT_ObjectFile, - MCContext)) - report_fatal_error("Cannot add AsmPrinter passes"); + if (TM->addAsmPrinter(PM, AsmStream, nullptr, CGFT_ObjectFile, MCContext)) + return make_error("Cannot add AsmPrinter passes"); PM.run(*Module); // Run all the passes + return Error::success(); } object::OwningBinary diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.h b/llvm/tools/llvm-exegesis/lib/Assembler.h index 5d4204e4a50ce..2a83344b751e5 100644 --- a/llvm/tools/llvm-exegesis/lib/Assembler.h +++ b/llvm/tools/llvm-exegesis/lib/Assembler.h @@ -18,6 +18,7 @@ #include #include "BenchmarkCode.h" +#include "Error.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/CodeGen/MachineFunction.h" @@ -86,11 +87,11 @@ using FillFunction = std::function; // Instructions. Runs a set of llvm Passes to provide correct prologue and // epilogue. Once the MachineFunction is ready, it is assembled for TM to // AsmStream, the temporary function is eventually discarded. -void assembleToStream(const ExegesisTarget &ET, - std::unique_ptr TM, - ArrayRef LiveIns, - ArrayRef RegisterInitialValues, - const FillFunction &Fill, raw_pwrite_stream &AsmStream); +Error assembleToStream(const ExegesisTarget &ET, + std::unique_ptr TM, + ArrayRef LiveIns, + ArrayRef RegisterInitialValues, + const FillFunction &Fill, raw_pwrite_stream &AsmStream); // Creates an ObjectFile in the format understood by the host. // Note: the resulting object keeps a copy of Buffer so it can be discarded once diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp index 6981aaa46cd92..5b15bc29c60d3 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -101,10 +101,12 @@ Expected BenchmarkRunner::runConfiguration( { SmallString<0> Buffer; raw_svector_ostream OS(Buffer); - assembleToStream(State.getExegesisTarget(), State.createTargetMachine(), - BC.LiveIns, BC.Key.RegisterInitialValues, - Repetitor.Repeat(Instructions, kMinInstructionsForSnippet), - OS); + if (Error E = assembleToStream( + State.getExegesisTarget(), State.createTargetMachine(), BC.LiveIns, + BC.Key.RegisterInitialValues, + Repetitor.Repeat(Instructions, kMinInstructionsForSnippet), OS)) { + return std::move(E); + } const ExecutableFunction EF(State.createTargetMachine(), getObjectFromBuffer(OS.str())); const auto FnBytes = EF.getFunctionBytes(); @@ -129,8 +131,11 @@ Expected BenchmarkRunner::runConfiguration( } else { SmallString<0> Buffer; raw_svector_ostream OS(Buffer); - assembleToStream(State.getExegesisTarget(), State.createTargetMachine(), - BC.LiveIns, BC.Key.RegisterInitialValues, Filler, OS); + if (Error E = assembleToStream(State.getExegesisTarget(), + State.createTargetMachine(), BC.LiveIns, + BC.Key.RegisterInitialValues, Filler, OS)) { + return std::move(E); + } ObjectFile = getObjectFromBuffer(OS.str()); } @@ -165,8 +170,11 @@ BenchmarkRunner::writeObjectFile(const BenchmarkCode &BC, sys::fs::createTemporaryFile("snippet", "o", ResultFD, ResultPath))) return std::move(E); raw_fd_ostream OFS(ResultFD, true /*ShouldClose*/); - assembleToStream(State.getExegesisTarget(), State.createTargetMachine(), - BC.LiveIns, BC.Key.RegisterInitialValues, FillFunction, OFS); + if (Error E = assembleToStream( + State.getExegesisTarget(), State.createTargetMachine(), BC.LiveIns, + BC.Key.RegisterInitialValues, FillFunction, OFS)) { + return std::move(E); + } return std::string(ResultPath.str()); } diff --git a/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h index 795b0d6ab64b2..239685beb14e9 100644 --- a/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h +++ b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h @@ -77,8 +77,8 @@ class MachineFunctionGeneratorBaseTest : public ::testing::Test { FillFunction Fill) { SmallString<256> Buffer; raw_svector_ostream AsmStream(Buffer); - assembleToStream(*ET, createTargetMachine(), /*LiveIns=*/{}, - RegisterInitialValues, Fill, AsmStream); + EXPECT_FALSE(assembleToStream(*ET, createTargetMachine(), /*LiveIns=*/{}, + RegisterInitialValues, Fill, AsmStream)); return ExecutableFunction(createTargetMachine(), getObjectFromBuffer(AsmStream.str())); }