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/Support/MachineValueType.h" 20 #include <cassert> 21 #include <string> 22 #include <utility> 23 #include <vector> 24 25 namespace llvm { 26 class SMLoc; 27 template <typename T> class ArrayRef; 28 class Record; 29 class DagInit; 30 class CodeGenTarget; 31 32 class CGIOperandList { 33 public: 34 class ConstraintInfo { 35 enum { None, EarlyClobber, Tied } Kind = None; 36 unsigned OtherTiedOperand = 0; 37 38 public: 39 ConstraintInfo() = default; 40 getEarlyClobber()41 static ConstraintInfo getEarlyClobber() { 42 ConstraintInfo I; 43 I.Kind = EarlyClobber; 44 I.OtherTiedOperand = 0; 45 return I; 46 } 47 getTied(unsigned Op)48 static ConstraintInfo getTied(unsigned Op) { 49 ConstraintInfo I; 50 I.Kind = Tied; 51 I.OtherTiedOperand = Op; 52 return I; 53 } 54 isNone()55 bool isNone() const { return Kind == None; } isEarlyClobber()56 bool isEarlyClobber() const { return Kind == EarlyClobber; } isTied()57 bool isTied() const { return Kind == Tied; } 58 getTiedOperand()59 unsigned getTiedOperand() const { 60 assert(isTied()); 61 return OtherTiedOperand; 62 } 63 64 bool operator==(const ConstraintInfo &RHS) const { 65 if (Kind != RHS.Kind) 66 return false; 67 if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand) 68 return false; 69 return true; 70 } 71 bool operator!=(const ConstraintInfo &RHS) const { 72 return !(*this == RHS); 73 } 74 }; 75 76 /// OperandInfo - The information we keep track of for each operand in the 77 /// operand list for a tablegen instruction. 78 struct OperandInfo { 79 /// Rec - The definition this operand is declared as. 80 /// 81 Record *Rec; 82 83 /// Name - If this operand was assigned a symbolic name, this is it, 84 /// otherwise, it's empty. 85 std::string Name; 86 87 /// The names of sub-operands, if given, otherwise empty. 88 std::vector<std::string> SubOpNames; 89 90 /// PrinterMethodName - The method used to print operands of this type in 91 /// the asmprinter. 92 std::string PrinterMethodName; 93 94 /// The method used to get the machine operand value for binary 95 /// encoding, per sub-operand. If empty, uses "getMachineOpValue". 96 std::vector<std::string> EncoderMethodNames; 97 98 /// OperandType - A value from MCOI::OperandType representing the type of 99 /// the operand. 100 std::string OperandType; 101 102 /// MIOperandNo - Currently (this is meant to be phased out), some logical 103 /// operands correspond to multiple MachineInstr operands. In the X86 104 /// target for example, one address operand is represented as 4 105 /// MachineOperands. Because of this, the operand number in the 106 /// OperandList may not match the MachineInstr operand num. Until it 107 /// does, this contains the MI operand index of this operand. 108 unsigned MIOperandNo; 109 unsigned MINumOperands; // The number of operands. 110 111 /// DoNotEncode - Bools are set to true in this vector for each operand in 112 /// the DisableEncoding list. These should not be emitted by the code 113 /// emitter. 114 BitVector DoNotEncode; 115 116 /// MIOperandInfo - Default MI operand type. Note an operand may be made 117 /// up of multiple MI operands. 118 DagInit *MIOperandInfo; 119 120 /// Constraint info for this operand. This operand can have pieces, so we 121 /// track constraint info for each. 122 std::vector<ConstraintInfo> Constraints; 123 OperandInfoOperandInfo124 OperandInfo(Record *R, const std::string &N, const std::string &PMN, 125 const std::string &OT, unsigned MION, unsigned MINO, 126 DagInit *MIOI) 127 : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN), 128 EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION), 129 MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI), 130 Constraints(MINO) {} 131 132 /// getTiedOperand - If this operand is tied to another one, return the 133 /// other operand number. Otherwise, return -1. getTiedRegisterOperandInfo134 int getTiedRegister() const { 135 for (unsigned j = 0, e = Constraints.size(); j != e; ++j) { 136 const CGIOperandList::ConstraintInfo &CI = Constraints[j]; 137 if (CI.isTied()) return CI.getTiedOperand(); 138 } 139 return -1; 140 } 141 }; 142 143 CGIOperandList(Record *D); 144 145 Record *TheDef; // The actual record containing this OperandList. 146 147 /// NumDefs - Number of def operands declared, this is the number of 148 /// elements in the instruction's (outs) list. 149 /// 150 unsigned NumDefs; 151 152 /// OperandList - The list of declared operands, along with their declared 153 /// type (which is a record). 154 std::vector<OperandInfo> OperandList; 155 156 /// SubOpAliases - List of alias names for suboperands. 157 StringMap<std::pair<unsigned, unsigned>> SubOpAliases; 158 159 // Information gleaned from the operand list. 160 bool isPredicable; 161 bool hasOptionalDef; 162 bool isVariadic; 163 164 // Provide transparent accessors to the operand list. empty()165 bool empty() const { return OperandList.empty(); } size()166 unsigned size() const { return OperandList.size(); } 167 const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } 168 OperandInfo &operator[](unsigned i) { return OperandList[i]; } back()169 OperandInfo &back() { return OperandList.back(); } back()170 const OperandInfo &back() const { return OperandList.back(); } 171 172 typedef std::vector<OperandInfo>::iterator iterator; 173 typedef std::vector<OperandInfo>::const_iterator const_iterator; begin()174 iterator begin() { return OperandList.begin(); } begin()175 const_iterator begin() const { return OperandList.begin(); } end()176 iterator end() { return OperandList.end(); } end()177 const_iterator end() const { return OperandList.end(); } 178 179 /// getOperandNamed - Return the index of the operand with the specified 180 /// non-empty name. If the instruction does not have an operand with the 181 /// specified name, abort. 182 unsigned getOperandNamed(StringRef Name) const; 183 184 /// hasOperandNamed - Query whether the instruction has an operand of the 185 /// given name. If so, return true and set OpIdx to the index of the 186 /// operand. Otherwise, return false. 187 bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const; 188 189 bool hasSubOperandAlias(StringRef Name, 190 std::pair<unsigned, unsigned> &SubOp) const; 191 192 /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", 193 /// where $foo is a whole operand and $foo.bar refers to a suboperand. 194 /// This aborts if the name is invalid. If AllowWholeOp is true, references 195 /// to operands with suboperands are allowed, otherwise not. 196 std::pair<unsigned,unsigned> ParseOperandName(StringRef Op, 197 bool AllowWholeOp = true); 198 199 /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a 200 /// flat machineinstr operand #. getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)201 unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const { 202 return OperandList[Op.first].MIOperandNo + Op.second; 203 } 204 205 /// getSubOperandNumber - Unflatten a operand number into an 206 /// operand/suboperand pair. getSubOperandNumber(unsigned Op)207 std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const { 208 for (unsigned i = 0; ; ++i) { 209 assert(i < OperandList.size() && "Invalid flat operand #"); 210 if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op) 211 return std::make_pair(i, Op-OperandList[i].MIOperandNo); 212 } 213 } 214 215 216 /// isFlatOperandNotEmitted - Return true if the specified flat operand # 217 /// should not be emitted with the code emitter. isFlatOperandNotEmitted(unsigned FlatOpNo)218 bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { 219 std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo); 220 if (OperandList[Op.first].DoNotEncode.size() > Op.second) 221 return OperandList[Op.first].DoNotEncode[Op.second]; 222 return false; 223 } 224 225 void ProcessDisableEncoding(StringRef Value); 226 }; 227 228 229 class CodeGenInstruction { 230 public: 231 Record *TheDef; // The actual record defining this instruction. 232 StringRef Namespace; // The namespace the instruction is in. 233 234 /// AsmString - The format string used to emit a .s file for the 235 /// instruction. 236 std::string AsmString; 237 238 /// Operands - This is information about the (ins) and (outs) list specified 239 /// to the instruction. 240 CGIOperandList Operands; 241 242 /// ImplicitDefs/ImplicitUses - These are lists of registers that are 243 /// implicitly defined and used by the instruction. 244 std::vector<Record*> ImplicitDefs, ImplicitUses; 245 246 // Various boolean values we track for the instruction. 247 bool isPreISelOpcode : 1; 248 bool isReturn : 1; 249 bool isEHScopeReturn : 1; 250 bool isBranch : 1; 251 bool isIndirectBranch : 1; 252 bool isCompare : 1; 253 bool isMoveImm : 1; 254 bool isMoveReg : 1; 255 bool isBitcast : 1; 256 bool isSelect : 1; 257 bool isBarrier : 1; 258 bool isCall : 1; 259 bool isAdd : 1; 260 bool isTrap : 1; 261 bool canFoldAsLoad : 1; 262 bool mayLoad : 1; 263 bool mayLoad_Unset : 1; 264 bool mayStore : 1; 265 bool mayStore_Unset : 1; 266 bool mayRaiseFPException : 1; 267 bool isPredicable : 1; 268 bool isConvertibleToThreeAddress : 1; 269 bool isCommutable : 1; 270 bool isTerminator : 1; 271 bool isReMaterializable : 1; 272 bool hasDelaySlot : 1; 273 bool usesCustomInserter : 1; 274 bool hasPostISelHook : 1; 275 bool hasCtrlDep : 1; 276 bool isNotDuplicable : 1; 277 bool hasSideEffects : 1; 278 bool hasSideEffects_Unset : 1; 279 bool isAsCheapAsAMove : 1; 280 bool hasExtraSrcRegAllocReq : 1; 281 bool hasExtraDefRegAllocReq : 1; 282 bool isCodeGenOnly : 1; 283 bool isPseudo : 1; 284 bool isMeta : 1; 285 bool isRegSequence : 1; 286 bool isExtractSubreg : 1; 287 bool isInsertSubreg : 1; 288 bool isConvergent : 1; 289 bool hasNoSchedulingInfo : 1; 290 bool FastISelShouldIgnore : 1; 291 bool hasChain : 1; 292 bool hasChain_Inferred : 1; 293 bool variadicOpsAreDefs : 1; 294 bool isAuthenticated : 1; 295 296 std::string DeprecatedReason; 297 bool HasComplexDeprecationPredicate; 298 299 /// Are there any undefined flags? hasUndefFlags()300 bool hasUndefFlags() const { 301 return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; 302 } 303 304 // The record used to infer instruction flags, or NULL if no flag values 305 // have been inferred. 306 Record *InferredFrom; 307 308 CodeGenInstruction(Record *R); 309 310 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one 311 /// implicit def and it has a known VT, return the VT, otherwise return 312 /// MVT::Other. 313 MVT::SimpleValueType 314 HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; 315 316 317 /// FlattenAsmStringVariants - Flatten the specified AsmString to only 318 /// include text from the specified variant, returning the new string. 319 static std::string FlattenAsmStringVariants(StringRef AsmString, 320 unsigned Variant); 321 322 // Is the specified operand in a generic instruction implicitly a pointer. 323 // This can be used on intructions that use typeN or ptypeN to identify 324 // operands that should be considered as pointers even though SelectionDAG 325 // didn't make a distinction between integer and pointers. isInOperandAPointer(unsigned i)326 bool isInOperandAPointer(unsigned i) const { 327 return isOperandImpl("InOperandList", i, "IsPointer"); 328 } 329 isOutOperandAPointer(unsigned i)330 bool isOutOperandAPointer(unsigned i) const { 331 return isOperandImpl("OutOperandList", i, "IsPointer"); 332 } 333 334 /// Check if the operand is required to be an immediate. isInOperandImmArg(unsigned i)335 bool isInOperandImmArg(unsigned i) const { 336 return isOperandImpl("InOperandList", i, "IsImmediate"); 337 } 338 339 private: 340 bool isOperandImpl(StringRef OpListName, unsigned i, 341 StringRef PropertyName) const; 342 }; 343 344 345 /// CodeGenInstAlias - This represents an InstAlias definition. 346 class CodeGenInstAlias { 347 public: 348 Record *TheDef; // The actual record defining this InstAlias. 349 350 /// AsmString - The format string used to emit a .s file for the 351 /// instruction. 352 std::string AsmString; 353 354 /// Result - The result instruction. 355 DagInit *Result; 356 357 /// ResultInst - The instruction generated by the alias (decoded from 358 /// Result). 359 CodeGenInstruction *ResultInst; 360 361 362 struct ResultOperand { 363 private: 364 std::string Name; 365 Record *R = nullptr; 366 int64_t Imm = 0; 367 368 public: 369 enum { 370 K_Record, 371 K_Imm, 372 K_Reg 373 } Kind; 374 ResultOperandResultOperand375 ResultOperand(std::string N, Record *r) 376 : Name(std::move(N)), R(r), Kind(K_Record) {} ResultOperandResultOperand377 ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {} ResultOperandResultOperand378 ResultOperand(Record *r) : R(r), Kind(K_Reg) {} 379 isRecordResultOperand380 bool isRecord() const { return Kind == K_Record; } isImmResultOperand381 bool isImm() const { return Kind == K_Imm; } isRegResultOperand382 bool isReg() const { return Kind == K_Reg; } 383 getNameResultOperand384 StringRef getName() const { assert(isRecord()); return Name; } getRecordResultOperand385 Record *getRecord() const { assert(isRecord()); return R; } getImmResultOperand386 int64_t getImm() const { assert(isImm()); return Imm; } getRegisterResultOperand387 Record *getRegister() const { assert(isReg()); return R; } 388 389 unsigned getMINumOperands() const; 390 }; 391 392 /// ResultOperands - The decoded operands for the result instruction. 393 std::vector<ResultOperand> ResultOperands; 394 395 /// ResultInstOperandIndex - For each operand, this vector holds a pair of 396 /// indices to identify the corresponding operand in the result 397 /// instruction. The first index specifies the operand and the second 398 /// index specifies the suboperand. If there are no suboperands or if all 399 /// of them are matched by the operand, the second value should be -1. 400 std::vector<std::pair<unsigned, int> > ResultInstOperandIndex; 401 402 CodeGenInstAlias(Record *R, CodeGenTarget &T); 403 404 bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, 405 Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc, 406 CodeGenTarget &T, ResultOperand &ResOp); 407 }; 408 } 409 410 #endif 411