diff options
author | Clement Courbet <courbet@google.com> | 2018-06-14 06:57:52 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2018-06-14 06:57:52 +0000 |
commit | 49fb4d413fc93449a81fa0d4d77f3a951ef8d876 (patch) | |
tree | d8b8e9f4b35b410875e326e9f91554b1bc1a97c2 /tools/llvm-exegesis | |
parent | 26570985ef8d700a5a1470a94f11514156d1fc6f (diff) |
[llvm-exegesis] Use BenchmarkResult::Instructions instead of OpcodeName
Summary:
Get rid of OpcodeName.
To remove the opcode name from an old file:
```
cat old_file | sed '/opcode_name.*/d'
```
Reviewers: gchatelet
Subscribers: tschuett, llvm-commits
Differential Revision: https://reviews.llvm.org/D48121
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334691 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-exegesis')
-rw-r--r-- | tools/llvm-exegesis/lib/Analysis.cpp | 105 | ||||
-rw-r--r-- | tools/llvm-exegesis/lib/BenchmarkResult.cpp | 3 | ||||
-rw-r--r-- | tools/llvm-exegesis/lib/BenchmarkResult.h | 1 | ||||
-rw-r--r-- | tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 1 |
4 files changed, 80 insertions, 30 deletions
diff --git a/tools/llvm-exegesis/lib/Analysis.cpp b/tools/llvm-exegesis/lib/Analysis.cpp index df353dcbf33..842790d74c7 100644 --- a/tools/llvm-exegesis/lib/Analysis.cpp +++ b/tools/llvm-exegesis/lib/Analysis.cpp @@ -20,7 +20,7 @@ static const char kCsvSep = ','; namespace { -enum EscapeTag { kEscapeCsv, kEscapeHtml }; +enum EscapeTag { kEscapeCsv, kEscapeHtml, kEscapeHtmlString }; template <EscapeTag Tag> void writeEscaped(llvm::raw_ostream &OS, const llvm::StringRef S); @@ -56,6 +56,16 @@ void writeEscaped<kEscapeHtml>(llvm::raw_ostream &OS, const llvm::StringRef S) { } } +template <> +void writeEscaped<kEscapeHtmlString>(llvm::raw_ostream &OS, const llvm::StringRef S) { + for (const char C : S) { + if (C == '"') + OS << "\\\""; + else + OS << C; + } +} + } // namespace template <EscapeTag Tag> @@ -75,6 +85,19 @@ static void writeMeasurementValue(llvm::raw_ostream &OS, const double Value) { writeEscaped<Tag>(OS, llvm::formatv("{0:F}", Value).str()); } +template <EscapeTag Tag> +static void writeSnippet(llvm::raw_ostream &OS, + const std::vector<llvm::MCInst> &Instructions, + const llvm::MCInstrInfo &InstrInfo, + const char* Separator) { + // FIXME: Print operands. + llvm::SmallVector<llvm::StringRef, 3> Opcodes; + for (const llvm::MCInst &Instr : Instructions) { + Opcodes.push_back(InstrInfo.getName(Instr.getOpcode())); + } + writeEscaped<Tag>(OS, llvm::join(Opcodes, Separator)); +} + // Prints a row representing an instruction, along with scheduling info and // point coordinates (measurements). void Analysis::printInstructionRowCsv(const size_t PointId, @@ -82,25 +105,22 @@ void Analysis::printInstructionRowCsv(const size_t PointId, const InstructionBenchmark &Point = Clustering_.getPoints()[PointId]; writeClusterId<kEscapeCsv>(OS, Clustering_.getClusterIdForPoint(PointId)); OS << kCsvSep; - writeEscaped<kEscapeCsv>(OS, Point.Key.OpcodeName); + writeSnippet<kEscapeCsv>(OS, Point.Key.Instructions, *InstrInfo_, "; "); OS << kCsvSep; writeEscaped<kEscapeCsv>(OS, Point.Key.Config); OS << kCsvSep; - const auto OpcodeIt = MnemonicToOpcode_.find(Point.Key.OpcodeName); - if (OpcodeIt != MnemonicToOpcode_.end()) { - const unsigned SchedClassId = - InstrInfo_->get(OpcodeIt->second).getSchedClass(); + assert(!Point.Key.Instructions.empty()); + // FIXME: Resolve variant classes. + const unsigned SchedClassId = + InstrInfo_->get(Point.Key.Instructions[0].getOpcode()).getSchedClass(); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - const auto &SchedModel = SubtargetInfo_->getSchedModel(); - const llvm::MCSchedClassDesc *const SCDesc = - SchedModel.getSchedClassDesc(SchedClassId); - writeEscaped<kEscapeCsv>(OS, SCDesc->Name); + const auto &SchedModel = SubtargetInfo_->getSchedModel(); + const llvm::MCSchedClassDesc *const SCDesc = + SchedModel.getSchedClassDesc(SchedClassId); + writeEscaped<kEscapeCsv>(OS, SCDesc->Name); #else - OS << SchedClassId; + OS << SchedClassId; #endif - } - // FIXME: Print the sched class once InstructionBenchmark separates key into - // (mnemonic, mode, opaque). for (const auto &Measurement : Point.Measurements) { OS << kCsvSep; writeMeasurementValue<kEscapeCsv>(OS, Measurement.Value); @@ -118,10 +138,6 @@ Analysis::Analysis(const llvm::Target &Target, const InstructionBenchmark &FirstPoint = Clustering.getPoints().front(); SubtargetInfo_.reset(Target.createMCSubtargetInfo(FirstPoint.LLVMTriple, FirstPoint.CpuName, "")); - - // Build an index of mnemonic->opcode. - for (int I = 0, E = InstrInfo_->getNumOpcodes(); I < E; ++I) - MnemonicToOpcode_.emplace(InstrInfo_->getName(I), I); } template <> @@ -158,16 +174,42 @@ Analysis::makePointsPerSchedClass() const { const InstructionBenchmark &Point = Points[PointId]; if (!Point.Error.empty()) continue; - const auto OpcodeIt = MnemonicToOpcode_.find(Point.Key.OpcodeName); - if (OpcodeIt == MnemonicToOpcode_.end()) - continue; - const unsigned SchedClassId = - InstrInfo_->get(OpcodeIt->second).getSchedClass(); - PointsPerSchedClass[SchedClassId].push_back(PointId); + assert(!Point.Key.Instructions.empty()); + const auto Opcode = Point.Key.Instructions[0].getOpcode(); + // FIXME: Resolve variant classes. + PointsPerSchedClass[InstrInfo_->get(Opcode).getSchedClass()].push_back( + PointId); } return PointsPerSchedClass; } +// Uops repeat the same opcode over again. Just show this opcode and show the +// whole snippet only on hover. +static void writeUopsSnippetHtml(llvm::raw_ostream &OS, + const std::vector<llvm::MCInst> &Instructions, + const llvm::MCInstrInfo &InstrInfo) { + if (Instructions.empty()) + return; + writeEscaped<kEscapeHtml>(OS, InstrInfo.getName(Instructions[0].getOpcode())); + if (Instructions.size() > 1) + OS << " (x" << Instructions.size() << ")"; +} + +// Latency tries to find a serial path. Just show the opcode path and show the +// whole snippet only on hover. +static void writeLatencySnippetHtml(llvm::raw_ostream &OS, + const std::vector<llvm::MCInst> &Instructions, + const llvm::MCInstrInfo &InstrInfo) { + bool First = true; + for (const llvm::MCInst &Instr : Instructions) { + if (First) + First = false; + else + OS << " → "; + writeEscaped<kEscapeHtml>(OS, InstrInfo.getName(Instr.getOpcode())); + } +} + void Analysis::printSchedClassClustersHtml( const std::vector<SchedClassCluster> &Clusters, const SchedClass &SC, llvm::raw_ostream &OS) const { @@ -195,8 +237,19 @@ void Analysis::printSchedClassClustersHtml( OS << "</td><td><ul>"; for (const size_t PointId : Cluster.getPointIds()) { const auto &Point = Points[PointId]; - OS << "<li><span class=\"mono\">"; - writeEscaped<kEscapeHtml>(OS, Point.Key.OpcodeName); + OS << "<li><span class=\"mono\" title=\""; + writeSnippet<kEscapeHtmlString>(OS, Point.Key.Instructions, *InstrInfo_, "\n"); + OS << "\">"; + switch (Point.Mode) { + case InstructionBenchmark::Latency: + writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_); + break; + case InstructionBenchmark::Uops: + writeUopsSnippetHtml(OS, Point.Key.Instructions, *InstrInfo_); + break; + default: + llvm_unreachable("invalid mode"); + } OS << "</span> <span class=\"mono\">"; writeEscaped<kEscapeHtml>(OS, Point.Key.Config); OS << "</span></li>"; diff --git a/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/tools/llvm-exegesis/lib/BenchmarkResult.cpp index 237a5404daa..841219cb7f2 100644 --- a/tools/llvm-exegesis/lib/BenchmarkResult.cpp +++ b/tools/llvm-exegesis/lib/BenchmarkResult.cpp @@ -140,8 +140,7 @@ struct ScalarEnumerationTraits<exegesis::InstructionBenchmark::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("instructions", Obj.Instructions); Io.mapOptional("config", Obj.Config); } }; diff --git a/tools/llvm-exegesis/lib/BenchmarkResult.h b/tools/llvm-exegesis/lib/BenchmarkResult.h index 5fa9af8e9d3..c226aa0020a 100644 --- a/tools/llvm-exegesis/lib/BenchmarkResult.h +++ b/tools/llvm-exegesis/lib/BenchmarkResult.h @@ -32,7 +32,6 @@ struct BenchmarkResultContext; // Forward declaration. struct InstructionBenchmarkKey { // The LLVM opcode name. - std::string OpcodeName; // FIXME: Deprecated, use Instructions below. std::vector<llvm::MCInst> Instructions; // An opaque configuration, that can be used to separate several benchmarks of // the same instruction under different configurations. diff --git a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp index 5cdaf777884..bed802d0b1e 100644 --- a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -62,7 +62,6 @@ InstructionBenchmark BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration, unsigned Opcode, unsigned NumRepetitions) const { InstructionBenchmark InstrBenchmark; - InstrBenchmark.Key.OpcodeName = State.getInstrInfo().getName(Opcode); InstrBenchmark.Mode = getMode(); InstrBenchmark.CpuName = State.getCpuName(); InstrBenchmark.LLVMTriple = State.getTriple(); |