1 //===-- SPIRVGlobalRegistry.h - SPIR-V Global Registry ----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
17 #define LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
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"
28 using SPIRVType
= const MachineInstr
;
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
*>>
40 // Map LLVM Type* to <MF, Reg>
41 SPIRVGeneralDuplicatesTracker DT
;
43 DenseMap
<SPIRVType
*, const Type
*> SPIRVToLLVMType
;
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
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
;
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
);
64 SmallPtrSet
<const Type
*, 4> TypesInProcessing
;
65 DenseMap
<const Type
*, SPIRVType
*> ForwardPointerTypes
;
67 // if a function returns a pointer, this is to map it into TypedPointerType
68 DenseMap
<const Function
*, TypedPointerType
*> FunResPointerTypes
;
70 // Number of bits pointers and size_t integers require.
71 const unsigned PointerSize
;
73 // Holds the maximum ID we have in the module.
76 // Maps values associated with untyped pointers into deduced element types of
78 DenseMap
<Value
*, Type
*> DeducedElTys
;
79 // Maps composite values to deduced types where untyped pointers are replaced
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
;
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
,
91 SPIRVType
*findSPIRVType(const Type
*Ty
, MachineIRBuilder
&MIRBuilder
,
92 SPIRV::AccessQualifier::AccessQualifier accessQual
=
93 SPIRV::AccessQualifier::ReadWrite
,
96 restOfCreateSPIRVType(const Type
*Type
, MachineIRBuilder
&MIRBuilder
,
97 SPIRV::AccessQualifier::AccessQualifier AccessQual
,
101 SPIRVGlobalRegistry(unsigned PointerSize
);
103 MachineFunction
*CurMF
;
105 void add(const Constant
*C
, MachineFunction
*MF
, Register R
) {
109 void add(const GlobalVariable
*GV
, MachineFunction
*MF
, Register R
) {
113 void add(const Function
*F
, MachineFunction
*MF
, Register R
) {
117 void add(const Argument
*Arg
, MachineFunction
*MF
, Register R
) {
121 void add(const MachineInstr
*MI
, MachineFunction
*MF
, Register R
) {
125 Register
find(const MachineInstr
*MI
, MachineFunction
*MF
) {
126 return DT
.find(MI
, MF
);
129 Register
find(const Constant
*C
, MachineFunction
*MF
) {
130 return DT
.find(C
, MF
);
133 Register
find(const GlobalVariable
*GV
, MachineFunction
*MF
) {
134 return DT
.find(GV
, MF
);
137 Register
find(const Function
*F
, MachineFunction
*MF
) {
138 return DT
.find(F
, MF
);
141 void buildDepsGraph(std::vector
<SPIRV::DTSortableEntry
*> &Graph
,
142 MachineModuleInfo
*MMI
= nullptr) {
143 DT
.buildDepsGraph(Graph
, MMI
);
146 void setBound(unsigned V
) { Bound
= V
; }
147 unsigned getBound() { return Bound
; }
149 // Add a record to the map of function return pointer types.
150 void addReturnType(const Function
*ArgF
, TypedPointerType
*DerivedTy
) {
151 FunResPointerTypes
[ArgF
] = DerivedTy
;
153 // Find a record in the map of function return pointer types.
154 const TypedPointerType
*findReturnType(const Function
*ArgF
) {
155 auto It
= FunResPointerTypes
.find(ArgF
);
156 return It
== FunResPointerTypes
.end() ? nullptr : It
->second
;
159 // A registry of "assign type" records:
161 void addAssignPtrTypeInstr(Value
*Val
, CallInst
*AssignPtrTyCI
) {
162 AssignPtrTypeInstr
[Val
] = AssignPtrTyCI
;
165 CallInst
*findAssignPtrTypeInstr(const Value
*Val
) {
166 auto It
= AssignPtrTypeInstr
.find(Val
);
167 return It
== AssignPtrTypeInstr
.end() ? nullptr : It
->second
;
170 // A registry of mutated values
171 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`):
173 void addMutated(Value
*Val
, Type
*Ty
) { MutatedAggRet
[Val
] = Ty
; }
175 Type
*findMutated(const Value
*Val
) {
176 auto It
= MutatedAggRet
.find(Val
);
177 return It
== MutatedAggRet
.end() ? nullptr : It
->second
;
180 // Deduced element types of untyped pointers and composites:
181 // - Add a record to the map of deduced element types.
182 void addDeducedElementType(Value
*Val
, Type
*Ty
) { DeducedElTys
[Val
] = Ty
; }
183 // - Find a record in the map of deduced element types.
184 Type
*findDeducedElementType(const Value
*Val
) {
185 auto It
= DeducedElTys
.find(Val
);
186 return It
== DeducedElTys
.end() ? nullptr : It
->second
;
188 // - Add a record to the map of deduced composite types.
189 void addDeducedCompositeType(Value
*Val
, Type
*Ty
) {
190 DeducedNestedTys
[Val
] = Ty
;
192 // - Find a record in the map of deduced composite types.
193 Type
*findDeducedCompositeType(const Value
*Val
) {
194 auto It
= DeducedNestedTys
.find(Val
);
195 return It
== DeducedNestedTys
.end() ? nullptr : It
->second
;
197 // - Find a type of the given Global value
198 Type
*getDeducedGlobalValueType(const GlobalValue
*Global
) {
199 // we may know element type if it was deduced earlier
200 Type
*ElementTy
= findDeducedElementType(Global
);
202 // or we may know element type if it's associated with a composite
204 if (Value
*GlobalElem
=
205 Global
->getNumOperands() > 0 ? Global
->getOperand(0) : nullptr)
206 ElementTy
= findDeducedCompositeType(GlobalElem
);
208 return ElementTy
? ElementTy
: Global
->getValueType();
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.
215 const MachineOperand
*getFunctionDefinitionByUse(const MachineOperand
*Use
) {
216 auto ResF
= InstrToFunction
.find(Use
);
217 if (ResF
== InstrToFunction
.end())
219 auto ResReg
= FunctionToInstr
.find(ResF
->second
);
220 return ResReg
== FunctionToInstr
.end() ? nullptr : ResReg
->second
;
223 // Map a Function to a machine instruction that represents the function
225 const MachineInstr
*getFunctionDefinition(const Function
*F
) {
228 auto MOIt
= FunctionToInstr
.find(F
);
229 return MOIt
== FunctionToInstr
.end() ? nullptr : MOIt
->second
->getParent();
232 // Map a Function to a machine instruction that represents the function
234 const Function
*getFunctionByDefinition(const MachineInstr
*MI
) {
237 auto FIt
= FunctionToInstrRev
.find(MI
);
238 return FIt
== FunctionToInstrRev
.end() ? nullptr : FIt
->second
;
241 // map function pointer (as a machine instruction operand) to the used
243 void recordFunctionPointer(const MachineOperand
*MO
, const Function
*F
) {
244 InstrToFunction
[MO
] = F
;
247 // map a Function to its definition (as a machine instruction)
248 void recordFunctionDefinition(const Function
*F
, const MachineOperand
*MO
) {
249 FunctionToInstr
[F
] = MO
;
250 FunctionToInstrRev
[MO
->getParent()] = F
;
253 // Return true if any OpConstantFunctionPointerINTEL were generated
254 bool hasConstFunPtr() { return !InstrToFunction
.empty(); }
256 // Add a record about forward function call.
257 void addForwardCall(const Function
*F
, MachineInstr
*MI
) {
258 auto It
= ForwardCalls
.find(F
);
259 if (It
== ForwardCalls
.end())
260 ForwardCalls
[F
] = {MI
};
262 It
->second
.insert(MI
);
265 // Map a Function to the vector of machine instructions that represents
266 // forward function calls or to nullptr if not found.
267 SmallPtrSet
<MachineInstr
*, 8> *getForwardCalls(const Function
*F
) {
268 auto It
= ForwardCalls
.find(F
);
269 return It
== ForwardCalls
.end() ? nullptr : &It
->second
;
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
,
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
);
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
);
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
,
303 const Type
*getTypeForSPIRVType(const SPIRVType
*Ty
) const {
304 auto Res
= SPIRVToLLVMType
.find(Ty
);
305 assert(Res
!= SPIRVToLLVMType
.end());
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
);
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
);
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
328 SPIRVType
*getSPIRVTypeForVReg(Register VReg
,
329 const MachineFunction
*MF
= nullptr) const;
331 // Whether the given VReg has a SPIR-V type mapped to it yet.
332 bool hasSPIRVTypeForVReg(Register VReg
) const {
333 return getSPIRVTypeForVReg(VReg
) != nullptr;
336 // Return the VReg holding the result of the given OpTypeXXX instruction.
337 Register
getSPIRVTypeID(const SPIRVType
*SpirvType
) const;
339 // Return previous value of the current machine function
340 MachineFunction
*setCurrentFunc(MachineFunction
&MF
) {
341 MachineFunction
*Ret
= CurMF
;
346 // Return true if the type is an aggregate type.
347 bool isAggregateType(SPIRVType
*Type
) const {
348 return Type
&& (Type
->getOpcode() == SPIRV::OpTypeStruct
&&
349 Type
->getOpcode() == SPIRV::OpTypeArray
);
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;
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;
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;
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;
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;
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;
379 // For integer vectors or scalars, return whether the integers are signed.
380 bool isScalarOrVectorSigned(const SPIRVType
*Type
) const;
382 // Gets the storage class of the pointer type assigned to this vreg.
383 SPIRV::StorageClass::StorageClass
getPointerStorageClass(Register VReg
) const;
385 // Return the number of bits SPIR-V pointers and size_t variables require.
386 unsigned getPointerSize() const { return PointerSize
; }
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;
394 SPIRVType
*getOpTypeBool(MachineIRBuilder
&MIRBuilder
);
396 const Type
*adjustIntTypeByWidth(const Type
*Ty
) const;
397 unsigned adjustOpTypeIntWidth(unsigned Width
) const;
399 SPIRVType
*getOpTypeInt(unsigned Width
, MachineIRBuilder
&MIRBuilder
,
400 bool IsSigned
= false);
402 SPIRVType
*getOpTypeFloat(uint32_t Width
, MachineIRBuilder
&MIRBuilder
);
404 SPIRVType
*getOpTypeVoid(MachineIRBuilder
&MIRBuilder
);
406 SPIRVType
*getOpTypeVector(uint32_t NumElems
, SPIRVType
*ElemType
,
407 MachineIRBuilder
&MIRBuilder
);
409 SPIRVType
*getOpTypeArray(uint32_t NumElems
, SPIRVType
*ElemType
,
410 MachineIRBuilder
&MIRBuilder
, bool EmitIR
= true);
412 SPIRVType
*getOpTypeOpaque(const StructType
*Ty
,
413 MachineIRBuilder
&MIRBuilder
);
415 SPIRVType
*getOpTypeStruct(const StructType
*Ty
, MachineIRBuilder
&MIRBuilder
,
418 SPIRVType
*getOpTypePointer(SPIRV::StorageClass::StorageClass SC
,
419 SPIRVType
*ElemType
, MachineIRBuilder
&MIRBuilder
,
422 SPIRVType
*getOpTypeForwardPointer(SPIRV::StorageClass::StorageClass SC
,
423 MachineIRBuilder
&MIRBuilder
);
425 SPIRVType
*getOpTypeFunction(SPIRVType
*RetType
,
426 const SmallVectorImpl
<SPIRVType
*> &ArgTypes
,
427 MachineIRBuilder
&MIRBuilder
);
430 getOrCreateSpecialType(const Type
*Ty
, MachineIRBuilder
&MIRBuilder
,
431 SPIRV::AccessQualifier::AccessQualifier AccQual
);
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
,
442 const SPIRVInstrInfo
&TII
,
444 Register
getOrCreateCompositeOrNull(Constant
*Val
, MachineInstr
&I
,
446 const SPIRVInstrInfo
&TII
, Constant
*CA
,
447 unsigned BitWidth
, unsigned ElemCnt
,
448 bool ZeroAsNull
= true);
450 Register
getOrCreateIntCompositeOrNull(uint64_t Val
,
451 MachineIRBuilder
&MIRBuilder
,
452 SPIRVType
*SpvType
, bool EmitIR
,
453 Constant
*CA
, unsigned BitWidth
,
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);
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
,
476 const SPIRVInstrInfo
&TII
);
477 Register
getOrCreateConsIntVector(uint64_t Val
, MachineIRBuilder
&MIRBuilder
,
478 SPIRVType
*SpvType
, bool EmitIR
= true);
479 Register
getOrCreateConstNullPtr(MachineIRBuilder
&MIRBuilder
,
481 Register
buildConstantSampler(Register Res
, unsigned AddrMode
, unsigned Param
,
483 MachineIRBuilder
&MIRBuilder
,
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
,
492 SPIRV::LinkageType::LinkageType LinkageType
,
493 MachineIRBuilder
&MIRBuilder
,
494 bool IsInstSelector
);
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
);
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
);
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
);
533 SPIRVType
*getOrCreateOpTypeSampler(MachineIRBuilder
&MIRBuilder
);
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
);
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
,
554 } // end namespace llvm
555 #endif // LLLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H