MCInstrDescView.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //===-- MCInstrDescView.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. /// Provide views around LLVM structures to represents an instruction instance,
  11. /// as well as its implicit and explicit arguments in a uniform way.
  12. /// Arguments that are explicit and independant (non tied) also have a Variable
  13. /// associated to them so the instruction can be fully defined by reading its
  14. /// Variables.
  15. ///
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
  18. #define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
  19. #include <memory>
  20. #include <random>
  21. #include <unordered_map>
  22. #include "RegisterAliasing.h"
  23. #include "llvm/ADT/ArrayRef.h"
  24. #include "llvm/MC/MCInst.h"
  25. #include "llvm/MC/MCInstrDesc.h"
  26. #include "llvm/MC/MCInstrInfo.h"
  27. namespace llvm {
  28. namespace exegesis {
  29. // A variable represents the value associated to an Operand or a set of Operands
  30. // if they are tied together.
  31. struct Variable {
  32. // Returns the index of this Variable inside Instruction's Variable.
  33. unsigned getIndex() const;
  34. // Returns the index of the Operand linked to this Variable.
  35. unsigned getPrimaryOperandIndex() const;
  36. // Returns whether this Variable has more than one Operand linked to it.
  37. bool hasTiedOperands() const;
  38. // The indices of the operands tied to this Variable.
  39. SmallVector<unsigned, 2> TiedOperands;
  40. // The index of this Variable in Instruction.Variables and its associated
  41. // Value in InstructionBuilder.VariableValues.
  42. std::optional<uint8_t> Index;
  43. };
  44. // MCOperandInfo can only represents Explicit operands. This object gives a
  45. // uniform view of Implicit and Explicit Operands.
  46. // - Index: can be used to refer to MCInstrDesc::operands for Explicit operands.
  47. // - Tracker: is set for Register Operands and is used to keep track of possible
  48. // registers and the registers reachable from them (aliasing registers).
  49. // - Info: a shortcut for MCInstrDesc::operands()[Index].
  50. // - TiedToIndex: the index of the Operand holding the value or -1.
  51. // - ImplicitReg: the register value when Operand is Implicit, 0 otherwise.
  52. // - VariableIndex: the index of the Variable holding the value for this Operand
  53. // or -1 if this operand is implicit.
  54. struct Operand {
  55. bool isExplicit() const;
  56. bool isImplicit() const;
  57. bool isImplicitReg() const;
  58. bool isDef() const;
  59. bool isUse() const;
  60. bool isReg() const;
  61. bool isTied() const;
  62. bool isVariable() const;
  63. bool isMemory() const;
  64. bool isImmediate() const;
  65. unsigned getIndex() const;
  66. unsigned getTiedToIndex() const;
  67. unsigned getVariableIndex() const;
  68. unsigned getImplicitReg() const;
  69. const RegisterAliasingTracker &getRegisterAliasing() const;
  70. const MCOperandInfo &getExplicitOperandInfo() const;
  71. // Please use the accessors above and not the following fields.
  72. std::optional<uint8_t> Index;
  73. bool IsDef = false;
  74. const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
  75. const MCOperandInfo *Info = nullptr; // Set for Explicit Op.
  76. std::optional<uint8_t> TiedToIndex; // Set for Reg&Explicit Op.
  77. MCPhysReg ImplicitReg = 0; // Non-0 for Implicit Op.
  78. std::optional<uint8_t> VariableIndex; // Set for Explicit Op.
  79. };
  80. /// A cache of BitVector to reuse between Instructions.
  81. /// The cache will only be exercised during Instruction initialization.
  82. /// For X86, this is ~160 unique vectors for all of the ~15K Instructions.
  83. struct BitVectorCache {
  84. // Finds or allocates the provided BitVector in the cache and retrieves it's
  85. // unique instance.
  86. const BitVector *getUnique(BitVector &&BV) const;
  87. private:
  88. mutable std::vector<std::unique_ptr<BitVector>> Cache;
  89. };
  90. // A view over an MCInstrDesc offering a convenient interface to compute
  91. // Register aliasing.
  92. struct Instruction {
  93. // Create an instruction for a particular Opcode.
  94. static std::unique_ptr<Instruction>
  95. create(const MCInstrInfo &InstrInfo, const RegisterAliasingTrackerCache &RATC,
  96. const BitVectorCache &BVC, unsigned Opcode);
  97. // Prevent copy or move, instructions are allocated once and cached.
  98. Instruction(const Instruction &) = delete;
  99. Instruction(Instruction &&) = delete;
  100. Instruction &operator=(const Instruction &) = delete;
  101. Instruction &operator=(Instruction &&) = delete;
  102. // Returns the Operand linked to this Variable.
  103. // In case the Variable is tied, the primary (i.e. Def) Operand is returned.
  104. const Operand &getPrimaryOperand(const Variable &Var) const;
  105. // Whether this instruction is self aliasing through its tied registers.
  106. // Repeating this instruction is guaranteed to executes sequentially.
  107. bool hasTiedRegisters() const;
  108. // Whether this instruction is self aliasing through its implicit registers.
  109. // Repeating this instruction is guaranteed to executes sequentially.
  110. bool hasAliasingImplicitRegisters() const;
  111. // Whether this instruction is self aliasing through some registers.
  112. // Repeating this instruction may execute sequentially by picking aliasing
  113. // Use and Def registers. It may also execute in parallel by picking non
  114. // aliasing Use and Def registers.
  115. bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const;
  116. // Whether this instruction's registers alias with OtherInstr's registers.
  117. bool hasAliasingRegistersThrough(const Instruction &OtherInstr,
  118. const BitVector &ForbiddenRegisters) const;
  119. // Returns whether this instruction has Memory Operands.
  120. // Repeating this instruction executes sequentially with an instruction that
  121. // reads or write the same memory region.
  122. bool hasMemoryOperands() const;
  123. // Returns whether this instruction as at least one use or one def.
  124. // Repeating this instruction may execute sequentially by adding an
  125. // instruction that aliases one of these.
  126. bool hasOneUseOrOneDef() const;
  127. // Convenient function to help with debugging.
  128. void dump(const MCRegisterInfo &RegInfo,
  129. const RegisterAliasingTrackerCache &RATC,
  130. raw_ostream &Stream) const;
  131. const MCInstrDesc &Description;
  132. const StringRef Name; // The name of this instruction.
  133. const SmallVector<Operand, 8> Operands;
  134. const SmallVector<Variable, 4> Variables;
  135. const BitVector &ImplDefRegs; // The set of aliased implicit def registers.
  136. const BitVector &ImplUseRegs; // The set of aliased implicit use registers.
  137. const BitVector &AllDefRegs; // The set of all aliased def registers.
  138. const BitVector &AllUseRegs; // The set of all aliased use registers.
  139. private:
  140. Instruction(const MCInstrDesc *Description, StringRef Name,
  141. SmallVector<Operand, 8> Operands,
  142. SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,
  143. const BitVector *ImplUseRegs, const BitVector *AllDefRegs,
  144. const BitVector *AllUseRegs);
  145. };
  146. // Instructions are expensive to instantiate. This class provides a cache of
  147. // Instructions with lazy construction.
  148. struct InstructionsCache {
  149. InstructionsCache(const MCInstrInfo &InstrInfo,
  150. const RegisterAliasingTrackerCache &RATC);
  151. // Returns the Instruction object corresponding to this Opcode.
  152. const Instruction &getInstr(unsigned Opcode) const;
  153. private:
  154. const MCInstrInfo &InstrInfo;
  155. const RegisterAliasingTrackerCache &RATC;
  156. mutable std::unordered_map<unsigned, std::unique_ptr<Instruction>>
  157. Instructions;
  158. const BitVectorCache BVC;
  159. };
  160. // Represents the assignment of a Register to an Operand.
  161. struct RegisterOperandAssignment {
  162. RegisterOperandAssignment(const Operand *Operand, MCPhysReg Reg)
  163. : Op(Operand), Reg(Reg) {}
  164. const Operand *Op; // Pointer to an Explicit Register Operand.
  165. MCPhysReg Reg;
  166. bool operator==(const RegisterOperandAssignment &other) const;
  167. };
  168. // Represents a set of Operands that would alias through the use of some
  169. // Registers.
  170. // There are two reasons why operands would alias:
  171. // - The registers assigned to each of the operands are the same or alias each
  172. // other (e.g. AX/AL)
  173. // - The operands are tied.
  174. struct AliasingRegisterOperands {
  175. SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1.
  176. SmallVector<RegisterOperandAssignment, 2> Uses;
  177. // True is Defs and Use contain an Implicit Operand.
  178. bool hasImplicitAliasing() const;
  179. bool operator==(const AliasingRegisterOperands &other) const;
  180. };
  181. // Returns all possible configurations leading Def registers of DefInstruction
  182. // to alias with Use registers of UseInstruction.
  183. struct AliasingConfigurations {
  184. AliasingConfigurations(const Instruction &DefInstruction,
  185. const Instruction &UseInstruction,
  186. const BitVector &ForbiddenRegisters);
  187. bool empty() const; // True if no aliasing configuration is found.
  188. bool hasImplicitAliasing() const;
  189. SmallVector<AliasingRegisterOperands, 32> Configurations;
  190. };
  191. // Writes MCInst to OS.
  192. // This is not assembly but the internal LLVM's name for instructions and
  193. // registers.
  194. void DumpMCInst(const MCRegisterInfo &MCRegisterInfo,
  195. const MCInstrInfo &MCInstrInfo, const MCInst &MCInst,
  196. raw_ostream &OS);
  197. } // namespace exegesis
  198. } // namespace llvm
  199. #endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H