diff options
author | Guillaume Chatelet <gchatelet@google.com> | 2018-06-07 07:40:40 +0000 |
---|---|---|
committer | Guillaume Chatelet <gchatelet@google.com> | 2018-06-07 07:40:40 +0000 |
commit | a1c8d87b41461d4b14dec66d7b3bde3942e4cb24 (patch) | |
tree | 4bd599b9d3f5a07ecc00889e761ddacaa03c7378 /tools/llvm-exegesis | |
parent | 680aba746e93e472c25ad76c126f27f703cfcaa3 (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.cpp | 103 | ||||
-rw-r--r-- | tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 4 |
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); |