diff --git a/llvm/test/tools/llvm-exegesis/X86/analysis-noise.test b/llvm/test/tools/llvm-exegesis/X86/analysis-noise.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-exegesis/X86/analysis-noise.test @@ -0,0 +1,23 @@ +# RUN: llvm-exegesis -mode=analysis -benchmarks-file=%s -analysis-inconsistencies-output-file=- -analysis-clusters-output-file="" -analysis-numpoints=3 | FileCheck %s + +# CHECK: DOCTYPE +# CHECK: [noise] Cluster (1 points) + +--- +mode: latency +key: + instructions: + - 'ADD64rr RAX RAX RDI' + config: '' + register_initial_values: + - 'RAX=0x0' + - 'RDI=0x0' +cpu_name: haswell +llvm_triple: x86_64-unknown-linux-gnu +num_repetitions: 10000 +measurements: + - { key: latency, value: 1.0049, per_snippet_value: 1.0049 } +error: '' +info: Repeating a single implicitly serial instruction +assembled_snippet: 48B8000000000000000048BF00000000000000004801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F84801F8C3 +... diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.h b/llvm/tools/llvm-exegesis/lib/Analysis.h --- a/llvm/tools/llvm-exegesis/lib/Analysis.h +++ b/llvm/tools/llvm-exegesis/lib/Analysis.h @@ -81,6 +81,12 @@ void printInstructionRowCsv(size_t PointId, raw_ostream &OS) const; + void printClusterRawHtml(const InstructionBenchmarkClustering::ClusterId &Id, + StringRef display_name, llvm::raw_ostream &OS) const; + + void printPointHtml(const InstructionBenchmark &Point, + llvm::raw_ostream &OS) const; + void printSchedClassClustersHtml(const std::vector &Clusters, const ResolvedSchedClass &SC, diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp --- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp +++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp @@ -268,6 +268,27 @@ } } +void Analysis::printPointHtml(const InstructionBenchmark &Point, + llvm::raw_ostream &OS) const { + OS << "
  • (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 << " "; + writeEscaped(OS, Point.Key.Config); + OS << "
  • "; +} + void Analysis::printSchedClassClustersHtml( const std::vector &Clusters, const ResolvedSchedClass &RSC, raw_ostream &OS) const { @@ -292,25 +313,7 @@ writeClusterId(OS, Cluster.id()); OS << "
      "; for (const size_t PointId : Cluster.getPointIds()) { - const auto &Point = Points[PointId]; - OS << "
    • (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 << " "; - writeEscaped(OS, Point.Key.Config); - OS << "
    • "; + printPointHtml(Points[PointId], OS); } OS << "
    "; for (const auto &Stats : Cluster.getCentroid().getStats()) { @@ -422,6 +425,43 @@ OS << ""; } +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 << "

    " << display_name << " Cluster (" + << Cluster.PointIndices.size() << " points)

    "; + OS << ""; + // Table Header. + OS << ""; + for (const auto &Measurement : Points[Cluster.PointIndices[0]].Measurements) { + OS << ""; + } + OS << ""; + + // Point data. + for (const auto &PointId : Cluster.PointIndices) { + OS << ""; + for (const auto &Measurement : Points[PointId].Measurements) { + OS << ""; + } + OS << "
    ClusterIdOpcode/Config"; + writeEscaped(OS, Measurement.Key); + OS << "
    " << display_name << "
      "; + printPointHtml(Points[PointId], OS); + OS << "
    "; + writeMeasurementValue(OS, Measurement.PerInstructionValue); + } + OS << "
    "; + + OS << "
    "; + +} // namespace exegesis + static constexpr const char kHtmlHead[] = R"( llvm-exegesis Analysis Results @@ -549,6 +589,9 @@ OS << ""; } + printClusterRawHtml(InstructionBenchmarkClustering::ClusterId::noise(), + "[noise]", OS); + OS << ""; return Error::success(); }