• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Analysis.h ----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// Analysis output for benchmark results.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H
16 #define LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H
17 
18 #include "Clustering.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/Support/Error.h"
26 #include "llvm/Support/TargetRegistry.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <memory>
29 #include <set>
30 #include <string>
31 #include <unordered_map>
32 
33 namespace exegesis {
34 
35 // A helper class to analyze benchmark results for a target.
36 class Analysis {
37 public:
38   Analysis(const llvm::Target &Target,
39            const InstructionBenchmarkClustering &Clustering);
40 
41   // Prints a csv of instructions for each cluster.
42   struct PrintClusters {};
43   // Find potential errors in the scheduling information given measurements.
44   struct PrintSchedClassInconsistencies {};
45 
46   template <typename Pass> llvm::Error run(llvm::raw_ostream &OS) const;
47 
48 private:
49   using ClusterId = InstructionBenchmarkClustering::ClusterId;
50 
51   // An llvm::MCSchedClassDesc augmented with some additional data.
52   struct SchedClass {
53     SchedClass(const llvm::MCSchedClassDesc &SD,
54                const llvm::MCSubtargetInfo &STI);
55 
56     const llvm::MCSchedClassDesc *const SCDesc;
57     const llvm::SmallVector<llvm::MCWriteProcResEntry, 8>
58         NonRedundantWriteProcRes;
59     const std::vector<std::pair<uint16_t, float>> IdealizedProcResPressure;
60   };
61 
62   // Represents the intersection of a sched class and a cluster.
63   class SchedClassCluster {
64   public:
id()65     const InstructionBenchmarkClustering::ClusterId &id() const {
66       return ClusterId;
67     }
68 
getPointIds()69     const std::vector<size_t> &getPointIds() const { return PointIds; }
70 
71     // Return the cluster centroid.
getRepresentative()72     const std::vector<BenchmarkMeasureStats> &getRepresentative() const {
73       return Representative;
74     }
75 
76     // Returns true if the cluster representative measurements match that of SC.
77     bool
78     measurementsMatch(const llvm::MCSubtargetInfo &STI, const SchedClass &SC,
79                       const InstructionBenchmarkClustering &Clustering) const;
80 
81     void addPoint(size_t PointId,
82                   const InstructionBenchmarkClustering &Clustering);
83 
84   private:
85     InstructionBenchmarkClustering::ClusterId ClusterId;
86     std::vector<size_t> PointIds;
87     // Measurement stats for the points in the SchedClassCluster.
88     std::vector<BenchmarkMeasureStats> Representative;
89   };
90 
91   void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const;
92 
93   void
94   printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
95                               const SchedClass &SC,
96                               llvm::raw_ostream &OS) const;
97   void printSchedClassDescHtml(const SchedClass &SC,
98                                llvm::raw_ostream &OS) const;
99 
100   // Builds a map of Sched Class -> indices of points that belong to the sched
101   // class.
102   std::unordered_map<unsigned, std::vector<size_t>>
103   makePointsPerSchedClass() const;
104 
105   template <typename EscapeTag, EscapeTag Tag>
106   void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef<uint8_t> Bytes,
107                     const char *Separator) const;
108 
109   const InstructionBenchmarkClustering &Clustering_;
110   llvm::MCObjectFileInfo ObjectFileInfo_;
111   std::unique_ptr<llvm::MCContext> Context_;
112   std::unique_ptr<llvm::MCSubtargetInfo> SubtargetInfo_;
113   std::unique_ptr<llvm::MCInstrInfo> InstrInfo_;
114   std::unique_ptr<llvm::MCRegisterInfo> RegInfo_;
115   std::unique_ptr<llvm::MCAsmInfo> AsmInfo_;
116   std::unique_ptr<llvm::MCInstPrinter> InstPrinter_;
117   std::unique_ptr<llvm::MCDisassembler> Disasm_;
118 };
119 
120 // Computes the idealized ProcRes Unit pressure. This is the expected
121 // distribution if the CPU scheduler can distribute the load as evenly as
122 // possible.
123 std::vector<std::pair<uint16_t, float>> computeIdealizedProcResPressure(
124     const llvm::MCSchedModel &SM,
125     llvm::SmallVector<llvm::MCWriteProcResEntry, 8> WPRS);
126 
127 } // namespace exegesis
128 
129 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H
130