diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp index 2615a829902..0e2052f82cc 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -7,23 +7,33 @@ // //===----------------------------------------------------------------------===// +#include <array> +#include <string> + +#include "Assembler.h" #include "BenchmarkRunner.h" -#include "InMemoryAssembler.h" +#include "MCInstrDescView.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include <string> +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Program.h" namespace exegesis { BenchmarkRunner::InstructionFilter::~InstructionFilter() = default; - +BenchmarkRunner::BenchmarkRunner(const LLVMState &State) + : State(State), MCInstrInfo(State.getInstrInfo()), + MCRegisterInfo(State.getRegInfo()), + RATC(MCRegisterInfo, + getFunctionReservedRegs(*State.createTargetMachine())) {} BenchmarkRunner::~BenchmarkRunner() = default; -InstructionBenchmark -BenchmarkRunner::run(const LLVMState &State, const unsigned Opcode, - unsigned NumRepetitions, - const InstructionFilter &Filter) const { +InstructionBenchmark BenchmarkRunner::run(unsigned Opcode, + const InstructionFilter &Filter, + unsigned NumRepetitions) { InstructionBenchmark InstrBenchmark; InstrBenchmark.Key.OpcodeName = State.getInstrInfo().getName(Opcode); @@ -41,36 +51,56 @@ BenchmarkRunner::run(const LLVMState &State, const unsigned Opcode, InstrBenchmark.Error = llvm::toString(std::move(E)); return InstrBenchmark; } - - JitFunctionContext Context(State.createTargetMachine()); - auto ExpectedInstructions = - createCode(State, Opcode, NumRepetitions, Context); - if (llvm::Error E = ExpectedInstructions.takeError()) { + llvm::raw_string_ostream InfoStream(InstrBenchmark.Info); + llvm::Expected<std::vector<llvm::MCInst>> SnippetOrError = + createSnippet(RATC, Opcode, InfoStream); + if (llvm::Error E = SnippetOrError.takeError()) { InstrBenchmark.Error = llvm::toString(std::move(E)); return InstrBenchmark; } + std::vector<llvm::MCInst> &Snippet = SnippetOrError.get(); + if (Snippet.empty()) { + InstrBenchmark.Error = "Empty snippet"; + return InstrBenchmark; + } - const std::vector<llvm::MCInst> Instructions = *ExpectedInstructions; - const JitFunction Function(std::move(Context), Instructions); - const llvm::StringRef CodeBytes = Function.getFunctionBytes(); + InfoStream << "Snippet:\n"; + for (const auto &MCInst : Snippet) { + DumpMCInst(MCRegisterInfo, MCInstrInfo, MCInst, InfoStream); + InfoStream << "\n"; + } + + std::vector<llvm::MCInst> Code; + for (int I = 0; I < InstrBenchmark.NumRepetitions; ++I) + Code.push_back(Snippet[I % Snippet.size()]); - std::string AsmExcerpt; - constexpr const int ExcerptSize = 100; - constexpr const int ExcerptTailSize = 10; - if (CodeBytes.size() <= ExcerptSize) { - AsmExcerpt = llvm::toHex(CodeBytes); - } else { - AsmExcerpt = - llvm::toHex(CodeBytes.take_front(ExcerptSize - ExcerptTailSize + 3)); - AsmExcerpt += "..."; - AsmExcerpt += llvm::toHex(CodeBytes.take_back(ExcerptTailSize)); + auto ExpectedObjectPath = writeObjectFile(Code); + if (llvm::Error E = ExpectedObjectPath.takeError()) { + InstrBenchmark.Error = llvm::toString(std::move(E)); + return InstrBenchmark; } - llvm::outs() << "# Asm excerpt: " << AsmExcerpt << "\n"; - llvm::outs().flush(); // In case we crash. - InstrBenchmark.Measurements = - runMeasurements(State, Function, NumRepetitions); + // FIXME: Check if TargetMachine or ExecutionEngine can be reused instead of + // creating one everytime. + const ExecutableFunction EF(State.createTargetMachine(), + getObjectFromFile(*ExpectedObjectPath)); + InstrBenchmark.Measurements = runMeasurements(EF, NumRepetitions); + return InstrBenchmark; } +llvm::Expected<std::string> +BenchmarkRunner::writeObjectFile(llvm::ArrayRef<llvm::MCInst> Code) const { + int ResultFD = 0; + llvm::SmallString<256> ResultPath; + if (llvm::Error E = llvm::errorCodeToError(llvm::sys::fs::createTemporaryFile( + "snippet", "o", ResultFD, ResultPath))) + return std::move(E); + llvm::raw_fd_ostream OFS(ResultFD, true /*ShouldClose*/); + assembleToStream(State.createTargetMachine(), Code, OFS); + llvm::outs() << "Check generated assembly with: /usr/bin/objdump -d " + << ResultPath << "\n"; + return ResultPath.str(); +} + } // namespace exegesis |