1 //===-- SPIRVGlobalRegistry.h - SPIR-V Global Registry ----------*- 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 // SPIRVGlobalRegistry is used to maintain rich type information required for 10 // SPIR-V even after lowering from LLVM IR to GMIR. It can convert an llvm::Type 11 // into an OpTypeXXX instruction, and map it to a virtual register. Also it 12 // builds and supports consistency of constants and global variables. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H 17 #define LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H 18 19 #include "MCTargetDesc/SPIRVBaseInfo.h" 20 #include "SPIRVDuplicatesTracker.h" 21 #include "SPIRVInstrInfo.h" 22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23 #include "llvm/IR/Constant.h" 24 #include "llvm/IR/TypedPointerType.h" 25 26 namespace llvm { 27 class SPIRVSubtarget; 28 using SPIRVType = const MachineInstr; 29 30 class SPIRVGlobalRegistry { 31 // Registers holding values which have types associated with them. 32 // Initialized upon VReg definition in IRTranslator. 33 // Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg> 34 // where Reg = OpType... 35 // while VRegToTypeMap tracks SPIR-V type assigned to other regs (i.e. not 36 // type-declaring ones). 37 DenseMap<const MachineFunction *, DenseMap<Register, SPIRVType *>> 38 VRegToTypeMap; 39 40 // Map LLVM Type* to <MF, Reg> 41 SPIRVGeneralDuplicatesTracker DT; 42 43 DenseMap<SPIRVType *, const Type *> SPIRVToLLVMType; 44 45 // map a Function to its definition (as a machine instruction operand) 46 DenseMap<const Function *, const MachineOperand *> FunctionToInstr; 47 DenseMap<const MachineInstr *, const Function *> FunctionToInstrRev; 48 // map function pointer (as a machine instruction operand) to the used 49 // Function 50 DenseMap<const MachineOperand *, const Function *> InstrToFunction; 51 // Maps Functions to their calls (in a form of the machine instruction, 52 // OpFunctionCall) that happened before the definition is available 53 DenseMap<const Function *, SmallPtrSet<MachineInstr *, 8>> ForwardCalls; 54 // map a Function to its original return type before the clone function was 55 // created during substitution of aggregate arguments 56 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`) 57 DenseMap<Value *, Type *> MutatedAggRet; 58 // map an instruction to its value's attributes (type, name) 59 DenseMap<MachineInstr *, std::pair<Type *, std::string>> ValueAttrs; 60 61 // Look for an equivalent of the newType in the map. Return the equivalent 62 // if it's found, otherwise insert newType to the map and return the type. 63 const MachineInstr *checkSpecialInstr(const SPIRV::SpecialTypeDescriptor &TD, 64 MachineIRBuilder &MIRBuilder); 65 66 SmallPtrSet<const Type *, 4> TypesInProcessing; 67 DenseMap<const Type *, SPIRVType *> ForwardPointerTypes; 68 69 // Stores for each function the last inserted SPIR-V Type. 70 // See: SPIRVGlobalRegistry::createOpType. 71 DenseMap<const MachineFunction *, MachineInstr *> LastInsertedTypeMap; 72 73 // if a function returns a pointer, this is to map it into TypedPointerType 74 DenseMap<const Function *, TypedPointerType *> FunResPointerTypes; 75 76 // Number of bits pointers and size_t integers require. 77 const unsigned PointerSize; 78 79 // Holds the maximum ID we have in the module. 80 unsigned Bound; 81 82 // Maps values associated with untyped pointers into deduced element types of 83 // untyped pointers. 84 DenseMap<Value *, Type *> DeducedElTys; 85 // Maps composite values to deduced types where untyped pointers are replaced 86 // with typed ones. 87 DenseMap<Value *, Type *> DeducedNestedTys; 88 // Maps values to "assign type" calls, thus being a registry of created 89 // Intrinsic::spv_assign_ptr_type instructions. 90 DenseMap<Value *, CallInst *> AssignPtrTypeInstr; 91 92 // Maps OpVariable and OpFunction-related v-regs to its LLVM IR definition. 93 DenseMap<std::pair<const MachineFunction *, Register>, const Value *> Reg2GO; 94 95 // Add a new OpTypeXXX instruction without checking for duplicates. 96 SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, 97 SPIRV::AccessQualifier::AccessQualifier AQ = 98 SPIRV::AccessQualifier::ReadWrite, 99 bool EmitIR = true); 100 SPIRVType *findSPIRVType(const Type *Ty, MachineIRBuilder &MIRBuilder, 101 SPIRV::AccessQualifier::AccessQualifier accessQual = 102 SPIRV::AccessQualifier::ReadWrite, 103 bool EmitIR = true); 104 SPIRVType * 105 restOfCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, 106 SPIRV::AccessQualifier::AccessQualifier AccessQual, 107 bool EmitIR); 108 109 // Internal function creating the an OpType at the correct position in the 110 // function by tweaking the passed "MIRBuilder" insertion point and restoring 111 // it to the correct position. "Op" should be the function creating the 112 // specific OpType you need, and should return the newly created instruction. 113 SPIRVType *createOpType(MachineIRBuilder &MIRBuilder, 114 std::function<MachineInstr *(MachineIRBuilder &)> Op); 115 116 public: 117 SPIRVGlobalRegistry(unsigned PointerSize); 118 119 MachineFunction *CurMF; 120 121 void add(const Constant *C, MachineFunction *MF, Register R) { 122 DT.add(C, MF, R); 123 } 124 125 void add(const GlobalVariable *GV, MachineFunction *MF, Register R) { 126 DT.add(GV, MF, R); 127 } 128 129 void add(const Function *F, MachineFunction *MF, Register R) { 130 DT.add(F, MF, R); 131 } 132 133 void add(const Argument *Arg, MachineFunction *MF, Register R) { 134 DT.add(Arg, MF, R); 135 } 136 137 void add(const MachineInstr *MI, MachineFunction *MF, Register R) { 138 DT.add(MI, MF, R); 139 } 140 141 Register find(const MachineInstr *MI, MachineFunction *MF) { 142 return DT.find(MI, MF); 143 } 144 145 Register find(const Constant *C, MachineFunction *MF) { 146 return DT.find(C, MF); 147 } 148 149 Register find(const GlobalVariable *GV, MachineFunction *MF) { 150 return DT.find(GV, MF); 151 } 152 153 Register find(const Function *F, MachineFunction *MF) { 154 return DT.find(F, MF); 155 } 156 157 void setBound(unsigned V) { Bound = V; } 158 unsigned getBound() { return Bound; } 159 160 void addGlobalObject(const Value *V, const MachineFunction *MF, Register R) { 161 Reg2GO[std::make_pair(MF, R)] = V; 162 } 163 const Value *getGlobalObject(const MachineFunction *MF, Register R) { 164 auto It = Reg2GO.find(std::make_pair(MF, R)); 165 return It == Reg2GO.end() ? nullptr : It->second; 166 } 167 168 // Add a record to the map of function return pointer types. 169 void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy) { 170 FunResPointerTypes[ArgF] = DerivedTy; 171 } 172 // Find a record in the map of function return pointer types. 173 const TypedPointerType *findReturnType(const Function *ArgF) { 174 auto It = FunResPointerTypes.find(ArgF); 175 return It == FunResPointerTypes.end() ? nullptr : It->second; 176 } 177 178 // A registry of "assign type" records: 179 // - Add a record. 180 void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI) { 181 AssignPtrTypeInstr[Val] = AssignPtrTyCI; 182 } 183 // - Find a record. 184 CallInst *findAssignPtrTypeInstr(const Value *Val) { 185 auto It = AssignPtrTypeInstr.find(Val); 186 return It == AssignPtrTypeInstr.end() ? nullptr : It->second; 187 } 188 // - Find a record and update its key or add a new record, if found. 189 void updateIfExistAssignPtrTypeInstr(Value *OldVal, Value *NewVal, 190 bool DeleteOld) { 191 if (CallInst *CI = findAssignPtrTypeInstr(OldVal)) { 192 if (DeleteOld) 193 AssignPtrTypeInstr.erase(OldVal); 194 AssignPtrTypeInstr[NewVal] = CI; 195 } 196 } 197 198 // A registry of mutated values 199 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`): 200 // - Add a record. 201 void addMutated(Value *Val, Type *Ty) { MutatedAggRet[Val] = Ty; } 202 // - Find a record. 203 Type *findMutated(const Value *Val) { 204 auto It = MutatedAggRet.find(Val); 205 return It == MutatedAggRet.end() ? nullptr : It->second; 206 } 207 208 // A registry of value's attributes (type, name) 209 // - Add a record. 210 void addValueAttrs(MachineInstr *Key, std::pair<Type *, std::string> Val) { 211 ValueAttrs[Key] = Val; 212 } 213 // - Find a record. 214 bool findValueAttrs(const MachineInstr *Key, Type *&Ty, StringRef &Name) { 215 auto It = ValueAttrs.find(Key); 216 if (It == ValueAttrs.end()) 217 return false; 218 Ty = It->second.first; 219 Name = It->second.second; 220 return true; 221 } 222 223 // Deduced element types of untyped pointers and composites: 224 // - Add a record to the map of deduced element types. 225 void addDeducedElementType(Value *Val, Type *Ty) { DeducedElTys[Val] = Ty; } 226 // - Find a record in the map of deduced element types. 227 Type *findDeducedElementType(const Value *Val) { 228 auto It = DeducedElTys.find(Val); 229 return It == DeducedElTys.end() ? nullptr : It->second; 230 } 231 // - Find a record and update its key or add a new record, if found. 232 void updateIfExistDeducedElementType(Value *OldVal, Value *NewVal, 233 bool DeleteOld) { 234 if (Type *Ty = findDeducedElementType(OldVal)) { 235 if (DeleteOld) 236 DeducedElTys.erase(OldVal); 237 DeducedElTys[NewVal] = Ty; 238 } 239 } 240 // - Add a record to the map of deduced composite types. 241 void addDeducedCompositeType(Value *Val, Type *Ty) { 242 DeducedNestedTys[Val] = Ty; 243 } 244 // - Find a record in the map of deduced composite types. 245 Type *findDeducedCompositeType(const Value *Val) { 246 auto It = DeducedNestedTys.find(Val); 247 return It == DeducedNestedTys.end() ? nullptr : It->second; 248 } 249 // - Find a type of the given Global value 250 Type *getDeducedGlobalValueType(const GlobalValue *Global) { 251 // we may know element type if it was deduced earlier 252 Type *ElementTy = findDeducedElementType(Global); 253 if (!ElementTy) { 254 // or we may know element type if it's associated with a composite 255 // value 256 if (Value *GlobalElem = 257 Global->getNumOperands() > 0 ? Global->getOperand(0) : nullptr) 258 ElementTy = findDeducedCompositeType(GlobalElem); 259 } 260 return ElementTy ? ElementTy : Global->getValueType(); 261 } 262 263 // Map a machine operand that represents a use of a function via function 264 // pointer to a machine operand that represents the function definition. 265 // Return either the register or invalid value, because we have no context for 266 // a good diagnostic message in case of unexpectedly missing references. 267 const MachineOperand *getFunctionDefinitionByUse(const MachineOperand *Use) { 268 auto ResF = InstrToFunction.find(Use); 269 if (ResF == InstrToFunction.end()) 270 return nullptr; 271 auto ResReg = FunctionToInstr.find(ResF->second); 272 return ResReg == FunctionToInstr.end() ? nullptr : ResReg->second; 273 } 274 275 // Map a Function to a machine instruction that represents the function 276 // definition. 277 const MachineInstr *getFunctionDefinition(const Function *F) { 278 if (!F) 279 return nullptr; 280 auto MOIt = FunctionToInstr.find(F); 281 return MOIt == FunctionToInstr.end() ? nullptr : MOIt->second->getParent(); 282 } 283 284 // Map a Function to a machine instruction that represents the function 285 // definition. 286 const Function *getFunctionByDefinition(const MachineInstr *MI) { 287 if (!MI) 288 return nullptr; 289 auto FIt = FunctionToInstrRev.find(MI); 290 return FIt == FunctionToInstrRev.end() ? nullptr : FIt->second; 291 } 292 293 // map function pointer (as a machine instruction operand) to the used 294 // Function 295 void recordFunctionPointer(const MachineOperand *MO, const Function *F) { 296 InstrToFunction[MO] = F; 297 } 298 299 // map a Function to its definition (as a machine instruction) 300 void recordFunctionDefinition(const Function *F, const MachineOperand *MO) { 301 FunctionToInstr[F] = MO; 302 FunctionToInstrRev[MO->getParent()] = F; 303 } 304 305 // Return true if any OpConstantFunctionPointerINTEL were generated 306 bool hasConstFunPtr() { return !InstrToFunction.empty(); } 307 308 // Add a record about forward function call. 309 void addForwardCall(const Function *F, MachineInstr *MI) { 310 ForwardCalls[F].insert(MI); 311 } 312 313 // Map a Function to the vector of machine instructions that represents 314 // forward function calls or to nullptr if not found. 315 SmallPtrSet<MachineInstr *, 8> *getForwardCalls(const Function *F) { 316 auto It = ForwardCalls.find(F); 317 return It == ForwardCalls.end() ? nullptr : &It->second; 318 } 319 320 // Get or create a SPIR-V type corresponding the given LLVM IR type, 321 // and map it to the given VReg by creating an ASSIGN_TYPE instruction. 322 SPIRVType *assignTypeToVReg(const Type *Type, Register VReg, 323 MachineIRBuilder &MIRBuilder, 324 SPIRV::AccessQualifier::AccessQualifier AQ = 325 SPIRV::AccessQualifier::ReadWrite, 326 bool EmitIR = true); 327 SPIRVType *assignIntTypeToVReg(unsigned BitWidth, Register VReg, 328 MachineInstr &I, const SPIRVInstrInfo &TII); 329 SPIRVType *assignFloatTypeToVReg(unsigned BitWidth, Register VReg, 330 MachineInstr &I, const SPIRVInstrInfo &TII); 331 SPIRVType *assignVectTypeToVReg(SPIRVType *BaseType, unsigned NumElements, 332 Register VReg, MachineInstr &I, 333 const SPIRVInstrInfo &TII); 334 335 // In cases where the SPIR-V type is already known, this function can be 336 // used to map it to the given VReg via an ASSIGN_TYPE instruction. 337 void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, 338 const MachineFunction &MF); 339 340 // Either generate a new OpTypeXXX instruction or return an existing one 341 // corresponding to the given LLVM IR type. 342 // EmitIR controls if we emit GMIR or SPV constants (e.g. for array sizes) 343 // because this method may be called from InstructionSelector and we don't 344 // want to emit extra IR instructions there. 345 SPIRVType *getOrCreateSPIRVType(const Type *Type, 346 MachineIRBuilder &MIRBuilder, 347 SPIRV::AccessQualifier::AccessQualifier AQ = 348 SPIRV::AccessQualifier::ReadWrite, 349 bool EmitIR = true); 350 351 const Type *getTypeForSPIRVType(const SPIRVType *Ty) const { 352 auto Res = SPIRVToLLVMType.find(Ty); 353 assert(Res != SPIRVToLLVMType.end()); 354 return Res->second; 355 } 356 357 // Return a pointee's type, or nullptr otherwise. 358 SPIRVType *getPointeeType(SPIRVType *PtrType); 359 // Return a pointee's type op code, or 0 otherwise. 360 unsigned getPointeeTypeOp(Register PtrReg); 361 362 // Either generate a new OpTypeXXX instruction or return an existing one 363 // corresponding to the given string containing the name of the builtin type. 364 // Return nullptr if unable to recognize SPIRV type name from `TypeStr`. 365 SPIRVType *getOrCreateSPIRVTypeByName( 366 StringRef TypeStr, MachineIRBuilder &MIRBuilder, 367 SPIRV::StorageClass::StorageClass SC = SPIRV::StorageClass::Function, 368 SPIRV::AccessQualifier::AccessQualifier AQ = 369 SPIRV::AccessQualifier::ReadWrite); 370 371 // Return the SPIR-V type instruction corresponding to the given VReg, or 372 // nullptr if no such type instruction exists. The second argument MF 373 // allows to search for the association in a context of the machine functions 374 // than the current one, without switching between different "current" machine 375 // functions. 376 SPIRVType *getSPIRVTypeForVReg(Register VReg, 377 const MachineFunction *MF = nullptr) const; 378 379 // Return the result type of the instruction defining the register. 380 SPIRVType *getResultType(Register VReg, MachineFunction *MF = nullptr); 381 382 // Whether the given VReg has a SPIR-V type mapped to it yet. 383 bool hasSPIRVTypeForVReg(Register VReg) const { 384 return getSPIRVTypeForVReg(VReg) != nullptr; 385 } 386 387 // Return the VReg holding the result of the given OpTypeXXX instruction. 388 Register getSPIRVTypeID(const SPIRVType *SpirvType) const; 389 390 // Return previous value of the current machine function 391 MachineFunction *setCurrentFunc(MachineFunction &MF) { 392 MachineFunction *Ret = CurMF; 393 CurMF = &MF; 394 return Ret; 395 } 396 397 // Return true if the type is an aggregate type. 398 bool isAggregateType(SPIRVType *Type) const { 399 return Type && (Type->getOpcode() == SPIRV::OpTypeStruct && 400 Type->getOpcode() == SPIRV::OpTypeArray); 401 } 402 403 // Whether the given VReg has an OpTypeXXX instruction mapped to it with the 404 // given opcode (e.g. OpTypeFloat). 405 bool isScalarOfType(Register VReg, unsigned TypeOpcode) const; 406 407 // Return true if the given VReg's assigned SPIR-V type is either a scalar 408 // matching the given opcode, or a vector with an element type matching that 409 // opcode (e.g. OpTypeBool, or OpTypeVector %x 4, where %x is OpTypeBool). 410 bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const; 411 412 // Return number of elements in a vector if the argument is associated with 413 // a vector type. Return 1 for a scalar type, and 0 for a missing type. 414 unsigned getScalarOrVectorComponentCount(Register VReg) const; 415 unsigned getScalarOrVectorComponentCount(SPIRVType *Type) const; 416 417 // Return the component type in a vector if the argument is associated with 418 // a vector type. Returns the argument itself for other types, and nullptr 419 // for a missing type. 420 SPIRVType *getScalarOrVectorComponentType(Register VReg) const; 421 SPIRVType *getScalarOrVectorComponentType(SPIRVType *Type) const; 422 423 // For vectors or scalars of booleans, integers and floats, return the scalar 424 // type's bitwidth. Otherwise calls llvm_unreachable(). 425 unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const; 426 427 // For vectors or scalars of integers and floats, return total bitwidth of the 428 // argument. Otherwise returns 0. 429 unsigned getNumScalarOrVectorTotalBitWidth(const SPIRVType *Type) const; 430 431 // Returns either pointer to integer type, that may be a type of vector 432 // elements or an original type, or nullptr if the argument is niether 433 // an integer scalar, nor an integer vector 434 const SPIRVType *retrieveScalarOrVectorIntType(const SPIRVType *Type) const; 435 436 // For integer vectors or scalars, return whether the integers are signed. 437 bool isScalarOrVectorSigned(const SPIRVType *Type) const; 438 439 // Gets the storage class of the pointer type assigned to this vreg. 440 SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const; 441 SPIRV::StorageClass::StorageClass 442 getPointerStorageClass(const SPIRVType *Type) const; 443 444 // Return the number of bits SPIR-V pointers and size_t variables require. 445 unsigned getPointerSize() const { return PointerSize; } 446 447 // Returns true if two types are defined and are compatible in a sense of 448 // OpBitcast instruction 449 bool isBitcastCompatible(const SPIRVType *Type1, 450 const SPIRVType *Type2) const; 451 452 // Informs about removal of the machine instruction and invalidates data 453 // structures referring this instruction. 454 void invalidateMachineInstr(MachineInstr *MI); 455 456 private: 457 SPIRVType *getOpTypeBool(MachineIRBuilder &MIRBuilder); 458 459 const Type *adjustIntTypeByWidth(const Type *Ty) const; 460 unsigned adjustOpTypeIntWidth(unsigned Width) const; 461 462 SPIRVType *getOpTypeInt(unsigned Width, MachineIRBuilder &MIRBuilder, 463 bool IsSigned = false); 464 465 SPIRVType *getOpTypeFloat(uint32_t Width, MachineIRBuilder &MIRBuilder); 466 467 SPIRVType *getOpTypeVoid(MachineIRBuilder &MIRBuilder); 468 469 SPIRVType *getOpTypeVector(uint32_t NumElems, SPIRVType *ElemType, 470 MachineIRBuilder &MIRBuilder); 471 472 SPIRVType *getOpTypeArray(uint32_t NumElems, SPIRVType *ElemType, 473 MachineIRBuilder &MIRBuilder, bool EmitIR = true); 474 475 SPIRVType *getOpTypeOpaque(const StructType *Ty, 476 MachineIRBuilder &MIRBuilder); 477 478 SPIRVType *getOpTypeStruct(const StructType *Ty, MachineIRBuilder &MIRBuilder, 479 bool EmitIR = true); 480 481 SPIRVType *getOpTypePointer(SPIRV::StorageClass::StorageClass SC, 482 SPIRVType *ElemType, MachineIRBuilder &MIRBuilder, 483 Register Reg); 484 485 SPIRVType *getOpTypeForwardPointer(SPIRV::StorageClass::StorageClass SC, 486 MachineIRBuilder &MIRBuilder); 487 488 SPIRVType *getOpTypeFunction(SPIRVType *RetType, 489 const SmallVectorImpl<SPIRVType *> &ArgTypes, 490 MachineIRBuilder &MIRBuilder); 491 492 SPIRVType * 493 getOrCreateSpecialType(const Type *Ty, MachineIRBuilder &MIRBuilder, 494 SPIRV::AccessQualifier::AccessQualifier AccQual); 495 496 std::tuple<Register, ConstantInt *, bool, unsigned> getOrCreateConstIntReg( 497 uint64_t Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder, 498 MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr); 499 std::tuple<Register, ConstantFP *, bool, unsigned> getOrCreateConstFloatReg( 500 APFloat Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder, 501 MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr); 502 SPIRVType *finishCreatingSPIRVType(const Type *LLVMTy, SPIRVType *SpirvType); 503 Register getOrCreateBaseRegister(Constant *Val, MachineInstr &I, 504 SPIRVType *SpvType, 505 const SPIRVInstrInfo &TII, unsigned BitWidth, 506 bool ZeroAsNull); 507 Register getOrCreateCompositeOrNull(Constant *Val, MachineInstr &I, 508 SPIRVType *SpvType, 509 const SPIRVInstrInfo &TII, Constant *CA, 510 unsigned BitWidth, unsigned ElemCnt, 511 bool ZeroAsNull = true); 512 513 Register getOrCreateIntCompositeOrNull(uint64_t Val, 514 MachineIRBuilder &MIRBuilder, 515 SPIRVType *SpvType, bool EmitIR, 516 Constant *CA, unsigned BitWidth, 517 unsigned ElemCnt); 518 519 public: 520 Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, 521 SPIRVType *SpvType, bool EmitIR = true, 522 bool ZeroAsNull = true); 523 Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, 524 SPIRVType *SpvType, const SPIRVInstrInfo &TII, 525 bool ZeroAsNull = true); 526 Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType, 527 const SPIRVInstrInfo &TII, 528 bool ZeroAsNull = true); 529 Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, 530 SPIRVType *SpvType = nullptr); 531 532 Register getOrCreateConstVector(uint64_t Val, MachineInstr &I, 533 SPIRVType *SpvType, const SPIRVInstrInfo &TII, 534 bool ZeroAsNull = true); 535 Register getOrCreateConstVector(APFloat Val, MachineInstr &I, 536 SPIRVType *SpvType, const SPIRVInstrInfo &TII, 537 bool ZeroAsNull = true); 538 Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, 539 SPIRVType *SpvType, 540 const SPIRVInstrInfo &TII); 541 Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, 542 SPIRVType *SpvType, bool EmitIR = true); 543 Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, 544 SPIRVType *SpvType); 545 Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, 546 unsigned FilerMode, 547 MachineIRBuilder &MIRBuilder, 548 SPIRVType *SpvType); 549 Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType, 550 const SPIRVInstrInfo &TII); 551 Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, 552 StringRef Name, const GlobalValue *GV, 553 SPIRV::StorageClass::StorageClass Storage, 554 const MachineInstr *Init, bool IsConst, 555 bool HasLinkageTy, 556 SPIRV::LinkageType::LinkageType LinkageType, 557 MachineIRBuilder &MIRBuilder, 558 bool IsInstSelector); 559 Register getOrCreateGlobalVariableWithBinding(const SPIRVType *VarType, 560 uint32_t Set, uint32_t Binding, 561 MachineIRBuilder &MIRBuilder); 562 563 // Convenient helpers for getting types with check for duplicates. 564 SPIRVType *getOrCreateSPIRVIntegerType(unsigned BitWidth, 565 MachineIRBuilder &MIRBuilder); 566 SPIRVType *getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineInstr &I, 567 const SPIRVInstrInfo &TII); 568 SPIRVType *getOrCreateSPIRVType(unsigned BitWidth, MachineInstr &I, 569 const SPIRVInstrInfo &TII, 570 unsigned SPIRVOPcode, Type *LLVMTy); 571 SPIRVType *getOrCreateSPIRVFloatType(unsigned BitWidth, MachineInstr &I, 572 const SPIRVInstrInfo &TII); 573 SPIRVType *getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder); 574 SPIRVType *getOrCreateSPIRVBoolType(MachineInstr &I, 575 const SPIRVInstrInfo &TII); 576 SPIRVType *getOrCreateSPIRVVectorType(SPIRVType *BaseType, 577 unsigned NumElements, 578 MachineIRBuilder &MIRBuilder); 579 SPIRVType *getOrCreateSPIRVVectorType(SPIRVType *BaseType, 580 unsigned NumElements, MachineInstr &I, 581 const SPIRVInstrInfo &TII); 582 SPIRVType *getOrCreateSPIRVArrayType(SPIRVType *BaseType, 583 unsigned NumElements, MachineInstr &I, 584 const SPIRVInstrInfo &TII); 585 586 SPIRVType *getOrCreateSPIRVPointerType( 587 SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, 588 SPIRV::StorageClass::StorageClass SClass = SPIRV::StorageClass::Function); 589 SPIRVType *getOrCreateSPIRVPointerType( 590 SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &TII, 591 SPIRV::StorageClass::StorageClass SClass = SPIRV::StorageClass::Function); 592 593 SPIRVType * 594 getOrCreateOpTypeImage(MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, 595 SPIRV::Dim::Dim Dim, uint32_t Depth, uint32_t Arrayed, 596 uint32_t Multisampled, uint32_t Sampled, 597 SPIRV::ImageFormat::ImageFormat ImageFormat, 598 SPIRV::AccessQualifier::AccessQualifier AccQual); 599 600 SPIRVType *getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder); 601 602 SPIRVType *getOrCreateOpTypeSampledImage(SPIRVType *ImageType, 603 MachineIRBuilder &MIRBuilder); 604 SPIRVType *getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, 605 const TargetExtType *ExtensionType, 606 const SPIRVType *ElemType, 607 uint32_t Scope, uint32_t Rows, 608 uint32_t Columns, uint32_t Use); 609 SPIRVType * 610 getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, 611 SPIRV::AccessQualifier::AccessQualifier AccQual); 612 SPIRVType *getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder); 613 SPIRVType *getOrCreateOpTypeFunctionWithArgs( 614 const Type *Ty, SPIRVType *RetType, 615 const SmallVectorImpl<SPIRVType *> &ArgTypes, 616 MachineIRBuilder &MIRBuilder); 617 SPIRVType *getOrCreateOpTypeByOpcode(const Type *Ty, 618 MachineIRBuilder &MIRBuilder, 619 unsigned Opcode); 620 621 const TargetRegisterClass *getRegClass(SPIRVType *SpvType) const; 622 LLT getRegType(SPIRVType *SpvType) const; 623 }; 624 } // end namespace llvm 625 #endif // LLLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H 626