diff options
author | Clement Courbet <courbet@google.com> | 2018-06-05 10:56:19 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2018-06-05 10:56:19 +0000 |
commit | 53d35d2dc4a6ef270d1407d0ea0717d8ccf6fccd (patch) | |
tree | 4ab3d10b61dcbce9f5a4d31c73de7b2ce76cc5ec /llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp | |
parent | fef9b6eea63b095ac32526342d45d726f6704050 (diff) | |
download | bcm5719-llvm-53d35d2dc4a6ef270d1407d0ea0717d8ccf6fccd.tar.gz bcm5719-llvm-53d35d2dc4a6ef270d1407d0ea0717d8ccf6fccd.zip |
[llvm-exegesis] Add instructions to BenchmarkResult Key.
We want llvm-exegesis to explore instructions (effect of initial register values, effect of operand selection). To enable this a BenchmarkResult muststore all the relevant data in its key. This patch starts adding such data. Here we simply allow to store the generated instructions, following patches will add operands and initial values for registers.
https://reviews.llvm.org/D47764
Authored by: Guilluame Chatelet
llvm-svn: 334008
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp | 118 |
1 files changed, 105 insertions, 13 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp index fd5b3504e1e..441aee0758e 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "BenchmarkResult.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" @@ -18,6 +19,38 @@ namespace llvm { namespace yaml { +// std::vector<llvm::MCInst> will be rendered as a list. +template <> struct SequenceElementTraits<llvm::MCInst> { + static const bool flow = false; +}; + +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; + } + + 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(); + } + + static QuotingType mustQuote(StringRef) { return QuotingType::Single; } + + static const bool flow = true; +}; + // std::vector<exegesis::Measure> will be rendered as a list. template <> struct SequenceElementTraits<exegesis::BenchmarkMeasure> { static const bool flow = false; @@ -47,6 +80,7 @@ struct ScalarEnumerationTraits<exegesis::InstructionBenchmarkKey::ModeE> { template <> struct MappingTraits<exegesis::InstructionBenchmarkKey> { static void mapping(IO &Io, exegesis::InstructionBenchmarkKey &Obj) { Io.mapRequired("opcode_name", Obj.OpcodeName); + Io.mapOptional("instructions", Obj.Instructions); Io.mapRequired("mode", Obj.Mode); Io.mapOptional("config", Obj.Config); } @@ -71,46 +105,104 @@ LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(exegesis::InstructionBenchmark) namespace exegesis { +void BenchmarkResultContext::addRegEntry(unsigned RegNo, llvm::StringRef Name) { + assert(RegNoToName.find(RegNo) == RegNoToName.end()); + assert(RegNameToNo.find(Name) == RegNameToNo.end()); + RegNoToName[RegNo] = Name; + RegNameToNo[Name] = RegNo; +} + +llvm::StringRef BenchmarkResultContext::getRegName(unsigned RegNo) const { + const auto Itr = RegNoToName.find(RegNo); + if (Itr != RegNoToName.end()) + return Itr->second; + return {}; +} + +unsigned BenchmarkResultContext::getRegNo(llvm::StringRef Name) const { + const auto Itr = RegNameToNo.find(Name); + if (Itr != RegNameToNo.end()) + return Itr->second; + return 0; +} + +void BenchmarkResultContext::addInstrEntry(unsigned Opcode, + llvm::StringRef Name) { + assert(InstrOpcodeToName.find(Opcode) == InstrOpcodeToName.end()); + assert(InstrNameToOpcode.find(Name) == InstrNameToOpcode.end()); + InstrOpcodeToName[Opcode] = Name; + InstrNameToOpcode[Name] = Opcode; +} + +llvm::StringRef BenchmarkResultContext::getInstrName(unsigned Opcode) const { + const auto Itr = InstrOpcodeToName.find(Opcode); + if (Itr != InstrOpcodeToName.end()) + return Itr->second; + return {}; +} + +unsigned BenchmarkResultContext::getInstrOpcode(llvm::StringRef Name) const { + const auto Itr = InstrNameToOpcode.find(Name); + if (Itr != InstrNameToOpcode.end()) + return Itr->second; + return 0; +} + template <typename ObjectOrList> -static ObjectOrList readYamlOrDieCommon(llvm::StringRef Filename) { +static ObjectOrList readYamlOrDieCommon(const BenchmarkResultContext &Context, + llvm::StringRef Filename) { std::unique_ptr<llvm::MemoryBuffer> MemBuffer = llvm::cantFail( llvm::errorOrToExpected(llvm::MemoryBuffer::getFile(Filename))); - llvm::yaml::Input Yin(*MemBuffer); + // YAML IO requires a mutable pointer to Context but we guarantee to not + // modify it. + llvm::yaml::Input Yin(*MemBuffer, + const_cast<BenchmarkResultContext *>(&Context)); ObjectOrList Benchmark; Yin >> Benchmark; return Benchmark; } InstructionBenchmark -InstructionBenchmark::readYamlOrDie(llvm::StringRef Filename) { - return readYamlOrDieCommon<InstructionBenchmark>(Filename); +InstructionBenchmark::readYamlOrDie(const BenchmarkResultContext &Context, + llvm::StringRef Filename) { + return readYamlOrDieCommon<InstructionBenchmark>(Context, Filename); } std::vector<InstructionBenchmark> -InstructionBenchmark::readYamlsOrDie(llvm::StringRef Filename) { - return readYamlOrDieCommon<std::vector<InstructionBenchmark>>(Filename); +InstructionBenchmark::readYamlsOrDie(const BenchmarkResultContext &Context, + llvm::StringRef Filename) { + return readYamlOrDieCommon<std::vector<InstructionBenchmark>>(Context, + Filename); } -void InstructionBenchmark::writeYamlTo(llvm::raw_ostream &S) { - llvm::yaml::Output Yout(S); +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)); Yout << *this; } -void InstructionBenchmark::readYamlFrom(llvm::StringRef InputContent) { - llvm::yaml::Input Yin(InputContent); +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)); Yin >> *this; } // FIXME: Change the API to let the caller handle errors. -void InstructionBenchmark::writeYamlOrDie(const llvm::StringRef Filename) { +void InstructionBenchmark::writeYamlOrDie(const BenchmarkResultContext &Context, + const llvm::StringRef Filename) { if (Filename == "-") { - writeYamlTo(llvm::outs()); + writeYamlTo(Context, llvm::outs()); } else { int ResultFD = 0; llvm::cantFail(llvm::errorCodeToError( openFileForWrite(Filename, ResultFD, llvm::sys::fs::F_Text))); llvm::raw_fd_ostream Ostr(ResultFD, true /*shouldClose*/); - writeYamlTo(Ostr); + writeYamlTo(Context, Ostr); } } |