[llvm-exegesis] Provide a way to handle memory instructions.
[llvm-core.git] / tools / llvm-exegesis / lib / BenchmarkRunner.h
blob845755ce97d0e67047b0b104481a76985e3dbc6c
1 //===-- 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 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H
17 #define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H
19 #include "Assembler.h"
20 #include "BenchmarkResult.h"
21 #include "LlvmState.h"
22 #include "MCInstrDescView.h"
23 #include "RegisterAliasing.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/Support/Error.h"
26 #include <cstdlib>
27 #include <memory>
28 #include <vector>
30 namespace exegesis {
32 // A class representing failures that happened during Benchmark, they are used
33 // to report informations to the user.
34 class BenchmarkFailure : public llvm::StringError {
35 public:
36 BenchmarkFailure(const llvm::Twine &S);
39 // A collection of instructions that are to be assembled, executed and measured.
40 struct BenchmarkConfiguration {
41 // This code is run before the Snippet is iterated. Since it is part of the
42 // measurement it should be as short as possible. It is usually used to setup
43 // the content of the Registers.
44 struct Setup {
45 std::vector<unsigned> LiveIns; // The registers that are live on entry.
46 std::vector<unsigned> RegsToDef;
48 Setup SnippetSetup;
50 // The sequence of instructions that are to be repeated.
51 std::vector<llvm::MCInst> Snippet;
53 // Informations about how this configuration was built.
54 std::string Info;
57 // Common code for all benchmark modes.
58 class BenchmarkRunner {
59 public:
60 explicit BenchmarkRunner(const LLVMState &State,
61 InstructionBenchmark::ModeE Mode);
63 virtual ~BenchmarkRunner();
65 llvm::Expected<std::vector<InstructionBenchmark>>
66 run(unsigned Opcode, unsigned NumRepetitions);
68 // Given a snippet, computes which registers the setup code needs to define.
69 std::vector<unsigned>
70 computeRegsToDef(const std::vector<InstructionInstance> &Snippet) const;
72 // Scratch space to run instructions that touch memory.
73 struct ScratchSpace {
74 static constexpr const size_t kAlignment = 1024;
75 static constexpr const size_t kSize = 1 << 20; // 1MB.
76 ScratchSpace()
77 : UnalignedPtr(llvm::make_unique<char[]>(kSize + kAlignment)),
78 AlignedPtr(
79 UnalignedPtr.get() + kAlignment -
80 (reinterpret_cast<intptr_t>(UnalignedPtr.get()) % kAlignment)) {}
81 char *ptr() const { return AlignedPtr; }
82 void clear() { std::memset(ptr(), 0, kSize); }
84 private:
85 const std::unique_ptr<char[]> UnalignedPtr;
86 char *const AlignedPtr;
89 protected:
90 const LLVMState &State;
91 const RegisterAliasingTrackerCache RATC;
93 // Generates a single instruction prototype that has a self-dependency.
94 llvm::Expected<SnippetPrototype>
95 generateSelfAliasingPrototype(const Instruction &Instr) const;
96 // Generates a single instruction prototype without assignment constraints.
97 llvm::Expected<SnippetPrototype>
98 generateUnconstrainedPrototype(const Instruction &Instr,
99 llvm::StringRef Msg) const;
101 private:
102 // API to be implemented by subclasses.
103 virtual llvm::Expected<SnippetPrototype>
104 generatePrototype(unsigned Opcode) const = 0;
106 virtual std::vector<BenchmarkMeasure>
107 runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
108 const unsigned NumRepetitions) const = 0;
110 // Internal helpers.
111 InstructionBenchmark runOne(const BenchmarkConfiguration &Configuration,
112 unsigned Opcode, unsigned NumRepetitions) const;
114 // Calls generatePrototype and expands the SnippetPrototype into one or more
115 // BenchmarkConfiguration.
116 llvm::Expected<std::vector<BenchmarkConfiguration>>
117 generateConfigurations(unsigned Opcode) const;
119 llvm::Expected<std::string>
120 writeObjectFile(const BenchmarkConfiguration::Setup &Setup,
121 llvm::ArrayRef<llvm::MCInst> Code) const;
123 const InstructionBenchmark::ModeE Mode;
125 const std::unique_ptr<ScratchSpace> Scratch;
128 } // namespace exegesis
130 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H