aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-exegesis
diff options
context:
space:
mode:
authorGuillaume Chatelet <gchatelet@google.com>2018-06-07 07:40:40 +0000
committerGuillaume Chatelet <gchatelet@google.com>2018-06-07 07:40:40 +0000
commita1c8d87b41461d4b14dec66d7b3bde3942e4cb24 (patch)
tree4bd599b9d3f5a07ecc00889e761ddacaa03c7378 /tools/llvm-exegesis
parent680aba746e93e472c25ad76c126f27f703cfcaa3 (diff)
[llvm-exegesis] Serializes instruction's operand in BenchmarkResult's key.
Summary: Follow up patch to https://reviews.llvm.org/D47764. Reviewers: courbet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D47785 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334165 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-exegesis')
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkResult.cpp103
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkRunner.cpp4
2 files changed, 81 insertions, 26 deletions
diff --git a/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 87b25b413f2..aac93abcbe8 100644
--- a/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -15,6 +15,78 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+static constexpr const char kIntegerFormat[] = "i_0x%" PRId64 "x";
+static constexpr const char kDoubleFormat[] = "f_%la";
+
+static void serialize(const exegesis::BenchmarkResultContext &Context,
+ const llvm::MCOperand &MCOperand, llvm::raw_ostream &OS) {
+ if (MCOperand.isReg()) {
+ OS << Context.getRegName(MCOperand.getReg());
+ } else if (MCOperand.isImm()) {
+ OS << llvm::format(kIntegerFormat, MCOperand.getImm());
+ } else if (MCOperand.isFPImm()) {
+ OS << llvm::format(kDoubleFormat, MCOperand.getFPImm());
+ } else {
+ OS << "INVALID";
+ }
+}
+
+static void serialize(const exegesis::BenchmarkResultContext &Context,
+ const llvm::MCInst &MCInst, llvm::raw_ostream &OS) {
+ OS << Context.getInstrName(MCInst.getOpcode());
+ for (const auto &Op : MCInst) {
+ OS << ' ';
+ serialize(Context, Op, OS);
+ }
+}
+
+static llvm::MCOperand
+deserialize(const exegesis::BenchmarkResultContext &Context,
+ llvm::StringRef String) {
+ assert(!String.empty());
+ int64_t IntValue = 0;
+ double DoubleValue = 0;
+ if (sscanf(String.data(), kIntegerFormat, &IntValue) == 1)
+ return llvm::MCOperand::createImm(IntValue);
+ if (sscanf(String.data(), kDoubleFormat, &DoubleValue) == 1)
+ return llvm::MCOperand::createFPImm(DoubleValue);
+ if (unsigned RegNo = Context.getRegNo(String)) // Returns 0 if invalid.
+ return llvm::MCOperand::createReg(RegNo);
+ return {};
+}
+
+static llvm::StringRef
+deserialize(const exegesis::BenchmarkResultContext &Context,
+ llvm::StringRef String, llvm::MCInst &Value) {
+ llvm::SmallVector<llvm::StringRef, 8> Pieces;
+ String.split(Pieces, " ");
+ if (Pieces.empty())
+ return "Invalid Instruction";
+ bool ProcessOpcode = true;
+ for (llvm::StringRef Piece : Pieces) {
+ if (ProcessOpcode) {
+ ProcessOpcode = false;
+ Value.setOpcode(Context.getInstrOpcode(Piece));
+ if (Value.getOpcode() == 0)
+ return "Unknown Opcode Name";
+ } else {
+ Value.addOperand(deserialize(Context, Piece));
+ }
+ }
+ return {};
+}
+
+// YAML IO requires a mutable pointer to Context but we guarantee to not
+// modify it.
+static void *getUntypedContext(const exegesis::BenchmarkResultContext &Ctx) {
+ return const_cast<exegesis::BenchmarkResultContext *>(&Ctx);
+}
+
+static const exegesis::BenchmarkResultContext &getTypedContext(void *Ctx) {
+ assert(Ctx);
+ return *static_cast<const exegesis::BenchmarkResultContext *>(Ctx);
+}
+
// Defining YAML traits for IO.
namespace llvm {
namespace yaml {
@@ -28,22 +100,11 @@ template <> struct ScalarTraits<llvm::MCInst> {
static void output(const llvm::MCInst &Value, void *Ctx,
llvm::raw_ostream &Out) {
- assert(Ctx);
- auto *Context = static_cast<const exegesis::BenchmarkResultContext *>(Ctx);
- const StringRef Name = Context->getInstrName(Value.getOpcode());
- assert(!Name.empty());
- Out << Name;
+ serialize(getTypedContext(Ctx), Value, Out);
}
static StringRef input(StringRef Scalar, void *Ctx, llvm::MCInst &Value) {
- assert(Ctx);
- auto *Context = static_cast<const exegesis::BenchmarkResultContext *>(Ctx);
- const unsigned Opcode = Context->getInstrOpcode(Scalar);
- if (Opcode == 0) {
- return "Unable to parse instruction";
- }
- Value.setOpcode(Opcode);
- return StringRef();
+ return deserialize(getTypedContext(Ctx), Scalar, Value);
}
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
@@ -153,10 +214,7 @@ static ObjectOrList readYamlOrDieCommon(const BenchmarkResultContext &Context,
llvm::StringRef Filename) {
std::unique_ptr<llvm::MemoryBuffer> MemBuffer = llvm::cantFail(
llvm::errorOrToExpected(llvm::MemoryBuffer::getFile(Filename)));
- // YAML IO requires a mutable pointer to Context but we guarantee to not
- // modify it.
- llvm::yaml::Input Yin(*MemBuffer,
- const_cast<BenchmarkResultContext *>(&Context));
+ llvm::yaml::Input Yin(*MemBuffer, getUntypedContext(Context));
ObjectOrList Benchmark;
Yin >> Benchmark;
return Benchmark;
@@ -176,19 +234,14 @@ InstructionBenchmark::readYamlsOrDie(const BenchmarkResultContext &Context,
}
void InstructionBenchmark::writeYamlTo(const BenchmarkResultContext &Context,
- llvm::raw_ostream &S) {
- // YAML IO requires a mutable pointer to Context but we guarantee to not
- // modify it.
- llvm::yaml::Output Yout(S, const_cast<BenchmarkResultContext *>(&Context));
+ llvm::raw_ostream &OS) {
+ llvm::yaml::Output Yout(OS, getUntypedContext(Context));
Yout << *this;
}
void InstructionBenchmark::readYamlFrom(const BenchmarkResultContext &Context,
llvm::StringRef InputContent) {
- // YAML IO requires a mutable pointer to Context but we guarantee to not
- // modify it.
- llvm::yaml::Input Yin(InputContent,
- const_cast<BenchmarkResultContext *>(&Context));
+ llvm::yaml::Input Yin(InputContent, getUntypedContext(Context));
Yin >> *this;
}
diff --git a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 0599c8e0f3f..1d8b34f1032 100644
--- a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -63,7 +63,9 @@ InstructionBenchmark BenchmarkRunner::run(unsigned Opcode,
InstrBenchmark.Error = "Empty snippet";
return InstrBenchmark;
}
-
+ for (const auto &MCInst : Snippet) {
+ InstrBenchmark.Key.Instructions.push_back(MCInst);
+ }
InfoStream << "Snippet:\n";
for (const auto &MCInst : Snippet) {
DumpMCInst(MCRegisterInfo, MCInstrInfo, MCInst, InfoStream);