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