252 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// 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 Variable13/// associated to them so the instruction can be fully defined by reading its14/// Variables.15///16//===----------------------------------------------------------------------===//17 18#ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H19#define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H20 21#include <memory>22#include <random>23#include <unordered_map>24 25#include "RegisterAliasing.h"26#include "llvm/ADT/ArrayRef.h"27#include "llvm/MC/MCInst.h"28#include "llvm/MC/MCInstrDesc.h"29#include "llvm/MC/MCInstrInfo.h"30 31namespace llvm {32namespace exegesis {33 34// A variable represents the value associated to an Operand or a set of Operands35// if they are tied together.36struct Variable {37 // Returns the index of this Variable inside Instruction's Variable.38 unsigned getIndex() const;39 40 // Returns the index of the Operand linked to this Variable.41 unsigned getPrimaryOperandIndex() const;42 43 // Returns whether this Variable has more than one Operand linked to it.44 bool hasTiedOperands() const;45 46 // The indices of the operands tied to this Variable.47 SmallVector<unsigned, 2> TiedOperands;48 49 // The index of this Variable in Instruction.Variables and its associated50 // Value in InstructionBuilder.VariableValues.51 std::optional<uint8_t> Index;52};53 54// MCOperandInfo can only represents Explicit operands. This object gives a55// uniform view of Implicit and Explicit Operands.56// - Index: can be used to refer to MCInstrDesc::operands for Explicit operands.57// - Tracker: is set for Register Operands and is used to keep track of possible58// registers and the registers reachable from them (aliasing registers).59// - Info: a shortcut for MCInstrDesc::operands()[Index].60// - TiedToIndex: the index of the Operand holding the value or -1.61// - ImplicitReg: the register value when Operand is Implicit, 0 otherwise.62// - VariableIndex: the index of the Variable holding the value for this Operand63// or -1 if this operand is implicit.64struct Operand {65 bool isExplicit() const;66 bool isImplicit() const;67 bool isImplicitReg() const;68 bool isDef() const;69 bool isUse() const;70 bool isReg() const;71 bool isTied() const;72 bool isVariable() const;73 bool isMemory() const;74 bool isImmediate() const;75 bool isEarlyClobber() const;76 unsigned getIndex() const;77 unsigned getTiedToIndex() const;78 unsigned getVariableIndex() const;79 MCRegister getImplicitReg() const;80 const RegisterAliasingTracker &getRegisterAliasing() const;81 const MCOperandInfo &getExplicitOperandInfo() const;82 83 // Please use the accessors above and not the following fields.84 std::optional<uint8_t> Index;85 bool IsDef = false;86 bool IsEarlyClobber = false;87 const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.88 const MCOperandInfo *Info = nullptr; // Set for Explicit Op.89 std::optional<uint8_t> TiedToIndex; // Set for Reg&Explicit Op.90 MCRegister ImplicitReg; // Non-0 for Implicit Op.91 std::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.97struct BitVectorCache {98 // Finds or allocates the provided BitVector in the cache and retrieves it's99 // unique instance.100 const BitVector *getUnique(BitVector &&BV) const;101 102private:103 mutable std::vector<std::unique_ptr<BitVector>> Cache;104};105 106// A view over an MCInstrDesc offering a convenient interface to compute107// Register aliasing.108struct 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 unsigned getOpcode() const { return Description.getOpcode(); }121 122 // Returns the Operand linked to this Variable.123 // In case the Variable is tied, the primary (i.e. Def) Operand is returned.124 const Operand &getPrimaryOperand(const Variable &Var) const;125 126 // Whether this instruction is self aliasing through its tied registers.127 // Repeating this instruction is guaranteed to executes sequentially.128 bool hasTiedRegisters() const;129 130 // Whether this instruction is self aliasing through its implicit registers.131 // Repeating this instruction is guaranteed to executes sequentially.132 bool hasAliasingImplicitRegisters() const;133 134 // Whether this instruction is self aliasing through some registers.135 // Repeating this instruction may execute sequentially by picking aliasing136 // Use and Def registers. It may also execute in parallel by picking non137 // aliasing Use and Def registers.138 bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const;139 140 // Whether this instruction is self aliasing through some registers.141 // Repeating this instruction may execute sequentially by picking aliasing142 // Def and Not Memory Use registers. It may also execute in parallel by143 // picking non aliasing Def and Not Memory Use registers.144 bool hasAliasingNotMemoryRegisters(const BitVector &ForbiddenRegisters) const;145 146 // Whether this instruction's registers alias with OtherInstr's registers.147 bool hasAliasingRegistersThrough(const Instruction &OtherInstr,148 const BitVector &ForbiddenRegisters) const;149 150 // Returns whether this instruction has Memory Operands.151 // Repeating this instruction executes sequentially with an instruction that152 // reads or write the same memory region.153 bool hasMemoryOperands() const;154 155 // Returns whether this instruction as at least one use or one def.156 // Repeating this instruction may execute sequentially by adding an157 // instruction that aliases one of these.158 bool hasOneUseOrOneDef() const;159 160 // Convenient function to help with debugging.161 void dump(const MCRegisterInfo &RegInfo,162 const RegisterAliasingTrackerCache &RATC,163 raw_ostream &Stream) const;164 165 const MCInstrDesc &Description;166 const StringRef Name; // The name of this instruction.167 const SmallVector<Operand, 8> Operands;168 const SmallVector<Variable, 4> Variables;169 const BitVector &ImplDefRegs; // The set of aliased implicit def registers.170 const BitVector &ImplUseRegs; // The set of aliased implicit use registers.171 const BitVector &AllDefRegs; // The set of all aliased def registers.172 const BitVector &AllUseRegs; // The set of all aliased use registers.173 // The set of all aliased not memory use registers.174 const BitVector &NonMemoryRegs;175 176private:177 Instruction(const MCInstrDesc *Description, StringRef Name,178 SmallVector<Operand, 8> Operands,179 SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,180 const BitVector *ImplUseRegs, const BitVector *AllDefRegs,181 const BitVector *AllUseRegs, const BitVector *NonMemoryRegs);182};183 184// Instructions are expensive to instantiate. This class provides a cache of185// Instructions with lazy construction.186struct InstructionsCache {187 InstructionsCache(const MCInstrInfo &InstrInfo,188 const RegisterAliasingTrackerCache &RATC);189 190 // Returns the Instruction object corresponding to this Opcode.191 const Instruction &getInstr(unsigned Opcode) const;192 193private:194 const MCInstrInfo &InstrInfo;195 const RegisterAliasingTrackerCache &RATC;196 mutable std::unordered_map<unsigned, std::unique_ptr<Instruction>>197 Instructions;198 const BitVectorCache BVC;199};200 201// Represents the assignment of a Register to an Operand.202struct RegisterOperandAssignment {203 RegisterOperandAssignment(const Operand *Operand, MCPhysReg Reg)204 : Op(Operand), Reg(Reg) {}205 206 const Operand *Op; // Pointer to an Explicit Register Operand.207 MCPhysReg Reg;208 209 bool operator==(const RegisterOperandAssignment &other) const;210};211 212// Represents a set of Operands that would alias through the use of some213// Registers.214// There are two reasons why operands would alias:215// - The registers assigned to each of the operands are the same or alias each216// other (e.g. AX/AL)217// - The operands are tied.218struct AliasingRegisterOperands {219 SmallVector<RegisterOperandAssignment, 1> Defs; // Unlikely size() > 1.220 SmallVector<RegisterOperandAssignment, 2> Uses;221 222 // True is Defs and Use contain an Implicit Operand.223 bool hasImplicitAliasing() const;224 225 bool operator==(const AliasingRegisterOperands &other) const;226};227 228// Returns all possible configurations leading Def registers of DefInstruction229// to alias with Use registers of UseInstruction.230struct AliasingConfigurations {231 AliasingConfigurations(const Instruction &DefInstruction,232 const Instruction &UseInstruction,233 const BitVector &ForbiddenRegisters);234 235 bool empty() const; // True if no aliasing configuration is found.236 bool hasImplicitAliasing() const;237 238 SmallVector<AliasingRegisterOperands, 32> Configurations;239};240 241// Writes MCInst to OS.242// This is not assembly but the internal LLVM's name for instructions and243// registers.244void DumpMCInst(const MCRegisterInfo &MCRegisterInfo,245 const MCInstrInfo &MCInstrInfo, const MCInst &MCInst,246 raw_ostream &OS);247 248} // namespace exegesis249} // namespace llvm250 251#endif // LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H252