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