1 //===-- SnippetGenerator.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Defines the abstract SnippetGenerator class for generating code that allows 11 /// measuring a certain property of instructions (e.g. latency). 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H 16 #define LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H 17 18 #include "Assembler.h" 19 #include "BenchmarkCode.h" 20 #include "CodeTemplate.h" 21 #include "LlvmState.h" 22 #include "MCInstrDescView.h" 23 #include "RegisterAliasing.h" 24 #include "llvm/ADT/CombinationGenerator.h" 25 #include "llvm/MC/MCInst.h" 26 #include "llvm/Support/Error.h" 27 #include <cstdlib> 28 #include <memory> 29 #include <vector> 30 31 namespace llvm { 32 namespace exegesis { 33 34 std::vector<CodeTemplate> getSingleton(CodeTemplate &&CT); 35 36 // Generates code templates that has a self-dependency. 37 Expected<std::vector<CodeTemplate>> 38 generateSelfAliasingCodeTemplates(InstructionTemplate Variant); 39 40 // Generates code templates without assignment constraints. 41 Expected<std::vector<CodeTemplate>> 42 generateUnconstrainedCodeTemplates(const InstructionTemplate &Variant, 43 StringRef Msg); 44 45 // A class representing failures that happened during Benchmark, they are used 46 // to report informations to the user. 47 class SnippetGeneratorFailure : public StringError { 48 public: 49 SnippetGeneratorFailure(const Twine &S); 50 }; 51 52 // Common code for all benchmark modes. 53 class SnippetGenerator { 54 public: 55 struct Options { 56 unsigned MaxConfigsPerOpcode = 1; 57 }; 58 59 explicit SnippetGenerator(const LLVMState &State, const Options &Opts); 60 61 virtual ~SnippetGenerator(); 62 63 // Calls generateCodeTemplate and expands it into one or more BenchmarkCode. 64 Error generateConfigurations(const InstructionTemplate &Variant, 65 std::vector<BenchmarkCode> &Benchmarks, 66 const BitVector &ExtraForbiddenRegs) const; 67 68 // Given a snippet, computes which registers the setup code needs to define. 69 std::vector<RegisterValue> computeRegisterInitialValues( 70 const std::vector<InstructionTemplate> &Snippet) const; 71 72 protected: 73 const LLVMState &State; 74 const Options Opts; 75 76 private: 77 // API to be implemented by subclasses. 78 virtual Expected<std::vector<CodeTemplate>> 79 generateCodeTemplates(InstructionTemplate Variant, 80 const BitVector &ForbiddenRegisters) const = 0; 81 }; 82 83 // A global Random Number Generator to randomize configurations. 84 // FIXME: Move random number generation into an object and make it seedable for 85 // unit tests. 86 std::mt19937 &randomGenerator(); 87 88 // Picks a random unsigned integer from 0 to Max (inclusive). 89 size_t randomIndex(size_t Max); 90 91 // Picks a random bit among the bits set in Vector and returns its index. 92 // Precondition: Vector must have at least one bit set. 93 size_t randomBit(const BitVector &Vector); 94 95 // Picks a random configuration, then selects a random def and a random use from 96 // it and finally set the selected values in the provided InstructionInstances. 97 void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations, 98 InstructionTemplate &DefIB, InstructionTemplate &UseIB); 99 100 // Assigns a Random Value to all Variables in IT that are still Invalid. 101 // Do not use any of the registers in `ForbiddenRegs`. 102 Error randomizeUnsetVariables(const LLVMState &State, 103 const BitVector &ForbiddenRegs, 104 InstructionTemplate &IT); 105 106 } // namespace exegesis 107 } // namespace llvm 108 109 #endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H 110