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_CODEGENINSTRUCTION_H 14 #define LLVM_UTILS_TABLEGEN_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 Record *Rec; 77 78 /// Name - If this operand was assigned a symbolic name, this is it, 79 /// otherwise, it's empty. 80 std::string Name; 81 82 /// The names of sub-operands, if given, otherwise empty. 83 std::vector<std::string> SubOpNames; 84 85 /// PrinterMethodName - The method used to print operands of this type in 86 /// the asmprinter. 87 std::string 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<std::string> 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 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(Record *R, const std::string &N, const std::string &PMN, 120 const std::string &OT, unsigned MION, unsigned MINO, 121 DagInit *MIOI) 122 : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN), 123 EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION), 124 MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI), 125 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 (unsigned j = 0, e = Constraints.size(); j != e; ++j) { 131 const CGIOperandList::ConstraintInfo &CI = Constraints[j]; 132 if (CI.isTied()) 133 return CI.getTiedOperand(); 134 } 135 return -1; 136 } 137 }; 138 139 CGIOperandList(Record *D); 140 141 Record *TheDef; // The actual record containing this OperandList. 142 143 /// NumDefs - Number of def operands declared, this is the number of 144 /// elements in the instruction's (outs) list. 145 /// 146 unsigned NumDefs; 147 148 /// OperandList - The list of declared operands, along with their declared 149 /// type (which is a record). 150 std::vector<OperandInfo> OperandList; 151 152 /// SubOpAliases - List of alias names for suboperands. 153 StringMap<std::pair<unsigned, unsigned>> SubOpAliases; 154 155 // Information gleaned from the operand list. 156 bool isPredicable; 157 bool hasOptionalDef; 158 bool isVariadic; 159 160 // Provide transparent accessors to the operand list. empty()161 bool empty() const { return OperandList.empty(); } size()162 unsigned size() const { return OperandList.size(); } 163 const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } 164 OperandInfo &operator[](unsigned i) { return OperandList[i]; } back()165 OperandInfo &back() { return OperandList.back(); } back()166 const OperandInfo &back() const { return OperandList.back(); } 167 168 typedef std::vector<OperandInfo>::iterator iterator; 169 typedef std::vector<OperandInfo>::const_iterator const_iterator; begin()170 iterator begin() { return OperandList.begin(); } begin()171 const_iterator begin() const { return OperandList.begin(); } end()172 iterator end() { return OperandList.end(); } end()173 const_iterator end() const { return OperandList.end(); } 174 175 /// getOperandNamed - Return the index of the operand with the specified 176 /// non-empty name. If the instruction does not have an operand with the 177 /// specified name, abort. 178 unsigned getOperandNamed(StringRef Name) const; 179 180 /// hasOperandNamed - Query whether the instruction has an operand of the 181 /// given name. If so, return true and set OpIdx to the index of the 182 /// operand. Otherwise, return false. 183 bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const; 184 185 bool hasSubOperandAlias(StringRef Name, 186 std::pair<unsigned, unsigned> &SubOp) const; 187 188 /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", 189 /// where $foo is a whole operand and $foo.bar refers to a suboperand. 190 /// This aborts if the name is invalid. If AllowWholeOp is true, references 191 /// to operands with suboperands are allowed, otherwise not. 192 std::pair<unsigned, unsigned> ParseOperandName(StringRef Op, 193 bool AllowWholeOp = true); 194 195 /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a 196 /// flat machineinstr operand #. getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)197 unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const { 198 return OperandList[Op.first].MIOperandNo + Op.second; 199 } 200 201 /// getSubOperandNumber - Unflatten a operand number into an 202 /// operand/suboperand pair. getSubOperandNumber(unsigned Op)203 std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const { 204 for (unsigned i = 0;; ++i) { 205 assert(i < OperandList.size() && "Invalid flat operand #"); 206 if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op) 207 return std::pair(i, Op - OperandList[i].MIOperandNo); 208 } 209 } 210 211 /// isFlatOperandNotEmitted - Return true if the specified flat operand # 212 /// should not be emitted with the code emitter. isFlatOperandNotEmitted(unsigned FlatOpNo)213 bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { 214 std::pair<unsigned, unsigned> Op = getSubOperandNumber(FlatOpNo); 215 if (OperandList[Op.first].DoNotEncode.size() > Op.second) 216 return OperandList[Op.first].DoNotEncode[Op.second]; 217 return false; 218 } 219 220 void ProcessDisableEncoding(StringRef Value); 221 }; 222 223 class CodeGenInstruction { 224 public: 225 Record *TheDef; // The actual record defining this instruction. 226 StringRef Namespace; // The namespace the instruction is in. 227 228 /// AsmString - The format string used to emit a .s file for the 229 /// instruction. 230 std::string AsmString; 231 232 /// Operands - This is information about the (ins) and (outs) list specified 233 /// to the instruction. 234 CGIOperandList Operands; 235 236 /// ImplicitDefs/ImplicitUses - These are lists of registers that are 237 /// implicitly defined and used by the instruction. 238 std::vector<Record *> ImplicitDefs, ImplicitUses; 239 240 // Various boolean values we track for the instruction. 241 bool isPreISelOpcode : 1; 242 bool isReturn : 1; 243 bool isEHScopeReturn : 1; 244 bool isBranch : 1; 245 bool isIndirectBranch : 1; 246 bool isCompare : 1; 247 bool isMoveImm : 1; 248 bool isMoveReg : 1; 249 bool isBitcast : 1; 250 bool isSelect : 1; 251 bool isBarrier : 1; 252 bool isCall : 1; 253 bool isAdd : 1; 254 bool isTrap : 1; 255 bool canFoldAsLoad : 1; 256 bool mayLoad : 1; 257 bool mayLoad_Unset : 1; 258 bool mayStore : 1; 259 bool mayStore_Unset : 1; 260 bool mayRaiseFPException : 1; 261 bool isPredicable : 1; 262 bool isConvertibleToThreeAddress : 1; 263 bool isCommutable : 1; 264 bool isTerminator : 1; 265 bool isReMaterializable : 1; 266 bool hasDelaySlot : 1; 267 bool usesCustomInserter : 1; 268 bool hasPostISelHook : 1; 269 bool hasCtrlDep : 1; 270 bool isNotDuplicable : 1; 271 bool hasSideEffects : 1; 272 bool hasSideEffects_Unset : 1; 273 bool isAsCheapAsAMove : 1; 274 bool hasExtraSrcRegAllocReq : 1; 275 bool hasExtraDefRegAllocReq : 1; 276 bool isCodeGenOnly : 1; 277 bool isPseudo : 1; 278 bool isMeta : 1; 279 bool isRegSequence : 1; 280 bool isExtractSubreg : 1; 281 bool isInsertSubreg : 1; 282 bool isConvergent : 1; 283 bool hasNoSchedulingInfo : 1; 284 bool FastISelShouldIgnore : 1; 285 bool hasChain : 1; 286 bool hasChain_Inferred : 1; 287 bool variadicOpsAreDefs : 1; 288 bool isAuthenticated : 1; 289 290 std::string DeprecatedReason; 291 bool HasComplexDeprecationPredicate; 292 293 /// Are there any undefined flags? hasUndefFlags()294 bool hasUndefFlags() const { 295 return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; 296 } 297 298 // The record used to infer instruction flags, or NULL if no flag values 299 // have been inferred. 300 Record *InferredFrom; 301 302 // The enum value assigned by CodeGenTarget::computeInstrsByEnum. 303 mutable unsigned EnumVal = 0; 304 305 CodeGenInstruction(Record *R); 306 307 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one 308 /// implicit def and it has a known VT, return the VT, otherwise return 309 /// MVT::Other. 310 MVT::SimpleValueType 311 HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; 312 313 /// FlattenAsmStringVariants - Flatten the specified AsmString to only 314 /// include text from the specified variant, returning the new string. 315 static std::string FlattenAsmStringVariants(StringRef AsmString, 316 unsigned Variant); 317 318 // Is the specified operand in a generic instruction implicitly a pointer. 319 // This can be used on intructions that use typeN or ptypeN to identify 320 // operands that should be considered as pointers even though SelectionDAG 321 // didn't make a distinction between integer and pointers. isInOperandAPointer(unsigned i)322 bool isInOperandAPointer(unsigned i) const { 323 return isOperandImpl("InOperandList", i, "IsPointer"); 324 } 325 isOutOperandAPointer(unsigned i)326 bool isOutOperandAPointer(unsigned i) const { 327 return isOperandImpl("OutOperandList", i, "IsPointer"); 328 } 329 330 /// Check if the operand is required to be an immediate. isInOperandImmArg(unsigned i)331 bool isInOperandImmArg(unsigned i) const { 332 return isOperandImpl("InOperandList", i, "IsImmediate"); 333 } 334 335 /// Return true if the instruction uses a variable length encoding. isVariableLengthEncoding()336 bool isVariableLengthEncoding() const { 337 const RecordVal *RV = TheDef->getValue("Inst"); 338 return RV && isa<DagInit>(RV->getValue()); 339 } 340 341 private: 342 bool isOperandImpl(StringRef OpListName, unsigned i, 343 StringRef PropertyName) const; 344 }; 345 } // namespace llvm 346 347 #endif 348