brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · a50b190 Raw
331 lines · c
1//===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- 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// This file defines a wrapper class for the 'Instruction' TableGen class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H14#define LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H15 16#include "llvm/ADT/BitVector.h"17#include "llvm/ADT/StringMap.h"18#include "llvm/ADT/StringRef.h"19#include "llvm/CodeGenTypes/MachineValueType.h"20#include "llvm/TableGen/Record.h"21#include <cassert>22#include <string>23#include <utility>24#include <vector>25 26namespace llvm {27class CodeGenTarget;28 29class CGIOperandList {30public:31  class ConstraintInfo {32    enum { None, EarlyClobber, Tied } Kind = None;33    unsigned OtherTiedOperand = 0;34 35  public:36    ConstraintInfo() = default;37 38    static ConstraintInfo getEarlyClobber() {39      ConstraintInfo I;40      I.Kind = EarlyClobber;41      I.OtherTiedOperand = 0;42      return I;43    }44 45    static ConstraintInfo getTied(unsigned Op) {46      ConstraintInfo I;47      I.Kind = Tied;48      I.OtherTiedOperand = Op;49      return I;50    }51 52    bool isNone() const { return Kind == None; }53    bool isEarlyClobber() const { return Kind == EarlyClobber; }54    bool isTied() const { return Kind == Tied; }55 56    unsigned getTiedOperand() const {57      assert(isTied());58      return OtherTiedOperand;59    }60 61    bool operator==(const ConstraintInfo &RHS) const {62      if (Kind != RHS.Kind)63        return false;64      if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand)65        return false;66      return true;67    }68    bool operator!=(const ConstraintInfo &RHS) const { return !(*this == RHS); }69  };70 71  /// OperandInfo - The information we keep track of for each operand in the72  /// operand list for a tablegen instruction.73  struct OperandInfo {74    /// Rec - The definition this operand is declared as.75    ///76    const Record *Rec;77 78    /// Name - If this operand was assigned a symbolic name, this is it,79    /// otherwise, it's empty.80    StringRef Name;81 82    /// The names of sub-operands, if given, otherwise empty.83    std::vector<StringRef> SubOpNames;84 85    /// PrinterMethodName - The method used to print operands of this type in86    /// the asmprinter.87    StringRef PrinterMethodName;88 89    /// The method used to get the machine operand value for binary90    /// encoding, per sub-operand. If empty, uses "getMachineOpValue".91    std::vector<StringRef> EncoderMethodNames;92 93    /// OperandType - A value from MCOI::OperandType representing the type of94    /// the operand.95    std::string OperandType;96 97    /// MIOperandNo - Currently (this is meant to be phased out), some logical98    /// operands correspond to multiple MachineInstr operands.  In the X8699    /// target for example, one address operand is represented as 4100    /// MachineOperands.  Because of this, the operand number in the101    /// OperandList may not match the MachineInstr operand num.  Until it102    /// does, this contains the MI operand index of this operand.103    unsigned MIOperandNo;104    unsigned MINumOperands; // The number of operands.105 106    /// MIOperandInfo - Default MI operand type. Note an operand may be made107    /// up of multiple MI operands.108    const DagInit *MIOperandInfo;109 110    /// Constraint info for this operand.  This operand can have pieces, so we111    /// track constraint info for each.112    std::vector<ConstraintInfo> Constraints;113 114    OperandInfo(const Record *R, StringRef Name, StringRef PrinterMethodName,115                const std::string &OT, unsigned MION, unsigned MINO,116                const DagInit *MIOI)117        : Rec(R), Name(Name), SubOpNames(MINO),118          PrinterMethodName(PrinterMethodName), EncoderMethodNames(MINO),119          OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),120          MIOperandInfo(MIOI), Constraints(MINO) {}121 122    /// getTiedOperand - If this operand is tied to another one, return the123    /// other operand number.  Otherwise, return -1.124    int getTiedRegister() const {125      for (const CGIOperandList::ConstraintInfo &CI : Constraints)126        if (CI.isTied())127          return CI.getTiedOperand();128      return -1;129    }130  };131 132  CGIOperandList(const Record *D);133 134  const Record *TheDef; // The actual record containing this OperandList.135 136  /// NumDefs - Number of def operands declared, this is the number of137  /// elements in the instruction's (outs) list.138  ///139  unsigned NumDefs;140 141  /// OperandList - The list of declared operands, along with their declared142  /// type (which is a record).143  std::vector<OperandInfo> OperandList;144 145  /// SubOpAliases - List of alias names for suboperands.146  StringMap<std::pair<unsigned, unsigned>> SubOpAliases;147 148  // Information gleaned from the operand list.149  bool isPredicable;150  bool hasOptionalDef;151  bool isVariadic;152 153  // Provide transparent accessors to the operand list.154  bool empty() const { return OperandList.empty(); }155  unsigned size() const { return OperandList.size(); }156  const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }157  OperandInfo &operator[](unsigned i) { return OperandList[i]; }158  OperandInfo &back() { return OperandList.back(); }159  const OperandInfo &back() const { return OperandList.back(); }160 161  using iterator = std::vector<OperandInfo>::iterator;162  using const_iterator = std::vector<OperandInfo>::const_iterator;163  iterator begin() { return OperandList.begin(); }164  const_iterator begin() const { return OperandList.begin(); }165  iterator end() { return OperandList.end(); }166  const_iterator end() const { return OperandList.end(); }167 168  /// getOperandNamed - Return the index of the operand with the specified169  /// non-empty name.  If the instruction does not have an operand with the170  /// specified name, abort.171  unsigned getOperandNamed(StringRef Name) const;172 173  /// findOperandNamed - Query whether the instruction has an operand of the174  /// given name. If so, the index of the operand. Otherwise, return175  /// std::nullopt.176  std::optional<unsigned> findOperandNamed(StringRef Name) const;177 178  std::optional<std::pair<unsigned, unsigned>>179  findSubOperandAlias(StringRef Name) const;180 181  /// Parses an operand name like "$foo" or "$foo.bar",182  /// where $foo is a whole operand and $foo.bar refers to a suboperand.183  /// This aborts if the name is invalid.  If AllowWholeOp is true, references184  /// to operands with suboperands are allowed, otherwise not.185  std::pair<unsigned, unsigned>186  parseOperandName(StringRef Op, bool AllowWholeOp = true) const;187 188  /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a189  /// flat machineinstr operand #.190  unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const {191    return OperandList[Op.first].MIOperandNo + Op.second;192  }193 194  /// getSubOperandNumber - Unflatten a operand number into an195  /// operand/suboperand pair.196  std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const {197    for (unsigned i = 0;; ++i) {198      assert(i < OperandList.size() && "Invalid flat operand #");199      if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op)200        return {i, Op - OperandList[i].MIOperandNo};201    }202  }203};204 205class CodeGenInstruction {206public:207  const Record *TheDef; // The actual record defining this instruction.208  StringRef Namespace;  // The namespace the instruction is in.209 210  /// AsmString - The format string used to emit a .s file for the211  /// instruction.212  StringRef AsmString;213 214  /// Operands - This is information about the (ins) and (outs) list specified215  /// to the instruction.216  CGIOperandList Operands;217 218  /// ImplicitDefs/ImplicitUses - These are lists of registers that are219  /// implicitly defined and used by the instruction.220  std::vector<const Record *> ImplicitDefs, ImplicitUses;221 222  // Various boolean values we track for the instruction.223  bool isPreISelOpcode : 1;224  bool isReturn : 1;225  bool isEHScopeReturn : 1;226  bool isBranch : 1;227  bool isIndirectBranch : 1;228  bool isCompare : 1;229  bool isMoveImm : 1;230  bool isMoveReg : 1;231  bool isBitcast : 1;232  bool isSelect : 1;233  bool isBarrier : 1;234  bool isCall : 1;235  bool isAdd : 1;236  bool isTrap : 1;237  bool canFoldAsLoad : 1;238  bool mayLoad : 1;239  bool mayLoad_Unset : 1;240  bool mayStore : 1;241  bool mayStore_Unset : 1;242  bool mayRaiseFPException : 1;243  bool isPredicable : 1;244  bool isConvertibleToThreeAddress : 1;245  bool isCommutable : 1;246  bool isTerminator : 1;247  bool isReMaterializable : 1;248  bool hasDelaySlot : 1;249  bool usesCustomInserter : 1;250  bool hasPostISelHook : 1;251  bool hasCtrlDep : 1;252  bool isNotDuplicable : 1;253  bool hasSideEffects : 1;254  bool hasSideEffects_Unset : 1;255  bool isAsCheapAsAMove : 1;256  bool hasExtraSrcRegAllocReq : 1;257  bool hasExtraDefRegAllocReq : 1;258  bool isCodeGenOnly : 1;259  bool isPseudo : 1;260  bool isMeta : 1;261  bool isRegSequence : 1;262  bool isExtractSubreg : 1;263  bool isInsertSubreg : 1;264  bool isConvergent : 1;265  bool hasNoSchedulingInfo : 1;266  bool FastISelShouldIgnore : 1;267  bool hasChain : 1;268  bool hasChain_Inferred : 1;269  bool variadicOpsAreDefs : 1;270  bool isAuthenticated : 1;271 272  std::string DeprecatedReason;273  bool HasComplexDeprecationPredicate;274 275  /// Are there any undefined flags?276  bool hasUndefFlags() const {277    return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;278  }279 280  // The record used to infer instruction flags, or NULL if no flag values281  // have been inferred.282  const Record *InferredFrom;283 284  // The enum value assigned by CodeGenTarget::computeInstrsByEnum.285  mutable unsigned EnumVal = 0;286 287  CodeGenInstruction(const Record *R);288 289  /// HasOneImplicitDefWithKnownVT - If the instruction has at least one290  /// implicit def and it has a known VT, return the VT, otherwise return291  /// MVT::Other.292  MVT HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;293 294  /// FlattenAsmStringVariants - Flatten the specified AsmString to only295  /// include text from the specified variant, returning the new string.296  static std::string FlattenAsmStringVariants(StringRef AsmString,297                                              unsigned Variant);298 299  // Is the specified operand in a generic instruction implicitly a pointer.300  // This can be used on intructions that use typeN or ptypeN to identify301  // operands that should be considered as pointers even though SelectionDAG302  // didn't make a distinction between integer and pointers.303  bool isInOperandAPointer(unsigned i) const {304    return isOperandImpl("InOperandList", i, "IsPointer");305  }306 307  bool isOutOperandAPointer(unsigned i) const {308    return isOperandImpl("OutOperandList", i, "IsPointer");309  }310 311  /// Check if the operand is required to be an immediate.312  bool isInOperandImmArg(unsigned i) const {313    return isOperandImpl("InOperandList", i, "IsImmediate");314  }315 316  /// Return true if the instruction uses a variable length encoding.317  bool isVariableLengthEncoding() const {318    const RecordVal *RV = TheDef->getValue("Inst");319    return RV && isa<DagInit>(RV->getValue());320  }321 322  StringRef getName() const { return TheDef->getName(); }323 324private:325  bool isOperandImpl(StringRef OpListName, unsigned i,326                     StringRef PropertyName) const;327};328} // namespace llvm329 330#endif // LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H331