1 //===-- MCInstrDescView.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 /// Provide views around LLVM structures to represents an instruction instance, 12 /// as well as its implicit and explicit arguments in a uniform way. 13 /// Arguments that are explicit and independant (non tied) also have a Variable 14 /// associated to them so the instruction can be fully defined by reading its 15 /// Variables. 16 /// 17 //===----------------------------------------------------------------------===// 18 19 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H 20 #define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H 21 22 #include <random> 23 24 #include "RegisterAliasing.h" 25 #include "llvm/ADT/ArrayRef.h" 26 #include "llvm/ADT/Optional.h" 27 #include "llvm/MC/MCInst.h" 28 #include "llvm/MC/MCInstrDesc.h" 29 #include "llvm/MC/MCInstrInfo.h" 30 31 namespace exegesis { 32 33 struct Operand; // forward declaration. 34 35 // A variable represents the value associated to an Operand or a set of Operands 36 // if they are tied together. 37 struct Variable { 38 // The indices of the operands tied to this Variable. 39 llvm::SmallVector<unsigned, 2> TiedOperands; 40 llvm::MCOperand AssignedValue; 41 // The index of this Variable in Instruction.Variables and its associated 42 // Value in InstructionInstance.VariableValues. 43 unsigned Index = -1; 44 }; 45 46 // MCOperandInfo can only represents Explicit operands. This object gives a 47 // uniform view of Implicit and Explicit Operands. 48 // 49 // - Index: can be used to refer to MCInstrDesc::operands for Explicit operands. 50 // - Tracker: is set for Register Operands and is used to keep track of possible 51 // registers and the registers reachable from them (aliasing registers). 52 // - Info: a shortcut for MCInstrDesc::operands()[Index]. 53 // - TiedToIndex: the index of the Operand holding the value or -1. 54 // - ImplicitReg: a pointer to the register value when Operand is Implicit, 55 // nullptr otherwise. 56 // - VariableIndex: the index of the Variable holding the value for this Operand 57 // or -1 if this operand is implicit. 58 struct Operand { 59 unsigned Index = 0; 60 bool IsDef = false; 61 bool IsExplicit = false; 62 const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op. 63 const llvm::MCOperandInfo *Info = nullptr; // Set for Explicit Op. 64 int TiedToIndex = -1; // Set for Reg&Explicit Op. 65 const llvm::MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op. 66 int VariableIndex = -1; // Set for Explicit Op. 67 }; 68 69 // A view over an MCInstrDesc offering a convenient interface to compute 70 // Register aliasing. 71 struct Instruction { 72 Instruction(const llvm::MCInstrDesc &MCInstrDesc, 73 const RegisterAliasingTrackerCache &ATC); 74 75 const llvm::MCInstrDesc *Description; // Never nullptr. 76 llvm::SmallVector<Operand, 8> Operands; 77 llvm::SmallVector<Variable, 4> Variables; 78 llvm::BitVector DefRegisters; // The union of the aliased def registers. 79 llvm::BitVector UseRegisters; // The union of the aliased use registers. 80 }; 81 82 // An instance of an Instruction holding values for each of its Variables. 83 struct InstructionInstance { 84 InstructionInstance(const Instruction &Instr); 85 86 // No copy. 87 InstructionInstance(const InstructionInstance &) = delete; 88 InstructionInstance &operator=(const InstructionInstance &) = delete; 89 90 // Moving is OK. 91 InstructionInstance(InstructionInstance &&); 92 InstructionInstance &operator=(InstructionInstance &&); 93 94 unsigned getOpcode() const; 95 llvm::MCOperand &getValueFor(const Variable &Var); 96 const llvm::MCOperand &getValueFor(const Variable &Var) const; 97 llvm::MCOperand &getValueFor(const Operand &Op); 98 const llvm::MCOperand &getValueFor(const Operand &Op) const; 99 bool hasImmediateVariables() const; 100 101 // Assigns a Random Value to all Variables that are still Invalid. 102 void randomizeUnsetVariables(); 103 104 // Returns the instance as an llvm::MCInst. The InstructionInstance must be 105 // fully allocated (no invalid variables). 106 llvm::MCInst build() const; 107 108 Instruction Instr; 109 llvm::SmallVector<llvm::MCOperand, 4> VariableValues; 110 }; 111 112 // A prototype is a set of InstructionInstances with an explanation of how 113 // it's been built. The prototype can then be randomized to exercice several 114 // immediate values. It is also used to gather the used registers and define 115 // their initial values. 116 struct SnippetPrototype { 117 SnippetPrototype() = default; 118 119 // No copy. 120 SnippetPrototype(const SnippetPrototype &) = delete; 121 SnippetPrototype &operator=(const SnippetPrototype &) = delete; 122 123 // Moving is OK. 124 SnippetPrototype(SnippetPrototype &&); 125 SnippetPrototype &operator=(SnippetPrototype &&); 126 127 std::string Explanation; 128 std::vector<InstructionInstance> Snippet; 129 }; 130 131 // Represents the assignment of a Register to an Operand. 132 struct RegisterOperandAssignment { RegisterOperandAssignmentRegisterOperandAssignment133 RegisterOperandAssignment(const Operand *Operand, llvm::MCPhysReg Reg) 134 : Op(Operand), Reg(Reg) {} 135 136 const Operand *Op; // Pointer to an Explicit Register Operand. 137 llvm::MCPhysReg Reg; 138 139 bool operator==(const RegisterOperandAssignment &other) const; 140 }; 141 142 // Represents a set of Operands that would alias through the use of some 143 // Registers. 144 // There are two reasons why operands would alias: 145 // - The registers assigned to each of the operands are the same or alias each 146 // other (e.g. AX/AL) 147 // - The operands are tied. 148 struct AliasingRegisterOperands { 149 llvm::SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1. 150 llvm::SmallVector<RegisterOperandAssignment, 2> Uses; 151 152 // True is Defs and Use contain an Implicit Operand. 153 bool hasImplicitAliasing() const; 154 155 bool operator==(const AliasingRegisterOperands &other) const; 156 }; 157 158 // Returns all possible configurations leading Def registers of DefInstruction 159 // to alias with Use registers of UseInstruction. 160 struct AliasingConfigurations { 161 AliasingConfigurations(const Instruction &DefInstruction, 162 const Instruction &UseInstruction); 163 164 bool empty() const; // True if no aliasing configuration is found. 165 bool hasImplicitAliasing() const; 166 void setExplicitAliasing() const; 167 168 const Instruction &DefInstruction; 169 const Instruction &UseInstruction; 170 llvm::SmallVector<AliasingRegisterOperands, 32> Configurations; 171 }; 172 173 // A global Random Number Generator to randomize configurations. 174 // FIXME: Move random number generation into an object and make it seedable for 175 // unit tests. 176 std::mt19937 &randomGenerator(); 177 178 // Picks a random bit among the bits set in Vector and returns its index. 179 // Precondition: Vector must have at least one bit set. 180 size_t randomBit(const llvm::BitVector &Vector); 181 182 // Picks a random configuration, then selects a random def and a random use from 183 // it and finally set the selected values in the provided InstructionInstances. 184 void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations, 185 InstructionInstance &DefII, InstructionInstance &UseII); 186 187 // Writes MCInst to OS. 188 // This is not assembly but the internal LLVM's name for instructions and 189 // registers. 190 void DumpMCInst(const llvm::MCRegisterInfo &MCRegisterInfo, 191 const llvm::MCInstrInfo &MCInstrInfo, 192 const llvm::MCInst &MCInst, llvm::raw_ostream &OS); 193 194 } // namespace exegesis 195 196 #endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H 197