blob: 15bd832af0a2698bcc00b0ea5ef2b7aff0c7eb6d [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"
Roman Lebedev1d1330c2019-03-29 14:24:27 +000018#include "SchedClassResolution.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
Fangrui Song32401af2018-10-22 17:10:47 +000033namespace llvm {
Clement Courbet37f0ca02018-05-15 12:08:00 +000034namespace exegesis {
35
Clement Courbet6d6c1a92018-05-16 08:47:21 +000036// A helper class to analyze benchmark results for a target.
37class Analysis {
38public:
Clement Courbet448550d2018-05-17 12:25:18 +000039 Analysis(const llvm::Target &Target,
Roman Lebedev69716392019-02-20 09:14:04 +000040 std::unique_ptr<llvm::MCInstrInfo> InstrInfo,
41 const InstructionBenchmarkClustering &Clustering,
Roman Lebedev542e5d72019-02-25 09:36:12 +000042 double AnalysisInconsistencyEpsilon,
Roman Lebedev69716392019-02-20 09:14:04 +000043 bool AnalysisDisplayUnstableOpcodes);
Clement Courbet6d6c1a92018-05-16 08:47:21 +000044
45 // Prints a csv of instructions for each cluster.
Clement Courbetcf210742018-05-17 13:41:28 +000046 struct PrintClusters {};
Clement Courbet448550d2018-05-17 12:25:18 +000047 // Find potential errors in the scheduling information given measurements.
Clement Courbetcf210742018-05-17 13:41:28 +000048 struct PrintSchedClassInconsistencies {};
49
50 template <typename Pass> llvm::Error run(llvm::raw_ostream &OS) const;
Clement Courbet6d6c1a92018-05-16 08:47:21 +000051
Clement Courbet448550d2018-05-17 12:25:18 +000052private:
Clement Courbet72287212018-06-04 11:11:55 +000053 using ClusterId = InstructionBenchmarkClustering::ClusterId;
54
Clement Courbet72287212018-06-04 11:11:55 +000055 // Represents the intersection of a sched class and a cluster.
56 class SchedClassCluster {
57 public:
58 const InstructionBenchmarkClustering::ClusterId &id() const {
59 return ClusterId;
60 }
61
62 const std::vector<size_t> &getPointIds() const { return PointIds; }
63
Roman Lebedevc2423fe2019-03-28 08:55:01 +000064 void addPoint(size_t PointId,
65 const InstructionBenchmarkClustering &Clustering);
66
Clement Courbet72287212018-06-04 11:11:55 +000067 // Return the cluster centroid.
Roman Lebedevc2423fe2019-03-28 08:55:01 +000068 const SchedClassClusterCentroid &getCentroid() const { return Centroid; }
Clement Courbet72287212018-06-04 11:11:55 +000069
Roman Lebedevb8fb15d2019-03-29 11:36:08 +000070 std::vector<BenchmarkMeasure>
71 getSchedClassPoint(InstructionBenchmark::ModeE Mode,
72 const llvm::MCSubtargetInfo &STI,
73 const ResolvedSchedClass &SC,
74 ArrayRef<PerInstructionStats> Representative) const;
75
Clement Courbet72287212018-06-04 11:11:55 +000076 // Returns true if the cluster representative measurements match that of SC.
77 bool
Clement Courbetd5a39552018-10-03 11:50:25 +000078 measurementsMatch(const llvm::MCSubtargetInfo &STI,
79 const ResolvedSchedClass &SC,
Roman Lebedev542e5d72019-02-25 09:36:12 +000080 const InstructionBenchmarkClustering &Clustering,
81 const double AnalysisInconsistencyEpsilonSquared_) const;
Clement Courbet72287212018-06-04 11:11:55 +000082
Clement Courbet72287212018-06-04 11:11:55 +000083 private:
84 InstructionBenchmarkClustering::ClusterId ClusterId;
85 std::vector<size_t> PointIds;
86 // Measurement stats for the points in the SchedClassCluster.
Roman Lebedevc2423fe2019-03-28 08:55:01 +000087 SchedClassClusterCentroid Centroid;
Clement Courbet72287212018-06-04 11:11:55 +000088 };
89
Clement Courbet17d3c252018-05-22 13:31:29 +000090 void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const;
91
Clement Courbet72287212018-06-04 11:11:55 +000092 void
93 printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
Clement Courbetd5a39552018-10-03 11:50:25 +000094 const ResolvedSchedClass &SC,
Clement Courbet72287212018-06-04 11:11:55 +000095 llvm::raw_ostream &OS) const;
Clement Courbetd5a39552018-10-03 11:50:25 +000096 void printSchedClassDescHtml(const ResolvedSchedClass &SC,
Clement Courbet2637e5f2018-05-24 10:47:05 +000097 llvm::raw_ostream &OS) const;
Clement Courbet448550d2018-05-17 12:25:18 +000098
Clement Courbetd5a39552018-10-03 11:50:25 +000099 // 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;
Clement Courbet448550d2018-05-17 12:25:18 +0000110
Clement Courbet4273e1e2018-06-15 07:30:45 +0000111 template <typename EscapeTag, EscapeTag Tag>
112 void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef<uint8_t> Bytes,
113 const char *Separator) const;
114
Clement Courbet448550d2018-05-17 12:25:18 +0000115 const InstructionBenchmarkClustering &Clustering_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000116 llvm::MCObjectFileInfo ObjectFileInfo_;
117 std::unique_ptr<llvm::MCContext> Context_;
Clement Courbet448550d2018-05-17 12:25:18 +0000118 std::unique_ptr<llvm::MCSubtargetInfo> SubtargetInfo_;
119 std::unique_ptr<llvm::MCInstrInfo> InstrInfo_;
Clement Courbet4273e1e2018-06-15 07:30:45 +0000120 std::unique_ptr<llvm::MCRegisterInfo> RegInfo_;
121 std::unique_ptr<llvm::MCAsmInfo> AsmInfo_;
122 std::unique_ptr<llvm::MCInstPrinter> InstPrinter_;
123 std::unique_ptr<llvm::MCDisassembler> Disasm_;
Roman Lebedev542e5d72019-02-25 09:36:12 +0000124 const double AnalysisInconsistencyEpsilonSquared_;
Roman Lebedev69716392019-02-20 09:14:04 +0000125 const bool AnalysisDisplayUnstableOpcodes_;
Clement Courbet6d6c1a92018-05-16 08:47:21 +0000126};
Clement Courbet37f0ca02018-05-15 12:08:00 +0000127
Clement Courbet37f0ca02018-05-15 12:08:00 +0000128} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000129} // namespace llvm
Clement Courbet37f0ca02018-05-15 12:08:00 +0000130
131#endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H