Home | History | Annotate | Download | only in lib
      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