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 "SchedClassResolution.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 21 #include "llvm/MC/MCInstPrinter.h" 22 #include "llvm/MC/MCInstrInfo.h" 23 #include "llvm/MC/MCObjectFileInfo.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/MC/TargetRegistry.h" 26 #include "llvm/Support/Error.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <memory> 29 #include <set> 30 #include <string> 31 #include <unordered_map> 32 33 namespace llvm { 34 namespace exegesis { 35 36 // A helper class to analyze benchmark results for a target. 37 class Analysis { 38 public: 39 Analysis(const Target &Target, std::unique_ptr<MCSubtargetInfo> SubtargetInfo, 40 std::unique_ptr<MCInstrInfo> InstrInfo, 41 const InstructionBenchmarkClustering &Clustering, 42 double AnalysisInconsistencyEpsilon, 43 bool AnalysisDisplayUnstableOpcodes, 44 const std::string &ForceCpuName = ""); 45 46 // Prints a csv of instructions for each cluster. 47 struct PrintClusters {}; 48 // Find potential errors in the scheduling information given measurements. 49 struct PrintSchedClassInconsistencies {}; 50 51 template <typename Pass> Error run(raw_ostream &OS) const; 52 53 private: 54 using ClusterId = InstructionBenchmarkClustering::ClusterId; 55 56 // Represents the intersection of a sched class and a cluster. 57 class SchedClassCluster { 58 public: id()59 const InstructionBenchmarkClustering::ClusterId &id() const { 60 return ClusterId; 61 } 62 getPointIds()63 const std::vector<size_t> &getPointIds() const { return PointIds; } 64 65 void addPoint(size_t PointId, 66 const InstructionBenchmarkClustering &Clustering); 67 68 // Return the cluster centroid. getCentroid()69 const SchedClassClusterCentroid &getCentroid() const { return Centroid; } 70 71 // Returns true if the cluster representative measurements match that of SC. 72 bool 73 measurementsMatch(const MCSubtargetInfo &STI, const ResolvedSchedClass &SC, 74 const InstructionBenchmarkClustering &Clustering, 75 const double AnalysisInconsistencyEpsilonSquared_) const; 76 77 private: 78 InstructionBenchmarkClustering::ClusterId ClusterId; 79 std::vector<size_t> PointIds; 80 // Measurement stats for the points in the SchedClassCluster. 81 SchedClassClusterCentroid Centroid; 82 }; 83 84 void printInstructionRowCsv(size_t PointId, raw_ostream &OS) const; 85 86 void printClusterRawHtml(const InstructionBenchmarkClustering::ClusterId &Id, 87 StringRef display_name, llvm::raw_ostream &OS) const; 88 89 void printPointHtml(const InstructionBenchmark &Point, 90 llvm::raw_ostream &OS) const; 91 92 void 93 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters, 94 const ResolvedSchedClass &SC, 95 raw_ostream &OS) const; 96 void printSchedClassDescHtml(const ResolvedSchedClass &SC, 97 raw_ostream &OS) const; 98 99 // A pair of (Sched Class, indices of points that belong to the sched 100 // class). 101 struct ResolvedSchedClassAndPoints { 102 explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC); 103 104 ResolvedSchedClass RSC; 105 std::vector<size_t> PointIds; 106 }; 107 108 // Builds a list of ResolvedSchedClassAndPoints. 109 std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const; 110 111 template <typename EscapeTag, EscapeTag Tag> 112 void writeSnippet(raw_ostream &OS, ArrayRef<uint8_t> Bytes, 113 const char *Separator) const; 114 115 const InstructionBenchmarkClustering &Clustering_; 116 std::unique_ptr<MCContext> Context_; 117 std::unique_ptr<MCSubtargetInfo> SubtargetInfo_; 118 std::unique_ptr<MCInstrInfo> InstrInfo_; 119 std::unique_ptr<MCRegisterInfo> RegInfo_; 120 std::unique_ptr<MCAsmInfo> AsmInfo_; 121 std::unique_ptr<MCInstPrinter> InstPrinter_; 122 std::unique_ptr<MCDisassembler> Disasm_; 123 const double AnalysisInconsistencyEpsilonSquared_; 124 const bool AnalysisDisplayUnstableOpcodes_; 125 }; 126 127 } // namespace exegesis 128 } // namespace llvm 129 130 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H 131