}
}
+void Analysis::printPointHtml(const InstructionBenchmark &Point,
+ llvm::raw_ostream &OS) const {
+ OS << "<li><span class=\"mono\" title=\"";
+ writeSnippet<EscapeTag, kEscapeHtmlString>(OS, Point.AssembledSnippet, "\n");
+ OS << "\">";
+ switch (Point.Mode) {
+ case InstructionBenchmark::Latency:
+ writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
+ break;
+ case InstructionBenchmark::Uops:
+ case InstructionBenchmark::InverseThroughput:
+ 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>";
+}
+
void Analysis::printSchedClassClustersHtml(
const std::vector<SchedClassCluster> &Clusters,
const ResolvedSchedClass &RSC, raw_ostream &OS) const {
writeClusterId<kEscapeHtml>(OS, Cluster.id());
OS << "</td><td><ul>";
for (const size_t PointId : Cluster.getPointIds()) {
- const auto &Point = Points[PointId];
- OS << "<li><span class=\"mono\" title=\"";
- writeSnippet<EscapeTag, kEscapeHtmlString>(OS, Point.AssembledSnippet,
- "\n");
- OS << "\">";
- switch (Point.Mode) {
- case InstructionBenchmark::Latency:
- writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
- break;
- case InstructionBenchmark::Uops:
- case InstructionBenchmark::InverseThroughput:
- 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>";
+ printPointHtml(Points[PointId], OS);
}
OS << "</ul></td>";
for (const auto &Stats : Cluster.getCentroid().getStats()) {
OS << "</table>";
}
+void Analysis::printClusterRawHtml(
+ const InstructionBenchmarkClustering::ClusterId &Id, StringRef display_name,
+ llvm::raw_ostream &OS) const {
+ const auto &Points = Clustering_.getPoints();
+ const auto &Cluster = Clustering_.getCluster(Id);
+ if (Cluster.PointIndices.empty())
+ return;
+
+ OS << "<div class=\"inconsistency\"><p>" << display_name << " Cluster ("
+ << Cluster.PointIndices.size() << " points)</p>";
+ OS << "<table class=\"sched-class-clusters\">";
+ // Table Header.
+ OS << "<tr><th>ClusterId</th><th>Opcode/Config</th>";
+ for (const auto &Measurement : Points[Cluster.PointIndices[0]].Measurements) {
+ OS << "<th>";
+ writeEscaped<kEscapeHtml>(OS, Measurement.Key);
+ OS << "</th>";
+ }
+ OS << "</tr>";
+
+ // Point data.
+ for (const auto &PointId : Cluster.PointIndices) {
+ OS << "<tr class=\"bad-cluster\"><td>" << display_name << "</td><td><ul>";
+ printPointHtml(Points[PointId], OS);
+ OS << "</ul></td>";
+ for (const auto &Measurement : Points[PointId].Measurements) {
+ OS << "<td class=\"measurement\">";
+ writeMeasurementValue<kEscapeHtml>(OS, Measurement.PerInstructionValue);
+ }
+ OS << "</tr>";
+ }
+ OS << "</table>";
+
+ OS << "</div>";
+
+} // namespace exegesis
+
static constexpr const char kHtmlHead[] = R"(
<head>
<title>llvm-exegesis Analysis Results</title>
OS << "</div>";
}
+ printClusterRawHtml(InstructionBenchmarkClustering::ClusterId::noise(),
+ "[noise]", OS);
+
OS << "</body></html>";
return Error::success();
}