[llvm-exegesis] Analysis: Show value extents.

Summary: Screenshot attached in phabricator.

Reviewers: gchatelet

Subscribers: tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D47318

llvm-svn: 333181
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
index 6ad693f..0802f84 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -195,22 +195,30 @@
     OS << "<tr><td>";
     writeClusterId<kEscapeHtml>(OS, CurrentClusterId);
     OS << "</td><td><ul>";
-    const auto &ClusterRepresentative =
-        Points[PointIds[I]]; // FIXME: average measurements.
+    std::vector<BenchmarkMeasureStats> MeasurementStats(
+        Points[PointIds[I]].Measurements.size());
     for (; I < E &&
            Clustering_.getClusterIdForPoint(PointIds[I]) == CurrentClusterId;
          ++I) {
+      const auto &Point = Points[PointIds[I]];
       OS << "<li><span class=\"mono\">";
-      writeEscaped<kEscapeHtml>(OS, Points[PointIds[I]].Key.OpcodeName);
+      writeEscaped<kEscapeHtml>(OS, Point.Key.OpcodeName);
       OS << "</span> <span class=\"mono\">";
-      writeEscaped<kEscapeHtml>(OS, Points[PointIds[I]].Key.Config);
+      writeEscaped<kEscapeHtml>(OS, Point.Key.Config);
       OS << "</span></li>";
+      for (size_t J = 0, F = Point.Measurements.size(); J < F; ++J) {
+        MeasurementStats[J].push(Point.Measurements[J]);
+      }
     }
     OS << "</ul></td>";
-    for (const auto &Measurement : ClusterRepresentative.Measurements) {
-      OS << "<td>";
-      writeMeasurementValue<kEscapeHtml>(OS, Measurement.Value);
-      OS << "</td>";
+    for (const auto &Stats : MeasurementStats) {
+      OS << "<td class=\"measurement\">";
+      writeMeasurementValue<kEscapeHtml>(OS, Stats.avg());
+      OS << "<br><span class=\"minmax\">[";
+      writeMeasurementValue<kEscapeHtml>(OS, Stats.min());
+      OS << ";";
+      writeMeasurementValue<kEscapeHtml>(OS, Stats.max());
+      OS << "]</span></td>";
     }
     OS << "</tr>";
   }
@@ -321,7 +329,7 @@
       writeEscaped<kEscapeHtml>(OS, SubtargetInfo_->getSchedModel()
                                         .getProcResource(WPR.ProcResourceIdx)
                                         ->Name);
-      OS << "</spam>: " << WPR.Cycles << "</li>";
+      OS << "</span>: " << WPR.Cycles << "</li>";
     }
     OS << "</ul></td>";
     OS << "</tr>";
@@ -378,6 +386,12 @@
 span.mono {
   font-family: monospace;
 }
+span.minmax {
+  color: #888;
+}
+td.measurement {
+  text-align: center;
+}
 </style>
 </head>
 )";
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index b1083f4..ed449db 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -104,4 +104,14 @@
   }
 }
 
+void BenchmarkMeasureStats::push(const BenchmarkMeasure &BM) {
+  if (Key.empty())
+    Key = BM.Key;
+  assert(Key == BM.Key);
+  ++NumValues;
+  SumValues += BM.Value;
+  MaxValue = std::max(MaxValue, BM.Value);
+  MinValue = std::min(MinValue, BM.Value);
+}
+
 } // namespace exegesis
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
index 3a7d241..4362df8 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/YAMLTraits.h"
+#include <limits>
 #include <string>
 #include <vector>
 
@@ -61,6 +62,29 @@
   void writeYamlOrDie(const llvm::StringRef Filename);
 };
 
+//------------------------------------------------------------------------------
+// Utilities to work with Benchmark measures.
+
+// A class that measures stats over benchmark measures.
+class BenchmarkMeasureStats {
+public:
+  void push(const BenchmarkMeasure &BM);
+
+  double avg() const {
+    assert(NumValues);
+    return SumValues / NumValues;
+  }
+  double min() const { return MinValue; }
+  double max() const { return MaxValue; }
+
+private:
+  std::string Key;
+  double SumValues = 0.0;
+  int NumValues = 0;
+  double MaxValue = std::numeric_limits<double>::min();
+  double MinValue = std::numeric_limits<double>::max();
+};
+
 } // namespace exegesis
 
 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H