blob: 5d7ea25ecb85d0069e3a199b3e61f2ddd2140dfc [file] [log] [blame]
Clement Courbetac74acd2018-04-04 11:37:06 +00001//===-- BenchmarkRunner.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 the abstract BenchmarkRunner class for measuring a certain execution
12/// property of instructions (e.g. latency).
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H
17#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H
18
Clement Courbet0e69e2d2018-05-17 10:52:18 +000019#include "Assembler.h"
Clement Courbetac74acd2018-04-04 11:37:06 +000020#include "BenchmarkResult.h"
Clement Courbetac74acd2018-04-04 11:37:06 +000021#include "LlvmState.h"
Guillaume Chateletef6cef52018-06-20 08:52:30 +000022#include "MCInstrDescView.h"
Clement Courbet0e69e2d2018-05-17 10:52:18 +000023#include "RegisterAliasing.h"
Clement Courbetac74acd2018-04-04 11:37:06 +000024#include "llvm/MC/MCInst.h"
25#include "llvm/Support/Error.h"
Guillaume Chateletfb943542018-08-01 14:41:45 +000026#include <cstdlib>
27#include <memory>
Clement Courbetac74acd2018-04-04 11:37:06 +000028#include <vector>
29
30namespace exegesis {
31
Guillaume Chateletc9f727b2018-06-13 13:24:41 +000032// A class representing failures that happened during Benchmark, they are used
33// to report informations to the user.
34class BenchmarkFailure : public llvm::StringError {
35public:
36 BenchmarkFailure(const llvm::Twine &S);
37};
38
Guillaume Chatelet7b852cd2018-06-07 08:11:54 +000039// A collection of instructions that are to be assembled, executed and measured.
Guillaume Chatelete60866a2018-08-03 09:29:38 +000040struct BenchmarkCode {
Guillaume Chatelet7b852cd2018-06-07 08:11:54 +000041 // The sequence of instructions that are to be repeated.
Guillaume Chatelete60866a2018-08-03 09:29:38 +000042 std::vector<llvm::MCInst> Instructions;
43
44 // Before the code is executed some instructions are added to setup the
45 // registers initial values.
46 std::vector<unsigned> RegsToDef;
47
48 // We also need to provide the registers that are live on entry for the
49 // assembler to generate proper prologue/epilogue.
50 std::vector<unsigned> LiveIns;
Guillaume Chateletb4f15822018-06-07 14:00:29 +000051
52 // Informations about how this configuration was built.
53 std::string Info;
Guillaume Chatelet7b852cd2018-06-07 08:11:54 +000054};
55
Clement Courbetac74acd2018-04-04 11:37:06 +000056// Common code for all benchmark modes.
57class BenchmarkRunner {
58public:
Clement Courbet2c278cd2018-07-05 12:26:12 +000059 explicit BenchmarkRunner(const LLVMState &State,
60 InstructionBenchmark::ModeE Mode);
Clement Courbetac74acd2018-04-04 11:37:06 +000061
62 virtual ~BenchmarkRunner();
63
Guillaume Chateletb4f15822018-06-07 14:00:29 +000064 llvm::Expected<std::vector<InstructionBenchmark>>
Clement Courbet4860b982018-06-26 08:49:30 +000065 run(unsigned Opcode, unsigned NumRepetitions);
Clement Courbet0e69e2d2018-05-17 10:52:18 +000066
Clement Courbeta51efc22018-06-25 13:12:02 +000067 // Given a snippet, computes which registers the setup code needs to define.
68 std::vector<unsigned>
Guillaume Chatelet171f3f42018-08-02 11:12:02 +000069 computeRegsToDef(const std::vector<InstructionBuilder> &Snippet) const;
Clement Courbeta51efc22018-06-25 13:12:02 +000070
Guillaume Chateletfb943542018-08-01 14:41:45 +000071 // Scratch space to run instructions that touch memory.
72 struct ScratchSpace {
73 static constexpr const size_t kAlignment = 1024;
74 static constexpr const size_t kSize = 1 << 20; // 1MB.
75 ScratchSpace()
76 : UnalignedPtr(llvm::make_unique<char[]>(kSize + kAlignment)),
77 AlignedPtr(
78 UnalignedPtr.get() + kAlignment -
79 (reinterpret_cast<intptr_t>(UnalignedPtr.get()) % kAlignment)) {}
80 char *ptr() const { return AlignedPtr; }
81 void clear() { std::memset(ptr(), 0, kSize); }
82
83 private:
84 const std::unique_ptr<char[]> UnalignedPtr;
85 char *const AlignedPtr;
86 };
87
Clement Courbet0e69e2d2018-05-17 10:52:18 +000088protected:
89 const LLVMState &State;
Guillaume Chateletc9f727b2018-06-13 13:24:41 +000090 const RegisterAliasingTrackerCache RATC;
Clement Courbetac74acd2018-04-04 11:37:06 +000091
Guillaume Chatelete60866a2018-08-03 09:29:38 +000092 // Generates a single code template that has a self-dependency.
93 llvm::Expected<CodeTemplate>
94 generateSelfAliasingCodeTemplate(const Instruction &Instr) const;
95 // Generates a single code template without assignment constraints.
96 llvm::Expected<CodeTemplate>
97 generateUnconstrainedCodeTemplate(const Instruction &Instr,
98 llvm::StringRef Msg) const;
Clement Courbet717c9762018-06-28 07:41:16 +000099
Clement Courbetac74acd2018-04-04 11:37:06 +0000100private:
Clement Courbet4860b982018-06-26 08:49:30 +0000101 // API to be implemented by subclasses.
Guillaume Chatelete60866a2018-08-03 09:29:38 +0000102 virtual llvm::Expected<CodeTemplate>
103 generateCodeTemplate(unsigned Opcode) const = 0;
Clement Courbet4860b982018-06-26 08:49:30 +0000104
105 virtual std::vector<BenchmarkMeasure>
Guillaume Chateletfb943542018-08-01 14:41:45 +0000106 runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
Clement Courbet2c278cd2018-07-05 12:26:12 +0000107 const unsigned NumRepetitions) const = 0;
Clement Courbet4860b982018-06-26 08:49:30 +0000108
109 // Internal helpers.
Guillaume Chatelete60866a2018-08-03 09:29:38 +0000110 InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration,
Guillaume Chatelete60866a2018-08-03 09:29:38 +0000111 unsigned NumRepetitions) const;
Guillaume Chateletb4f15822018-06-07 14:00:29 +0000112
Guillaume Chatelete60866a2018-08-03 09:29:38 +0000113 // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
114 llvm::Expected<std::vector<BenchmarkCode>>
Guillaume Chateletef6cef52018-06-20 08:52:30 +0000115 generateConfigurations(unsigned Opcode) const;
116
Clement Courbet0e69e2d2018-05-17 10:52:18 +0000117 llvm::Expected<std::string>
Guillaume Chatelete60866a2018-08-03 09:29:38 +0000118 writeObjectFile(const BenchmarkCode &Configuration,
Clement Courbeta51efc22018-06-25 13:12:02 +0000119 llvm::ArrayRef<llvm::MCInst> Code) const;
Clement Courbet4860b982018-06-26 08:49:30 +0000120
121 const InstructionBenchmark::ModeE Mode;
Guillaume Chateletfb943542018-08-01 14:41:45 +0000122
123 const std::unique_ptr<ScratchSpace> Scratch;
Clement Courbetac74acd2018-04-04 11:37:06 +0000124};
125
126} // namespace exegesis
127
128#endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H