1 //===-- Analysis.h ----------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Analysis output for benchmark results. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H 15 #define LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H 16 17 #include "Clustering.h" 18 #include "DisassemblerHelper.h" 19 #include "SchedClassResolution.h" 20 #include "llvm/MC/MCInstrInfo.h" 21 #include "llvm/MC/MCObjectFileInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/Support/Error.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include <memory> 26 27 namespace llvm { 28 namespace exegesis { 29 30 // A helper class to analyze benchmark results for a target. 31 class Analysis { 32 public: 33 Analysis(const LLVMState &State, 34 const BenchmarkClustering &Clustering, 35 double AnalysisInconsistencyEpsilon, 36 bool AnalysisDisplayUnstableOpcodes); 37 38 // Prints a csv of instructions for each cluster. 39 struct PrintClusters {}; 40 // Find potential errors in the scheduling information given measurements. 41 struct PrintSchedClassInconsistencies {}; 42 43 template <typename Pass> Error run(raw_ostream &OS) const; 44 45 private: 46 using ClusterId = BenchmarkClustering::ClusterId; 47 48 // Represents the intersection of a sched class and a cluster. 49 class SchedClassCluster { 50 public: id()51 const BenchmarkClustering::ClusterId &id() const { 52 return ClusterId; 53 } 54 getPointIds()55 const std::vector<size_t> &getPointIds() const { return PointIds; } 56 57 void addPoint(size_t PointId, 58 const BenchmarkClustering &Clustering); 59 60 // Return the cluster centroid. getCentroid()61 const SchedClassClusterCentroid &getCentroid() const { return Centroid; } 62 63 // Returns true if the cluster representative measurements match that of SC. 64 bool 65 measurementsMatch(const MCSubtargetInfo &STI, const ResolvedSchedClass &SC, 66 const BenchmarkClustering &Clustering, 67 const double AnalysisInconsistencyEpsilonSquared_) const; 68 69 private: 70 BenchmarkClustering::ClusterId ClusterId; 71 std::vector<size_t> PointIds; 72 // Measurement stats for the points in the SchedClassCluster. 73 SchedClassClusterCentroid Centroid; 74 }; 75 76 void printInstructionRowCsv(size_t PointId, raw_ostream &OS) const; 77 78 void printClusterRawHtml(const BenchmarkClustering::ClusterId &Id, 79 StringRef display_name, raw_ostream &OS) const; 80 81 void printPointHtml(const Benchmark &Point, raw_ostream &OS) const; 82 83 void 84 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters, 85 const ResolvedSchedClass &SC, 86 raw_ostream &OS) const; 87 void printSchedClassDescHtml(const ResolvedSchedClass &SC, 88 raw_ostream &OS) const; 89 90 // A pair of (Sched Class, indices of points that belong to the sched 91 // class). 92 struct ResolvedSchedClassAndPoints { 93 explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC); 94 95 ResolvedSchedClass RSC; 96 std::vector<size_t> PointIds; 97 }; 98 99 // Builds a list of ResolvedSchedClassAndPoints. 100 std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const; 101 102 template <typename EscapeTag, EscapeTag Tag> 103 void writeSnippet(raw_ostream &OS, ArrayRef<uint8_t> Bytes, 104 const char *Separator) const; 105 106 const BenchmarkClustering &Clustering_; 107 const LLVMState &State_; 108 std::unique_ptr<DisassemblerHelper> DisasmHelper_; 109 const double AnalysisInconsistencyEpsilonSquared_; 110 const bool AnalysisDisplayUnstableOpcodes_; 111 }; 112 113 } // namespace exegesis 114 } // namespace llvm 115 116 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H 117