blob: e38f460b79d1342b33cd1ff145c4f70acfb01403 [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
Roman Lebedevc2423fe2019-03-28 08:55:01 +000076 void addPoint(size_t PointId,
77 const InstructionBenchmarkClustering &Clustering);
78
Clement Courbet72287212018-06-04 11:11:55 +000079 // Return the cluster centroid.
Roman Lebedevc2423fe2019-03-28 08:55:01 +000080 const SchedClassClusterCentroid &getCentroid() const { return Centroid; }
Clement Courbet72287212018-06-04 11:11:55 +000081
82 // Returns true if the cluster representative measurements match that of SC.
83 bool
Clement Courbetd5a39552018-10-03 11:50:25 +000084 measurementsMatch(const llvm::MCSubtargetInfo &STI,
85 const ResolvedSchedClass &SC,
Roman Lebedev542e5d72019-02-25 09:36:12 +000086 const InstructionBenchmarkClustering &Clustering,
87 const double AnalysisInconsistencyEpsilonSquared_) const;
Clement Courbet72287212018-06-04 11:11:55 +000088
Clement Courbet72287212018-06-04 11:11:55 +000089 private:
90 InstructionBenchmarkClustering::ClusterId ClusterId;
91 std::vector<size_t> PointIds;
92 // Measurement stats for the points in the SchedClassCluster.
Roman Lebedevc2423fe2019-03-28 08:55:01 +000093 SchedClassClusterCentroid Centroid;
Clement Courbet72287212018-06-04 11:11:55 +000094 };
95
Clement Courbet17d3c252018-05-22 13:31:29 +000096 void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const;
97
Clement Courbet72287212018-06-04 11:11:55 +000098 void
99 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
Clement Courbetd5a39552018-10-03 11:50:25 +0000100 const ResolvedSchedClass &SC,
Clement Courbet72287212018-06-04 11:11:55 +0000101 llvm::raw_ostream &OS) const;
Clement Courbetd5a39552018-10-03 11:50:25 +0000102 void printSchedClassDescHtml(const ResolvedSchedClass &SC,
Clement Courbet2637e5f2018-05-24 10:47:05 +0000103 llvm::raw_ostream &OS) const;
Clement Courbet448550d2018-05-17 12:25:18 +0000104
Clement Courbetd5a39552018-10-03 11:50:25 +0000105 // A pair of (Sched Class, indices of points that belong to the sched
106 // class).
107 struct ResolvedSchedClassAndPoints {
108 explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC);
109
110 ResolvedSchedClass RSC;
111 std::vector<size_t> PointIds;
112 };
113
114 // Builds a list of ResolvedSchedClassAndPoints.
115 std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const;
Clement Courbet448550d2018-05-17 12:25:18 +0000116
Clement Courbet4273e1e2018-06-15 07:30:45 +0000117 template <typename EscapeTag, EscapeTag Tag>
118 void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef<uint8_t> Bytes,
119 const char *Separator) const;
120
Clement Courbet448550d2018-05-17 12:25:18 +0000121 const InstructionBenchmarkClustering &Clustering_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000122 llvm::MCObjectFileInfo ObjectFileInfo_;
123 std::unique_ptr<llvm::MCContext> Context_;
Clement Courbet448550d2018-05-17 12:25:18 +0000124 std::unique_ptr<llvm::MCSubtargetInfo> SubtargetInfo_;
125 std::unique_ptr<llvm::MCInstrInfo> InstrInfo_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000126 std::unique_ptr<llvm::MCRegisterInfo> RegInfo_;
127 std::unique_ptr<llvm::MCAsmInfo> AsmInfo_;
128 std::unique_ptr<llvm::MCInstPrinter> InstPrinter_;
129 std::unique_ptr<llvm::MCDisassembler> Disasm_;
Roman Lebedev542e5d72019-02-25 09:36:12 +0000130 const double AnalysisInconsistencyEpsilonSquared_;
Roman Lebedev69716392019-02-20 09:14:04 +0000131 const bool AnalysisDisplayUnstableOpcodes_;
Clement Courbet6d6c1a92018-05-16 08:47:21 +0000132};
Clement Courbet37f0ca02018-05-15 12:08:00 +0000133
Clement Courbetdf79e792018-06-01 14:18:02 +0000134// Computes the idealized ProcRes Unit pressure. This is the expected
135// distribution if the CPU scheduler can distribute the load as evenly as
136// possible.
137std::vector<std::pair<uint16_t, float>> computeIdealizedProcResPressure(
138 const llvm::MCSchedModel &SM,
139 llvm::SmallVector<llvm::MCWriteProcResEntry, 8> WPRS);
140
Clement Courbet37f0ca02018-05-15 12:08:00 +0000141} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000142} // namespace llvm
Clement Courbet37f0ca02018-05-15 12:08:00 +0000143
144#endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H