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 const BitVector &ForbiddenRegisters); 40 41 // Generates code templates without assignment constraints. 42 Expected<std::vector<CodeTemplate>> 43 generateUnconstrainedCodeTemplates(const InstructionTemplate &Variant, 44 StringRef Msg); 45 46 // A class representing failures that happened during Benchmark, they are used 47 // to report informations to the user. 48 class SnippetGeneratorFailure : public StringError { 49 public: 50 SnippetGeneratorFailure(const Twine &S); 51 }; 52 53 // Common code for all benchmark modes. 54 class SnippetGenerator { 55 public: 56 struct Options { 57 unsigned MaxConfigsPerOpcode = 1; 58 }; 59 60 explicit SnippetGenerator(const LLVMState &State, const Options &Opts); 61 62 virtual ~SnippetGenerator(); 63 64 // Calls generateCodeTemplate and expands it into one or more BenchmarkCode. 65 Error generateConfigurations(const InstructionTemplate &Variant, 66 std::vector<BenchmarkCode> &Benchmarks, 67 const BitVector &ExtraForbiddenRegs) const; 68 69 // Given a snippet, computes which registers the setup code needs to define. 70 std::vector<RegisterValue> computeRegisterInitialValues( 71 const std::vector<InstructionTemplate> &Snippet) const; 72 73 protected: 74 const LLVMState &State; 75 const Options Opts; 76 77 private: 78 // API to be implemented by subclasses. 79 virtual Expected<std::vector<CodeTemplate>> 80 generateCodeTemplates(InstructionTemplate Variant, 81 const BitVector &ForbiddenRegisters) const = 0; 82 }; 83 84 // A global Random Number Generator to randomize configurations. 85 // FIXME: Move random number generation into an object and make it seedable for 86 // unit tests. 87 std::mt19937 &randomGenerator(); 88 89 // Picks a random unsigned integer from 0 to Max (inclusive). 90 size_t randomIndex(size_t Max); 91 92 // Picks a random bit among the bits set in Vector and returns its index. 93 // Precondition: Vector must have at least one bit set. 94 size_t randomBit(const BitVector &Vector); 95 96 // Picks a first bit that is common to these two vectors. 97 std::optional<int> getFirstCommonBit(const BitVector &A, const BitVector &B); 98 99 // Picks a random configuration, then selects a random def and a random use from 100 // it and finally set the selected values in the provided InstructionInstances. 101 void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations, 102 InstructionTemplate &DefIB, InstructionTemplate &UseIB); 103 104 // Assigns a Random Value to all Variables in IT that are still Invalid. 105 // Do not use any of the registers in `ForbiddenRegs`. 106 Error randomizeUnsetVariables(const LLVMState &State, 107 const BitVector &ForbiddenRegs, 108 InstructionTemplate &IT); 109 110 } // namespace exegesis 111 } // namespace llvm 112 113 #endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H 114