summaryrefslogtreecommitdiff
path: root/tools/llvm-exegesis
diff options
context:
space:
mode:
authorClement Courbet <courbet@google.com>2018-06-14 06:57:52 +0000
committerClement Courbet <courbet@google.com>2018-06-14 06:57:52 +0000
commit49fb4d413fc93449a81fa0d4d77f3a951ef8d876 (patch)
treed8b8e9f4b35b410875e326e9f91554b1bc1a97c2 /tools/llvm-exegesis
parent26570985ef8d700a5a1470a94f11514156d1fc6f (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.cpp105
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkResult.cpp3
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkResult.h1
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkRunner.cpp1
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 << " &rarr; ";
+ 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();