Clement Courbet | 0e69e2d | 2018-05-17 10:52:18 +0000 | [diff] [blame] | 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 of an Operand or a set of Operands if they ar |
| 36 | // tied together. |
| 37 | struct Variable { |
| 38 | llvm::SmallVector<const Operand *, 2> TiedOperands; |
| 39 | llvm::MCOperand AssignedValue; |
| 40 | }; |
| 41 | |
| 42 | // MCOperandInfo can only represents Explicit operands. This object gives a |
| 43 | // uniform view of Implicit and Explicit Operands. |
| 44 | // |
| 45 | // - Index: can be used to refer to MCInstrDesc::operands for Explicit operands. |
| 46 | // - Tracker: is set for Register Operands and is used to keep track of possible |
| 47 | // registers and the registers reachable from them (aliasing registers). |
| 48 | // - Info: a shortcut for MCInstrDesc::operands()[Index]. |
| 49 | // - TiedTo: a pointer to the Operand holding the value or nullptr. |
| 50 | // - ImplicitReg: a pointer to the register value when Operand is Implicit, |
| 51 | // nullptr otherwise. |
| 52 | // - Variable: The value associated with this Operand. It is only set for |
| 53 | // explicit operands that are not TiedTo. |
| 54 | struct Operand { |
| 55 | uint8_t Index = 0; |
| 56 | bool IsDef = false; |
| 57 | bool IsExplicit = false; |
| 58 | const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op. |
| 59 | const llvm::MCOperandInfo *Info = nullptr; // Set for Explicit Op. |
| 60 | const Operand *TiedTo = nullptr; // Set for Reg/Explicit Op. |
| 61 | const llvm::MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op. |
| 62 | mutable llvm::Optional<Variable> Var; // Set for Explicit Op. |
| 63 | }; |
| 64 | |
| 65 | // A view over an MCInstrDesc offering a convenient interface to compute |
| 66 | // Register aliasing and assign values to Operands. |
| 67 | struct Instruction { |
| 68 | Instruction(const llvm::MCInstrDesc &MCInstrDesc, |
| 69 | RegisterAliasingTrackerCache &ATC); |
| 70 | |
| 71 | const llvm::MCInstrDesc &Description; |
| 72 | llvm::SmallVector<Operand, 8> Operands; |
| 73 | llvm::SmallVector<Variable *, 8> Variables; |
| 74 | llvm::BitVector DefRegisters; // The union of the aliased def registers. |
| 75 | llvm::BitVector UseRegisters; // The union of the aliased use registers. |
| 76 | }; |
| 77 | |
| 78 | // Represents the assignment of a Register to an Operand. |
| 79 | struct RegisterOperandAssignment { |
| 80 | RegisterOperandAssignment(const Operand *Operand, llvm::MCPhysReg Reg) |
| 81 | : Op(Operand), Reg(Reg) {} |
| 82 | |
| 83 | const Operand *Op; // Pointer to an Explicit Register Operand. |
| 84 | llvm::MCPhysReg Reg; |
| 85 | |
| 86 | bool operator==(const RegisterOperandAssignment &other) const; |
| 87 | }; |
| 88 | |
| 89 | // Represents a set of Operands that would alias through the use of some |
| 90 | // Registers. |
| 91 | // There are two reasons why operands would alias: |
| 92 | // - The registers assigned to each of the operands are the same or alias each |
| 93 | // other (e.g. AX/AL) |
| 94 | // - The operands are tied. |
| 95 | struct AliasingRegisterOperands { |
| 96 | llvm::SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1. |
| 97 | llvm::SmallVector<RegisterOperandAssignment, 2> Uses; |
| 98 | |
| 99 | // True is Defs and Use contain an Implicit Operand. |
| 100 | bool hasImplicitAliasing() const; |
| 101 | |
| 102 | bool operator==(const AliasingRegisterOperands &other) const; |
| 103 | }; |
| 104 | |
| 105 | // Returns all possible configurations leading Def registers of DefInstruction |
| 106 | // to alias with Use registers of UseInstruction. |
| 107 | struct AliasingConfigurations { |
| 108 | AliasingConfigurations(const Instruction &DefInstruction, |
| 109 | const Instruction &UseInstruction); |
| 110 | |
| 111 | bool empty() const; // True if no aliasing configuration is found. |
| 112 | bool hasImplicitAliasing() const; |
| 113 | void setExplicitAliasing() const; |
| 114 | |
| 115 | const Instruction &DefInstruction; |
| 116 | const Instruction &UseInstruction; |
| 117 | llvm::SmallVector<AliasingRegisterOperands, 32> Configurations; |
| 118 | }; |
| 119 | |
| 120 | // A global Random Number Generator to randomize configurations. |
| 121 | // FIXME: Move random number generation into an object and make it seedable for |
| 122 | // unit tests. |
| 123 | std::mt19937 &randomGenerator(); |
| 124 | |
| 125 | // Picks a random bit among the bits set in Vector and returns its index. |
| 126 | // Precondition: Vector must have at least one bit set. |
| 127 | size_t randomBit(const llvm::BitVector &Vector); |
| 128 | |
| 129 | // Picks a random configuration, then select a random def and a random use from |
| 130 | // it and set the target Variables to the selected values. |
| 131 | // FIXME: This function mutates some nested variables in a const object, please |
| 132 | // fix ASAP. |
| 133 | void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations); |
| 134 | |
| 135 | // Set all Instruction's Variables AssignedValue to Invalid. |
| 136 | void clearVariableAssignments(const Instruction &Instruction); |
| 137 | |
| 138 | // Assigns a Random Value to all Instruction's Variables that are still Invalid. |
| 139 | llvm::MCInst randomizeUnsetVariablesAndBuild(const Instruction &Instruction); |
| 140 | |
| 141 | // Writes MCInst to OS. |
| 142 | // This is not assembly but the internal LLVM's name for instructions and |
| 143 | // registers. |
| 144 | void DumpMCInst(const llvm::MCRegisterInfo &MCRegisterInfo, |
| 145 | const llvm::MCInstrInfo &MCInstrInfo, |
| 146 | const llvm::MCInst &MCInst, llvm::raw_ostream &OS); |
| 147 | |
| 148 | } // namespace exegesis |
| 149 | |
| 150 | #endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H |