Home | History | Annotate | Download | only in lib
      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 {
    133   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