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