summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp88
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
OpenPOWER on IntegriCloud