diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp | 103 |
1 files changed, 78 insertions, 25 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp index 87b25b413f2..aac93abcbe8 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp +++ b/llvm/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; } |