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