blob: a52ea27081cf1adf4528e26bdd2f7004c97d0549 [file] [log] [blame]
Clement Courbet37f0ca02018-05-15 12:08:00 +00001//===-- 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"
Clement Courbet4273e1e2018-06-15 07:30:45 +000019#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCDisassembler/MCDisassembler.h"
21#include "llvm/MC/MCInstPrinter.h"
Clement Courbet6d6c1a92018-05-16 08:47:21 +000022#include "llvm/MC/MCInstrInfo.h"
Clement Courbet4273e1e2018-06-15 07:30:45 +000023#include "llvm/MC/MCObjectFileInfo.h"
Clement Courbet37f0ca02018-05-15 12:08:00 +000024#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/Support/Error.h"
Clement Courbet448550d2018-05-17 12:25:18 +000026#include "llvm/Support/TargetRegistry.h"
Clement Courbet37f0ca02018-05-15 12:08:00 +000027#include "llvm/Support/raw_ostream.h"
Clement Courbet4273e1e2018-06-15 07:30:45 +000028#include <memory>
Clement Courbet72287212018-06-04 11:11:55 +000029#include <set>
Clement Courbet6d6c1a92018-05-16 08:47:21 +000030#include <string>
31#include <unordered_map>
Clement Courbet37f0ca02018-05-15 12:08:00 +000032
33namespace 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,
39 const InstructionBenchmarkClustering &Clustering);
Clement Courbet6d6c1a92018-05-16 08:47:21 +000040
41 // Prints a csv of instructions for each cluster.
Clement Courbetcf210742018-05-17 13:41:28 +000042 struct PrintClusters {};
Clement Courbet448550d2018-05-17 12:25:18 +000043 // Find potential errors in the scheduling information given measurements.
Clement Courbetcf210742018-05-17 13:41:28 +000044 struct PrintSchedClassInconsistencies {};
45
46 template <typename Pass> llvm::Error run(llvm::raw_ostream &OS) const;
Clement Courbet6d6c1a92018-05-16 08:47:21 +000047
Clement Courbet448550d2018-05-17 12:25:18 +000048private:
Clement Courbet72287212018-06-04 11:11:55 +000049 using ClusterId = InstructionBenchmarkClustering::ClusterId;
50
51 // An llvm::MCSchedClassDesc augmented with some additional data.
Clement Courbetd5a39552018-10-03 11:50:25 +000052 struct ResolvedSchedClass {
53 ResolvedSchedClass(const llvm::MCSubtargetInfo &STI,
54 unsigned ResolvedSchedClassId, bool WasVariant);
Clement Courbet72287212018-06-04 11:11:55 +000055
Clement Courbet4273e1e2018-06-15 07:30:45 +000056 const llvm::MCSchedClassDesc *const SCDesc;
Clement Courbetd5a39552018-10-03 11:50:25 +000057 const bool WasVariant; // Whether the original class was variant.
Clement Courbet72287212018-06-04 11:11:55 +000058 const llvm::SmallVector<llvm::MCWriteProcResEntry, 8>
59 NonRedundantWriteProcRes;
60 const std::vector<std::pair<uint16_t, float>> IdealizedProcResPressure;
61 };
62
63 // Represents the intersection of a sched class and a cluster.
64 class SchedClassCluster {
65 public:
66 const InstructionBenchmarkClustering::ClusterId &id() const {
67 return ClusterId;
68 }
69
70 const std::vector<size_t> &getPointIds() const { return PointIds; }
71
72 // Return the cluster centroid.
Clement Courbet684a5f62018-09-26 08:37:21 +000073 const std::vector<PerInstructionStats> &getRepresentative() const {
Clement Courbet72287212018-06-04 11:11:55 +000074 return Representative;
75 }
76
77 // Returns true if the cluster representative measurements match that of SC.
78 bool
Clement Courbetd5a39552018-10-03 11:50:25 +000079 measurementsMatch(const llvm::MCSubtargetInfo &STI,
80 const ResolvedSchedClass &SC,
Clement Courbet72287212018-06-04 11:11:55 +000081 const InstructionBenchmarkClustering &Clustering) const;
82
83 void addPoint(size_t PointId,
84 const InstructionBenchmarkClustering &Clustering);
85
86 private:
87 InstructionBenchmarkClustering::ClusterId ClusterId;
88 std::vector<size_t> PointIds;
89 // Measurement stats for the points in the SchedClassCluster.
Clement Courbet684a5f62018-09-26 08:37:21 +000090 std::vector<PerInstructionStats> Representative;
Clement Courbet72287212018-06-04 11:11:55 +000091 };
92
Clement Courbet17d3c252018-05-22 13:31:29 +000093 void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const;
94
Clement Courbet72287212018-06-04 11:11:55 +000095 void
96 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
Clement Courbetd5a39552018-10-03 11:50:25 +000097 const ResolvedSchedClass &SC,
Clement Courbet72287212018-06-04 11:11:55 +000098 llvm::raw_ostream &OS) const;
Clement Courbetd5a39552018-10-03 11:50:25 +000099 void printSchedClassDescHtml(const ResolvedSchedClass &SC,
Clement Courbet2637e5f2018-05-24 10:47:05 +0000100 llvm::raw_ostream &OS) const;
Clement Courbet448550d2018-05-17 12:25:18 +0000101
Clement Courbetd5a39552018-10-03 11:50:25 +0000102 // A pair of (Sched Class, indices of points that belong to the sched
103 // class).
104 struct ResolvedSchedClassAndPoints {
105 explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC);
106
107 ResolvedSchedClass RSC;
108 std::vector<size_t> PointIds;
109 };
110
111 // Builds a list of ResolvedSchedClassAndPoints.
112 std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const;
Clement Courbet448550d2018-05-17 12:25:18 +0000113
Clement Courbet4273e1e2018-06-15 07:30:45 +0000114 template <typename EscapeTag, EscapeTag Tag>
115 void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef<uint8_t> Bytes,
116 const char *Separator) const;
117
Clement Courbet448550d2018-05-17 12:25:18 +0000118 const InstructionBenchmarkClustering &Clustering_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000119 llvm::MCObjectFileInfo ObjectFileInfo_;
120 std::unique_ptr<llvm::MCContext> Context_;
Clement Courbet448550d2018-05-17 12:25:18 +0000121 std::unique_ptr<llvm::MCSubtargetInfo> SubtargetInfo_;
122 std::unique_ptr<llvm::MCInstrInfo> InstrInfo_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000123 std::unique_ptr<llvm::MCRegisterInfo> RegInfo_;
124 std::unique_ptr<llvm::MCAsmInfo> AsmInfo_;
125 std::unique_ptr<llvm::MCInstPrinter> InstPrinter_;
126 std::unique_ptr<llvm::MCDisassembler> Disasm_;
Clement Courbet6d6c1a92018-05-16 08:47:21 +0000127};
Clement Courbet37f0ca02018-05-15 12:08:00 +0000128
Clement Courbetdf79e792018-06-01 14:18:02 +0000129// Computes the idealized ProcRes Unit pressure. This is the expected
130// distribution if the CPU scheduler can distribute the load as evenly as
131// possible.
132std::vector<std::pair<uint16_t, float>> computeIdealizedProcResPressure(
133 const llvm::MCSchedModel &SM,
134 llvm::SmallVector<llvm::MCWriteProcResEntry, 8> WPRS);
135
Clement Courbet37f0ca02018-05-15 12:08:00 +0000136} // namespace exegesis
137
138#endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H