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 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H 17 #define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H 18 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 <vector> 27 28 namespace exegesis { 29 30 // A class representing failures that happened during Benchmark, they are used 31 // to report informations to the user. 32 class BenchmarkFailure : public llvm::StringError { 33 public: 34 BenchmarkFailure(const llvm::Twine &S); 35 }; 36 37 // A collection of instructions that are to be assembled, executed and measured. 38 struct BenchmarkConfiguration { 39 // This code is run before the Snippet is iterated. Since it is part of the 40 // measurement it should be as short as possible. It is usually used to setup 41 // the content of the Registers. 42 struct Setup { 43 std::vector<unsigned> RegsToDef; 44 }; 45 Setup SnippetSetup; 46 47 // The sequence of instructions that are to be repeated. 48 std::vector<llvm::MCInst> Snippet; 49 50 // Informations about how this configuration was built. 51 std::string Info; 52 }; 53 54 // Common code for all benchmark modes. 55 class BenchmarkRunner { 56 public: 57 explicit BenchmarkRunner(const LLVMState &State, 58 InstructionBenchmark::ModeE Mode); 59 60 virtual ~BenchmarkRunner(); 61 62 llvm::Expected<std::vector<InstructionBenchmark>> 63 run(unsigned Opcode, unsigned NumRepetitions); 64 65 // Given a snippet, computes which registers the setup code needs to define. 66 std::vector<unsigned> 67 computeRegsToDef(const std::vector<InstructionInstance> &Snippet) const; 68 69 protected: 70 const LLVMState &State; 71 const RegisterAliasingTrackerCache RATC; 72 73 // Generates a single instruction prototype that has a self-dependency. 74 llvm::Expected<SnippetPrototype> 75 generateSelfAliasingPrototype(const Instruction &Instr) const; 76 // Generates a single instruction prototype without assignment constraints. 77 llvm::Expected<SnippetPrototype> 78 generateUnconstrainedPrototype(const Instruction &Instr, 79 llvm::StringRef Msg) const; 80 81 private: 82 // API to be implemented by subclasses. 83 virtual llvm::Expected<SnippetPrototype> 84 generatePrototype(unsigned Opcode) const = 0; 85 86 virtual std::vector<BenchmarkMeasure> 87 runMeasurements(const ExecutableFunction &EF, 88 const unsigned NumRepetitions) const = 0; 89 90 // Internal helpers. 91 InstructionBenchmark runOne(const BenchmarkConfiguration &Configuration, 92 unsigned Opcode, unsigned NumRepetitions) const; 93 94 // Calls generatePrototype and expands the SnippetPrototype into one or more 95 // BenchmarkConfiguration. 96 llvm::Expected<std::vector<BenchmarkConfiguration>> 97 generateConfigurations(unsigned Opcode) const; 98 99 llvm::Expected<std::string> 100 writeObjectFile(const BenchmarkConfiguration::Setup &Setup, 101 llvm::ArrayRef<llvm::MCInst> Code) const; 102 103 const InstructionBenchmark::ModeE Mode; 104 }; 105 106 } // namespace exegesis 107 108 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H 109