blob: 1a0859ee512d0b1921f3a9dd9fb93032bed1e110 [file] [log] [blame]
Clement Courbet37f0ca02018-05-15 12:08:00 +00001//===-- Analysis.h ----------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Clement Courbet37f0ca02018-05-15 12:08:00 +00006//
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"
Clement Courbet4273e1e2018-06-15 07:30:45 +000018#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCDisassembler/MCDisassembler.h"
20#include "llvm/MC/MCInstPrinter.h"
Clement Courbet6d6c1a92018-05-16 08:47:21 +000021#include "llvm/MC/MCInstrInfo.h"
Clement Courbet4273e1e2018-06-15 07:30:45 +000022#include "llvm/MC/MCObjectFileInfo.h"
Clement Courbet37f0ca02018-05-15 12:08:00 +000023#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/Support/Error.h"
Clement Courbet448550d2018-05-17 12:25:18 +000025#include "llvm/Support/TargetRegistry.h"
Clement Courbet37f0ca02018-05-15 12:08:00 +000026#include "llvm/Support/raw_ostream.h"
Clement Courbet4273e1e2018-06-15 07:30:45 +000027#include <memory>
Clement Courbet72287212018-06-04 11:11:55 +000028#include <set>
Clement Courbet6d6c1a92018-05-16 08:47:21 +000029#include <string>
30#include <unordered_map>
Clement Courbet37f0ca02018-05-15 12:08:00 +000031
Fangrui Song32401af2018-10-22 17:10:47 +000032namespace llvm {
Clement Courbet37f0ca02018-05-15 12:08:00 +000033namespace exegesis {
34
Clement Courbet6d6c1a92018-05-16 08:47:21 +000035// A helper class to analyze benchmark results for a target.
36class Analysis {
37public:
Clement Courbet448550d2018-05-17 12:25:18 +000038 Analysis(const llvm::Target &Target,
Roman Lebedev69716392019-02-20 09:14:04 +000039 std::unique_ptr<llvm::MCInstrInfo> InstrInfo,
40 const InstructionBenchmarkClustering &Clustering,
Roman Lebedev542e5d72019-02-25 09:36:12 +000041 double AnalysisInconsistencyEpsilon,
Roman Lebedev69716392019-02-20 09:14:04 +000042 bool AnalysisDisplayUnstableOpcodes);
Clement Courbet6d6c1a92018-05-16 08:47:21 +000043
44 // Prints a csv of instructions for each cluster.
Clement Courbetcf210742018-05-17 13:41:28 +000045 struct PrintClusters {};
Clement Courbet448550d2018-05-17 12:25:18 +000046 // Find potential errors in the scheduling information given measurements.
Clement Courbetcf210742018-05-17 13:41:28 +000047 struct PrintSchedClassInconsistencies {};
48
49 template <typename Pass> llvm::Error run(llvm::raw_ostream &OS) const;
Clement Courbet6d6c1a92018-05-16 08:47:21 +000050
Clement Courbet448550d2018-05-17 12:25:18 +000051private:
Clement Courbet72287212018-06-04 11:11:55 +000052 using ClusterId = InstructionBenchmarkClustering::ClusterId;
53
54 // An llvm::MCSchedClassDesc augmented with some additional data.
Clement Courbetd5a39552018-10-03 11:50:25 +000055 struct ResolvedSchedClass {
56 ResolvedSchedClass(const llvm::MCSubtargetInfo &STI,
57 unsigned ResolvedSchedClassId, bool WasVariant);
Clement Courbet72287212018-06-04 11:11:55 +000058
Clement Courbet8a5a6be2018-10-03 12:35:35 +000059 const unsigned SchedClassId;
Clement Courbet4273e1e2018-06-15 07:30:45 +000060 const llvm::MCSchedClassDesc *const SCDesc;
Clement Courbetd5a39552018-10-03 11:50:25 +000061 const bool WasVariant; // Whether the original class was variant.
Clement Courbet72287212018-06-04 11:11:55 +000062 const llvm::SmallVector<llvm::MCWriteProcResEntry, 8>
63 NonRedundantWriteProcRes;
64 const std::vector<std::pair<uint16_t, float>> IdealizedProcResPressure;
65 };
66
67 // Represents the intersection of a sched class and a cluster.
68 class SchedClassCluster {
69 public:
70 const InstructionBenchmarkClustering::ClusterId &id() const {
71 return ClusterId;
72 }
73
74 const std::vector<size_t> &getPointIds() const { return PointIds; }
75
76 // Return the cluster centroid.
Clement Courbet684a5f62018-09-26 08:37:21 +000077 const std::vector<PerInstructionStats> &getRepresentative() const {
Clement Courbet72287212018-06-04 11:11:55 +000078 return Representative;
79 }
80
81 // Returns true if the cluster representative measurements match that of SC.
82 bool
Clement Courbetd5a39552018-10-03 11:50:25 +000083 measurementsMatch(const llvm::MCSubtargetInfo &STI,
84 const ResolvedSchedClass &SC,
Roman Lebedev542e5d72019-02-25 09:36:12 +000085 const InstructionBenchmarkClustering &Clustering,
86 const double AnalysisInconsistencyEpsilonSquared_) const;
Clement Courbet72287212018-06-04 11:11:55 +000087
88 void addPoint(size_t PointId,
89 const InstructionBenchmarkClustering &Clustering);
90
91 private:
92 InstructionBenchmarkClustering::ClusterId ClusterId;
93 std::vector<size_t> PointIds;
94 // Measurement stats for the points in the SchedClassCluster.
Clement Courbet684a5f62018-09-26 08:37:21 +000095 std::vector<PerInstructionStats> Representative;
Clement Courbet72287212018-06-04 11:11:55 +000096 };
97
Clement Courbet17d3c252018-05-22 13:31:29 +000098 void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const;
99
Clement Courbet72287212018-06-04 11:11:55 +0000100 void
101 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
Clement Courbetd5a39552018-10-03 11:50:25 +0000102 const ResolvedSchedClass &SC,
Clement Courbet72287212018-06-04 11:11:55 +0000103 llvm::raw_ostream &OS) const;
Clement Courbetd5a39552018-10-03 11:50:25 +0000104 void printSchedClassDescHtml(const ResolvedSchedClass &SC,
Clement Courbet2637e5f2018-05-24 10:47:05 +0000105 llvm::raw_ostream &OS) const;
Clement Courbet448550d2018-05-17 12:25:18 +0000106
Clement Courbetd5a39552018-10-03 11:50:25 +0000107 // A pair of (Sched Class, indices of points that belong to the sched
108 // class).
109 struct ResolvedSchedClassAndPoints {
110 explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC);
111
112 ResolvedSchedClass RSC;
113 std::vector<size_t> PointIds;
114 };
115
116 // Builds a list of ResolvedSchedClassAndPoints.
117 std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const;
Clement Courbet448550d2018-05-17 12:25:18 +0000118
Clement Courbet4273e1e2018-06-15 07:30:45 +0000119 template <typename EscapeTag, EscapeTag Tag>
120 void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef<uint8_t> Bytes,
121 const char *Separator) const;
122
Clement Courbet448550d2018-05-17 12:25:18 +0000123 const InstructionBenchmarkClustering &Clustering_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000124 llvm::MCObjectFileInfo ObjectFileInfo_;
125 std::unique_ptr<llvm::MCContext> Context_;
Clement Courbet448550d2018-05-17 12:25:18 +0000126 std::unique_ptr<llvm::MCSubtargetInfo> SubtargetInfo_;
127 std::unique_ptr<llvm::MCInstrInfo> InstrInfo_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000128 std::unique_ptr<llvm::MCRegisterInfo> RegInfo_;
129 std::unique_ptr<llvm::MCAsmInfo> AsmInfo_;
130 std::unique_ptr<llvm::MCInstPrinter> InstPrinter_;
131 std::unique_ptr<llvm::MCDisassembler> Disasm_;
Roman Lebedev542e5d72019-02-25 09:36:12 +0000132 const double AnalysisInconsistencyEpsilonSquared_;
Roman Lebedev69716392019-02-20 09:14:04 +0000133 const bool AnalysisDisplayUnstableOpcodes_;
Clement Courbet6d6c1a92018-05-16 08:47:21 +0000134};
Clement Courbet37f0ca02018-05-15 12:08:00 +0000135
Clement Courbetdf79e792018-06-01 14:18:02 +0000136// Computes the idealized ProcRes Unit pressure. This is the expected
137// distribution if the CPU scheduler can distribute the load as evenly as
138// possible.
139std::vector<std::pair<uint16_t, float>> computeIdealizedProcResPressure(
140 const llvm::MCSchedModel &SM,
141 llvm::SmallVector<llvm::MCWriteProcResEntry, 8> WPRS);
142
Clement Courbet37f0ca02018-05-15 12:08:00 +0000143} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000144} // namespace llvm
Clement Courbet37f0ca02018-05-15 12:08:00 +0000145
146#endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H