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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a wrapper class for the 'Instruction' TableGen class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H 14 #define LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H 15 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 26 namespace llvm { 27 class CodeGenTarget; 28 29 class CGIOperandList { 30 public: 31 class ConstraintInfo { 32 enum { None, EarlyClobber, Tied } Kind = None; 33 unsigned OtherTiedOperand = 0; 34 35 public: 36 ConstraintInfo() = default; 37 getEarlyClobber()38 static ConstraintInfo getEarlyClobber() { 39 ConstraintInfo I; 40 I.Kind = EarlyClobber; 41 I.OtherTiedOperand = 0; 42 return I; 43 } 44 getTied(unsigned Op)45 static ConstraintInfo getTied(unsigned Op) { 46 ConstraintInfo I; 47 I.Kind = Tied; 48 I.OtherTiedOperand = Op; 49 return I; 50 } 51 isNone()52 bool isNone() const { return Kind == None; } isEarlyClobber()53 bool isEarlyClobber() const { return Kind == EarlyClobber; } isTied()54 bool isTied() const { return Kind == Tied; } 55 getTiedOperand()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 the 72 /// 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 in 86 /// the asmprinter. 87 StringRef PrinterMethodName; 88 89 /// The method used to get the machine operand value for binary 90 /// encoding, per sub-operand. If empty, uses "getMachineOpValue". 91 std::vector<StringRef> EncoderMethodNames; 92 93 /// OperandType - A value from MCOI::OperandType representing the type of 94 /// the operand. 95 std::string OperandType; 96 97 /// MIOperandNo - Currently (this is meant to be phased out), some logical 98 /// operands correspond to multiple MachineInstr operands. In the X86 99 /// target for example, one address operand is represented as 4 100 /// MachineOperands. Because of this, the operand number in the 101 /// OperandList may not match the MachineInstr operand num. Until it 102 /// does, this contains the MI operand index of this operand. 103 unsigned MIOperandNo; 104 unsigned MINumOperands; // The number of operands. 105 106 /// DoNotEncode - Bools are set to true in this vector for each operand in 107 /// the DisableEncoding list. These should not be emitted by the code 108 /// emitter. 109 BitVector DoNotEncode; 110 111 /// MIOperandInfo - Default MI operand type. Note an operand may be made 112 /// up of multiple MI operands. 113 const DagInit *MIOperandInfo; 114 115 /// Constraint info for this operand. This operand can have pieces, so we 116 /// track constraint info for each. 117 std::vector<ConstraintInfo> Constraints; 118 OperandInfoOperandInfo119 OperandInfo(const Record *R, StringRef Name, StringRef PrinterMethodName, 120 const std::string &OT, unsigned MION, unsigned MINO, 121 const DagInit *MIOI) 122 : Rec(R), Name(Name), SubOpNames(MINO), 123 PrinterMethodName(PrinterMethodName), EncoderMethodNames(MINO), 124 OperandType(OT), MIOperandNo(MION), MINumOperands(MINO), 125 DoNotEncode(MINO), MIOperandInfo(MIOI), Constraints(MINO) {} 126 127 /// getTiedOperand - If this operand is tied to another one, return the 128 /// other operand number. Otherwise, return -1. getTiedRegisterOperandInfo129 int getTiedRegister() const { 130 for (const CGIOperandList::ConstraintInfo &CI : Constraints) 131 if (CI.isTied()) 132 return CI.getTiedOperand(); 133 return -1; 134 } 135 }; 136 137 CGIOperandList(const Record *D); 138 139 const Record *TheDef; // The actual record containing this OperandList. 140 141 /// NumDefs - Number of def operands declared, this is the number of 142 /// elements in the instruction's (outs) list. 143 /// 144 unsigned NumDefs; 145 146 /// OperandList - The list of declared operands, along with their declared 147 /// type (which is a record). 148 std::vector<OperandInfo> OperandList; 149 150 /// SubOpAliases - List of alias names for suboperands. 151 StringMap<std::pair<unsigned, unsigned>> SubOpAliases; 152 153 // Information gleaned from the operand list. 154 bool isPredicable; 155 bool hasOptionalDef; 156 bool isVariadic; 157 158 // Provide transparent accessors to the operand list. empty()159 bool empty() const { return OperandList.empty(); } size()160 unsigned size() const { return OperandList.size(); } 161 const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } 162 OperandInfo &operator[](unsigned i) { return OperandList[i]; } back()163 OperandInfo &back() { return OperandList.back(); } back()164 const OperandInfo &back() const { return OperandList.back(); } 165 166 typedef std::vector<OperandInfo>::iterator iterator; 167 typedef std::vector<OperandInfo>::const_iterator const_iterator; begin()168 iterator begin() { return OperandList.begin(); } begin()169 const_iterator begin() const { return OperandList.begin(); } end()170 iterator end() { return OperandList.end(); } end()171 const_iterator end() const { return OperandList.end(); } 172 173 /// getOperandNamed - Return the index of the operand with the specified 174 /// non-empty name. If the instruction does not have an operand with the 175 /// specified name, abort. 176 unsigned getOperandNamed(StringRef Name) const; 177 178 /// findOperandNamed - Query whether the instruction has an operand of the 179 /// given name. If so, the index of the operand. Otherwise, return 180 /// std::nullopt. 181 std::optional<unsigned> findOperandNamed(StringRef Name) const; 182 183 std::optional<std::pair<unsigned, unsigned>> 184 findSubOperandAlias(StringRef Name) const; 185 186 /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", 187 /// where $foo is a whole operand and $foo.bar refers to a suboperand. 188 /// This aborts if the name is invalid. If AllowWholeOp is true, references 189 /// to operands with suboperands are allowed, otherwise not. 190 std::pair<unsigned, unsigned> ParseOperandName(StringRef Op, 191 bool AllowWholeOp = true); 192 193 /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a 194 /// flat machineinstr operand #. getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)195 unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const { 196 return OperandList[Op.first].MIOperandNo + Op.second; 197 } 198 199 /// getSubOperandNumber - Unflatten a operand number into an 200 /// operand/suboperand pair. getSubOperandNumber(unsigned Op)201 std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const { 202 for (unsigned i = 0;; ++i) { 203 assert(i < OperandList.size() && "Invalid flat operand #"); 204 if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op) 205 return {i, Op - OperandList[i].MIOperandNo}; 206 } 207 } 208 209 /// isFlatOperandNotEmitted - Return true if the specified flat operand # 210 /// should not be emitted with the code emitter. isFlatOperandNotEmitted(unsigned FlatOpNo)211 bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { 212 std::pair<unsigned, unsigned> Op = getSubOperandNumber(FlatOpNo); 213 if (OperandList[Op.first].DoNotEncode.size() > Op.second) 214 return OperandList[Op.first].DoNotEncode[Op.second]; 215 return false; 216 } 217 218 void ProcessDisableEncoding(StringRef Value); 219 }; 220 221 class CodeGenInstruction { 222 public: 223 const Record *TheDef; // The actual record defining this instruction. 224 StringRef Namespace; // The namespace the instruction is in. 225 226 /// AsmString - The format string used to emit a .s file for the 227 /// instruction. 228 StringRef AsmString; 229 230 /// Operands - This is information about the (ins) and (outs) list specified 231 /// to the instruction. 232 CGIOperandList Operands; 233 234 /// ImplicitDefs/ImplicitUses - These are lists of registers that are 235 /// implicitly defined and used by the instruction. 236 std::vector<const Record *> ImplicitDefs, ImplicitUses; 237 238 // Various boolean values we track for the instruction. 239 bool isPreISelOpcode : 1; 240 bool isReturn : 1; 241 bool isEHScopeReturn : 1; 242 bool isBranch : 1; 243 bool isIndirectBranch : 1; 244 bool isCompare : 1; 245 bool isMoveImm : 1; 246 bool isMoveReg : 1; 247 bool isBitcast : 1; 248 bool isSelect : 1; 249 bool isBarrier : 1; 250 bool isCall : 1; 251 bool isAdd : 1; 252 bool isTrap : 1; 253 bool canFoldAsLoad : 1; 254 bool mayLoad : 1; 255 bool mayLoad_Unset : 1; 256 bool mayStore : 1; 257 bool mayStore_Unset : 1; 258 bool mayRaiseFPException : 1; 259 bool isPredicable : 1; 260 bool isConvertibleToThreeAddress : 1; 261 bool isCommutable : 1; 262 bool isTerminator : 1; 263 bool isReMaterializable : 1; 264 bool hasDelaySlot : 1; 265 bool usesCustomInserter : 1; 266 bool hasPostISelHook : 1; 267 bool hasCtrlDep : 1; 268 bool isNotDuplicable : 1; 269 bool hasSideEffects : 1; 270 bool hasSideEffects_Unset : 1; 271 bool isAsCheapAsAMove : 1; 272 bool hasExtraSrcRegAllocReq : 1; 273 bool hasExtraDefRegAllocReq : 1; 274 bool isCodeGenOnly : 1; 275 bool isPseudo : 1; 276 bool isMeta : 1; 277 bool isRegSequence : 1; 278 bool isExtractSubreg : 1; 279 bool isInsertSubreg : 1; 280 bool isConvergent : 1; 281 bool hasNoSchedulingInfo : 1; 282 bool FastISelShouldIgnore : 1; 283 bool hasChain : 1; 284 bool hasChain_Inferred : 1; 285 bool variadicOpsAreDefs : 1; 286 bool isAuthenticated : 1; 287 288 std::string DeprecatedReason; 289 bool HasComplexDeprecationPredicate; 290 291 /// Are there any undefined flags? hasUndefFlags()292 bool hasUndefFlags() const { 293 return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; 294 } 295 296 // The record used to infer instruction flags, or NULL if no flag values 297 // have been inferred. 298 const Record *InferredFrom; 299 300 // The enum value assigned by CodeGenTarget::computeInstrsByEnum. 301 mutable unsigned EnumVal = 0; 302 303 CodeGenInstruction(const Record *R); 304 305 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one 306 /// implicit def and it has a known VT, return the VT, otherwise return 307 /// MVT::Other. 308 MVT::SimpleValueType 309 HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; 310 311 /// FlattenAsmStringVariants - Flatten the specified AsmString to only 312 /// include text from the specified variant, returning the new string. 313 static std::string FlattenAsmStringVariants(StringRef AsmString, 314 unsigned Variant); 315 316 // Is the specified operand in a generic instruction implicitly a pointer. 317 // This can be used on intructions that use typeN or ptypeN to identify 318 // operands that should be considered as pointers even though SelectionDAG 319 // didn't make a distinction between integer and pointers. isInOperandAPointer(unsigned i)320 bool isInOperandAPointer(unsigned i) const { 321 return isOperandImpl("InOperandList", i, "IsPointer"); 322 } 323 isOutOperandAPointer(unsigned i)324 bool isOutOperandAPointer(unsigned i) const { 325 return isOperandImpl("OutOperandList", i, "IsPointer"); 326 } 327 328 /// Check if the operand is required to be an immediate. isInOperandImmArg(unsigned i)329 bool isInOperandImmArg(unsigned i) const { 330 return isOperandImpl("InOperandList", i, "IsImmediate"); 331 } 332 333 /// Return true if the instruction uses a variable length encoding. isVariableLengthEncoding()334 bool isVariableLengthEncoding() const { 335 const RecordVal *RV = TheDef->getValue("Inst"); 336 return RV && isa<DagInit>(RV->getValue()); 337 } 338 339 private: 340 bool isOperandImpl(StringRef OpListName, unsigned i, 341 StringRef PropertyName) const; 342 }; 343 } // namespace llvm 344 345 #endif // LLVM_UTILS_TABLEGEN_COMMON_CODEGENINSTRUCTION_H 346