blob: 5fa9af8e9d3d24b10e51855c1d0e6823e01b53aa [file] [log] [blame]
Clement Courbetac74acd2018-04-04 11:37:06 +00001//===-- BenchmarkResult.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/// Defines classes to represent measurements and serialize/deserialize them to
12// Yaml.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H
17#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H
18
Clement Courbet53d35d22018-06-05 10:56:19 +000019#include "llvm/ADT/StringMap.h"
Clement Courbetac74acd2018-04-04 11:37:06 +000020#include "llvm/ADT/StringRef.h"
Clement Courbet53d35d22018-06-05 10:56:19 +000021#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstBuilder.h"
Clement Courbetac74acd2018-04-04 11:37:06 +000023#include "llvm/Support/YAMLTraits.h"
Clement Courbetae8ae5dc2018-05-24 12:41:02 +000024#include <limits>
Clement Courbetac74acd2018-04-04 11:37:06 +000025#include <string>
Clement Courbet53d35d22018-06-05 10:56:19 +000026#include <unordered_map>
Clement Courbetac74acd2018-04-04 11:37:06 +000027#include <vector>
28
29namespace exegesis {
30
Clement Courbet53d35d22018-06-05 10:56:19 +000031struct BenchmarkResultContext; // Forward declaration.
32
Clement Courbeta66bfaa42018-05-15 13:07:05 +000033struct InstructionBenchmarkKey {
34 // The LLVM opcode name.
Clement Courbet53d35d22018-06-05 10:56:19 +000035 std::string OpcodeName; // FIXME: Deprecated, use Instructions below.
36 std::vector<llvm::MCInst> Instructions;
Clement Courbeta66bfaa42018-05-15 13:07:05 +000037 // An opaque configuration, that can be used to separate several benchmarks of
38 // the same instruction under different configurations.
39 std::string Config;
Clement Courbetac74acd2018-04-04 11:37:06 +000040};
41
42struct BenchmarkMeasure {
43 std::string Key;
44 double Value;
45 std::string DebugString;
46};
47
48// The result of an instruction benchmark.
49struct InstructionBenchmark {
Clement Courbeta66bfaa42018-05-15 13:07:05 +000050 InstructionBenchmarkKey Key;
Clement Courbet62b34fa2018-06-06 09:42:36 +000051 enum ModeE { Unknown, Latency, Uops };
52 ModeE Mode;
Clement Courbetac74acd2018-04-04 11:37:06 +000053 std::string CpuName;
54 std::string LLVMTriple;
Clement Courbet8fb6e402018-04-04 12:01:46 +000055 int NumRepetitions = 0;
Clement Courbetac74acd2018-04-04 11:37:06 +000056 std::vector<BenchmarkMeasure> Measurements;
57 std::string Error;
Clement Courbeta66bfaa42018-05-15 13:07:05 +000058 std::string Info;
Clement Courbetac74acd2018-04-04 11:37:06 +000059
Clement Courbet0e69e2d2018-05-17 10:52:18 +000060 // Read functions.
Guillaume Chatelet8c91d4c2018-06-07 07:51:16 +000061 static llvm::Expected<InstructionBenchmark>
62 readYaml(const BenchmarkResultContext &Context, llvm::StringRef Filename);
Clement Courbet53d35d22018-06-05 10:56:19 +000063
Guillaume Chatelet8c91d4c2018-06-07 07:51:16 +000064 static llvm::Expected<std::vector<InstructionBenchmark>>
65 readYamls(const BenchmarkResultContext &Context, llvm::StringRef Filename);
Clement Courbet53d35d22018-06-05 10:56:19 +000066
67 void readYamlFrom(const BenchmarkResultContext &Context,
68 llvm::StringRef InputContent);
Clement Courbet0e69e2d2018-05-17 10:52:18 +000069
70 // Write functions, non-const because of YAML traits.
Clement Courbet53d35d22018-06-05 10:56:19 +000071 void writeYamlTo(const BenchmarkResultContext &Context, llvm::raw_ostream &S);
72
Guillaume Chatelet8c91d4c2018-06-07 07:51:16 +000073 llvm::Error writeYaml(const BenchmarkResultContext &Context,
74 const llvm::StringRef Filename);
Clement Courbetac74acd2018-04-04 11:37:06 +000075};
76
Clement Courbetae8ae5dc2018-05-24 12:41:02 +000077//------------------------------------------------------------------------------
78// Utilities to work with Benchmark measures.
79
80// A class that measures stats over benchmark measures.
81class BenchmarkMeasureStats {
82public:
83 void push(const BenchmarkMeasure &BM);
84
85 double avg() const {
86 assert(NumValues);
87 return SumValues / NumValues;
88 }
89 double min() const { return MinValue; }
90 double max() const { return MaxValue; }
91
Clement Courbet72287212018-06-04 11:11:55 +000092 const std::string &key() const { return Key; }
93
Clement Courbetae8ae5dc2018-05-24 12:41:02 +000094private:
95 std::string Key;
96 double SumValues = 0.0;
97 int NumValues = 0;
98 double MaxValue = std::numeric_limits<double>::min();
99 double MinValue = std::numeric_limits<double>::max();
100};
101
Clement Courbet53d35d22018-06-05 10:56:19 +0000102// This context is used when de/serializing InstructionBenchmark to guarantee
103// that Registers and Instructions are human readable and preserved accross
104// different versions of LLVM.
105struct BenchmarkResultContext {
106 BenchmarkResultContext() = default;
107 BenchmarkResultContext(BenchmarkResultContext &&) = default;
108 BenchmarkResultContext &operator=(BenchmarkResultContext &&) = default;
109 BenchmarkResultContext(const BenchmarkResultContext &) = delete;
110 BenchmarkResultContext &operator=(const BenchmarkResultContext &) = delete;
111
112 // Populate Registers and Instruction mapping.
113 void addRegEntry(unsigned RegNo, llvm::StringRef Name);
114 void addInstrEntry(unsigned Opcode, llvm::StringRef Name);
115
116 // Register accessors.
117 llvm::StringRef getRegName(unsigned RegNo) const;
118 unsigned getRegNo(llvm::StringRef Name) const; // 0 is not found.
119
120 // Instruction accessors.
121 llvm::StringRef getInstrName(unsigned Opcode) const;
122 unsigned getInstrOpcode(llvm::StringRef Name) const; // 0 is not found.
123
124private:
125 // Ideally we would like to use MCRegisterInfo and MCInstrInfo but doing so
126 // would make testing harder, instead we create a mapping that we can easily
127 // populate.
128 std::unordered_map<unsigned, llvm::StringRef> InstrOpcodeToName;
129 std::unordered_map<unsigned, llvm::StringRef> RegNoToName;
130 llvm::StringMap<unsigned> InstrNameToOpcode;
131 llvm::StringMap<unsigned> RegNameToNo;
132};
133
Clement Courbetac74acd2018-04-04 11:37:06 +0000134} // namespace exegesis
135
136#endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H