[llvm] r334165 - [llvm-exegesis] Serializes instruction's operand in BenchmarkResult's key.
Guillaume Chatelet via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 7 00:40:40 PDT 2018
Author: gchatelet
Date: Thu Jun 7 00:40:40 2018
New Revision: 334165
URL: http://llvm.org/viewvc/llvm-project?rev=334165&view=rev
Log:
[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
Modified:
llvm/trunk/tools/llvm-exegesis/lib/BenchmarkResult.cpp
llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
llvm/trunk/unittests/tools/llvm-exegesis/BenchmarkResultTest.cpp
Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkResult.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkResult.cpp?rev=334165&r1=334164&r2=334165&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkResult.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkResult.cpp Thu Jun 7 00:40:40 2018
@@ -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::MC
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(
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(con
}
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;
}
Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp?rev=334165&r1=334164&r2=334165&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp Thu Jun 7 00:40:40 2018
@@ -63,7 +63,9 @@ InstructionBenchmark BenchmarkRunner::ru
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);
Modified: llvm/trunk/unittests/tools/llvm-exegesis/BenchmarkResultTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/BenchmarkResultTest.cpp?rev=334165&r1=334164&r2=334165&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/BenchmarkResultTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/BenchmarkResultTest.cpp Thu Jun 7 00:40:40 2018
@@ -28,23 +28,46 @@ bool operator==(const BenchmarkMeasure &
return std::tie(A.Key, A.Value) == std::tie(B.Key, B.Value);
}
+static std::string Dump(const llvm::MCInst &McInst) {
+ std::string Buffer;
+ llvm::raw_string_ostream OS(Buffer);
+ McInst.print(OS);
+ return Buffer;
+}
+
MATCHER(EqMCInst, "") {
- return get<0>(arg).getOpcode() == get<1>(arg).getOpcode();
+ const std::string Lhs = Dump(get<0>(arg));
+ const std::string Rhs = Dump(get<1>(arg));
+ if (Lhs != Rhs) {
+ *result_listener << Lhs << " <=> " << Rhs;
+ return false;
+ }
+ return true;
}
namespace {
static constexpr const unsigned kInstrId = 5;
static constexpr const char kInstrName[] = "Instruction5";
+static constexpr const unsigned kReg1Id = 1;
+static constexpr const char kReg1Name[] = "Reg1";
+static constexpr const unsigned kReg2Id = 2;
+static constexpr const char kReg2Name[] = "Reg2";
TEST(BenchmarkResultTest, WriteToAndReadFromDisk) {
BenchmarkResultContext Ctx;
Ctx.addInstrEntry(kInstrId, kInstrName);
+ Ctx.addRegEntry(kReg1Id, kReg1Name);
+ Ctx.addRegEntry(kReg2Id, kReg2Name);
InstructionBenchmark ToDisk;
ToDisk.Key.OpcodeName = "name";
- ToDisk.Key.Instructions.push_back(llvm::MCInstBuilder(kInstrId));
+ ToDisk.Key.Instructions.push_back(llvm::MCInstBuilder(kInstrId)
+ .addReg(kReg1Id)
+ .addReg(kReg2Id)
+ .addImm(123)
+ .addFPImm(0.5));
ToDisk.Key.Config = "config";
ToDisk.Mode = InstructionBenchmark::Latency;
ToDisk.CpuName = "cpu_name";
More information about the llvm-commits
mailing list