LLVM 22.0.0git
SPIRVGlobalRegistry.h
Go to the documentation of this file.
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
20#include "SPIRVIRMapping.h"
21#include "SPIRVInstrInfo.h"
23#include "llvm/IR/Constant.h"
25
26namespace llvm {
27class SPIRVSubtarget;
28using SPIRVType = const MachineInstr;
29using StructOffsetDecorator = std::function<void(Register)>;
30
32 // Registers holding values which have types associated with them.
33 // Initialized upon VReg definition in IRTranslator.
34 // Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
35 // where Reg = OpType...
36 // while VRegToTypeMap tracks SPIR-V type assigned to other regs (i.e. not
37 // type-declaring ones).
39 VRegToTypeMap;
40
42
43 // map a Function to its definition (as a machine instruction operand)
46 // map function pointer (as a machine instruction operand) to the used
47 // Function
49 // Maps Functions to their calls (in a form of the machine instruction,
50 // OpFunctionCall) that happened before the definition is available
52 // map a Function to its original return type before the clone function was
53 // created during substitution of aggregate arguments
54 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`)
55 DenseMap<Value *, Type *> MutatedAggRet;
56 // map an instruction to its value's attributes (type, name)
58
59 SmallPtrSet<const Type *, 4> TypesInProcessing;
60 DenseMap<const Type *, SPIRVType *> ForwardPointerTypes;
61
62 // Stores for each function the last inserted SPIR-V Type.
63 // See: SPIRVGlobalRegistry::createOpType.
65
66 // if a function returns a pointer, this is to map it into TypedPointerType
68
69 // Number of bits pointers and size_t integers require.
70 const unsigned PointerSize;
71
72 // Holds the maximum ID we have in the module.
73 unsigned Bound;
74
75 // Maps values associated with untyped pointers into deduced element types of
76 // untyped pointers.
77 DenseMap<Value *, Type *> DeducedElTys;
78 // Maps composite values to deduced types where untyped pointers are replaced
79 // with typed ones.
80 DenseMap<Value *, Type *> DeducedNestedTys;
81 // Maps values to "assign type" calls, thus being a registry of created
82 // Intrinsic::spv_assign_ptr_type instructions.
83 DenseMap<Value *, CallInst *> AssignPtrTypeInstr;
84
85 // Maps OpVariable and OpFunction-related v-regs to its LLVM IR definition.
87
88 // map of aliasing decorations to aliasing metadata
89 std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
90
91 // Add a new OpTypeXXX instruction without checking for duplicates.
92 SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
93 SPIRV::AccessQualifier::AccessQualifier AQ,
94 bool ExplicitLayoutRequired, bool EmitIR);
95 SPIRVType *findSPIRVType(const Type *Ty, MachineIRBuilder &MIRBuilder,
96 SPIRV::AccessQualifier::AccessQualifier accessQual,
97 bool ExplicitLayoutRequired, bool EmitIR);
98 SPIRVType *
99 restOfCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
100 SPIRV::AccessQualifier::AccessQualifier AccessQual,
101 bool ExplicitLayoutRequired, bool EmitIR);
102
103 // Internal function creating the an OpType at the correct position in the
104 // function by tweaking the passed "MIRBuilder" insertion point and restoring
105 // it to the correct position. "Op" should be the function creating the
106 // specific OpType you need, and should return the newly created instruction.
107 SPIRVType *createOpType(MachineIRBuilder &MIRBuilder,
108 std::function<MachineInstr *(MachineIRBuilder &)> Op);
109
110public:
111 SPIRVGlobalRegistry(unsigned PointerSize);
112
114
115 void setBound(unsigned V) { Bound = V; }
116 unsigned getBound() { return Bound; }
117
118 void addGlobalObject(const Value *V, const MachineFunction *MF, Register R) {
119 Reg2GO[std::make_pair(MF, R)] = V;
120 }
122 auto It = Reg2GO.find(std::make_pair(MF, R));
123 return It == Reg2GO.end() ? nullptr : It->second;
124 }
125
126 // Add a record to the map of function return pointer types.
127 void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy) {
128 FunResPointerTypes[ArgF] = DerivedTy;
129 }
130 // Find a record in the map of function return pointer types.
132 auto It = FunResPointerTypes.find(ArgF);
133 return It == FunResPointerTypes.end() ? nullptr : It->second;
134 }
135
136 // A registry of "assign type" records:
137 // - Add a record.
138 void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI) {
139 AssignPtrTypeInstr[Val] = AssignPtrTyCI;
140 }
141 // - Find a record.
143 auto It = AssignPtrTypeInstr.find(Val);
144 return It == AssignPtrTypeInstr.end() ? nullptr : It->second;
145 }
146 // - Find a record and update its key or add a new record, if found.
148 bool DeleteOld) {
149 if (CallInst *CI = findAssignPtrTypeInstr(OldVal)) {
150 if (DeleteOld)
151 AssignPtrTypeInstr.erase(OldVal);
152 AssignPtrTypeInstr[NewVal] = CI;
153 }
154 }
155
156 // A registry of mutated values
157 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`):
158 // - Add a record.
159 void addMutated(Value *Val, Type *Ty) { MutatedAggRet[Val] = Ty; }
160 // - Find a record.
161 Type *findMutated(const Value *Val) {
162 auto It = MutatedAggRet.find(Val);
163 return It == MutatedAggRet.end() ? nullptr : It->second;
164 }
165
166 // A registry of value's attributes (type, name)
167 // - Add a record.
168 void addValueAttrs(MachineInstr *Key, std::pair<Type *, std::string> Val) {
169 ValueAttrs[Key] = Val;
170 }
171 // - Find a record.
172 bool findValueAttrs(const MachineInstr *Key, Type *&Ty, StringRef &Name) {
173 auto It = ValueAttrs.find(Key);
174 if (It == ValueAttrs.end())
175 return false;
176 Ty = It->second.first;
177 Name = It->second.second;
178 return true;
179 }
180
181 // Deduced element types of untyped pointers and composites:
182 // - Add a record to the map of deduced element types.
183 void addDeducedElementType(Value *Val, Type *Ty) { DeducedElTys[Val] = Ty; }
184 // - Find a record in the map of deduced element types.
186 auto It = DeducedElTys.find(Val);
187 return It == DeducedElTys.end() ? nullptr : It->second;
188 }
189 // - Find a record and update its key or add a new record, if found.
191 bool DeleteOld) {
192 if (Type *Ty = findDeducedElementType(OldVal)) {
193 if (DeleteOld)
194 DeducedElTys.erase(OldVal);
195 DeducedElTys[NewVal] = Ty;
196 }
197 }
198 // - Add a record to the map of deduced composite types.
200 DeducedNestedTys[Val] = Ty;
201 }
202 // - Find a record in the map of deduced composite types.
204 auto It = DeducedNestedTys.find(Val);
205 return It == DeducedNestedTys.end() ? nullptr : It->second;
206 }
207 // - Find a type of the given Global value
209 // we may know element type if it was deduced earlier
210 Type *ElementTy = findDeducedElementType(Global);
211 if (!ElementTy) {
212 // or we may know element type if it's associated with a composite
213 // value
214 if (Value *GlobalElem =
215 Global->getNumOperands() > 0 ? Global->getOperand(0) : nullptr)
216 ElementTy = findDeducedCompositeType(GlobalElem);
217 else if (const Function *Fn = dyn_cast<Function>(Global))
218 ElementTy = SPIRV::getOriginalFunctionType(*Fn);
219 }
220 return ElementTy ? ElementTy : Global->getValueType();
221 }
222
223 // Map a machine operand that represents a use of a function via function
224 // pointer to a machine operand that represents the function definition.
225 // Return either the register or invalid value, because we have no context for
226 // a good diagnostic message in case of unexpectedly missing references.
228 auto ResF = InstrToFunction.find(Use);
229 if (ResF == InstrToFunction.end())
230 return nullptr;
231 auto ResReg = FunctionToInstr.find(ResF->second);
232 return ResReg == FunctionToInstr.end() ? nullptr : ResReg->second;
233 }
234
235 // Map a Function to a machine instruction that represents the function
236 // definition.
238 if (!F)
239 return nullptr;
240 auto MOIt = FunctionToInstr.find(F);
241 return MOIt == FunctionToInstr.end() ? nullptr : MOIt->second->getParent();
242 }
243
244 // Map a Function to a machine instruction that represents the function
245 // definition.
247 if (!MI)
248 return nullptr;
249 auto FIt = FunctionToInstrRev.find(MI);
250 return FIt == FunctionToInstrRev.end() ? nullptr : FIt->second;
251 }
252
253 // map function pointer (as a machine instruction operand) to the used
254 // Function
256 InstrToFunction[MO] = F;
257 }
258
259 // map a Function to its definition (as a machine instruction)
261 FunctionToInstr[F] = MO;
262 FunctionToInstrRev[MO->getParent()] = F;
263 }
264
265 // Return true if any OpConstantFunctionPointerINTEL were generated
266 bool hasConstFunPtr() { return !InstrToFunction.empty(); }
267
268 // Add a record about forward function call.
270 ForwardCalls[F].insert(MI);
271 }
272
273 // Map a Function to the vector of machine instructions that represents
274 // forward function calls or to nullptr if not found.
276 auto It = ForwardCalls.find(F);
277 return It == ForwardCalls.end() ? nullptr : &It->second;
278 }
279
280 // Get or create a SPIR-V type corresponding the given LLVM IR type,
281 // and map it to the given VReg.
283 MachineIRBuilder &MIRBuilder,
284 SPIRV::AccessQualifier::AccessQualifier AQ,
285 bool EmitIR);
290 SPIRVType *assignVectTypeToVReg(SPIRVType *BaseType, unsigned NumElements,
291 Register VReg, MachineInstr &I,
292 const SPIRVInstrInfo &TII);
293
294 // In cases where the SPIR-V type is already known, this function can be
295 // used to map it to the given VReg.
297 const MachineFunction &MF);
298
299 // Either generate a new OpTypeXXX instruction or return an existing one
300 // corresponding to the given LLVM IR type.
301 // EmitIR controls if we emit GMIR or SPV constants (e.g. for array sizes)
302 // because this method may be called from InstructionSelector and we don't
303 // want to emit extra IR instructions there.
305 SPIRV::AccessQualifier::AccessQualifier AQ,
306 bool EmitIR) {
307 MachineIRBuilder MIRBuilder(I);
308 return getOrCreateSPIRVType(Type, MIRBuilder, AQ, EmitIR);
309 }
310
312 MachineIRBuilder &MIRBuilder,
313 SPIRV::AccessQualifier::AccessQualifier AQ,
314 bool EmitIR) {
315 return getOrCreateSPIRVType(Type, MIRBuilder, AQ, false, EmitIR);
316 }
317
318 const Type *getTypeForSPIRVType(const SPIRVType *Ty) const {
319 auto Res = SPIRVToLLVMType.find(Ty);
320 assert(Res != SPIRVToLLVMType.end());
321 return Res->second;
322 }
323
324 // Return a pointee's type, or nullptr otherwise.
326 // Return a pointee's type op code, or 0 otherwise.
327 unsigned getPointeeTypeOp(Register PtrReg);
328
329 // Either generate a new OpTypeXXX instruction or return an existing one
330 // corresponding to the given string containing the name of the builtin type.
331 // Return nullptr if unable to recognize SPIRV type name from `TypeStr`.
333 StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR,
334 SPIRV::StorageClass::StorageClass SC = SPIRV::StorageClass::Function,
335 SPIRV::AccessQualifier::AccessQualifier AQ =
336 SPIRV::AccessQualifier::ReadWrite);
337
338 // Return the SPIR-V type instruction corresponding to the given VReg, or
339 // nullptr if no such type instruction exists. The second argument MF
340 // allows to search for the association in a context of the machine functions
341 // than the current one, without switching between different "current" machine
342 // functions.
344 const MachineFunction *MF = nullptr) const;
345
346 // Return the result type of the instruction defining the register.
347 SPIRVType *getResultType(Register VReg, MachineFunction *MF = nullptr);
348
349 // Whether the given VReg has a SPIR-V type mapped to it yet.
350 bool hasSPIRVTypeForVReg(Register VReg) const {
351 return getSPIRVTypeForVReg(VReg) != nullptr;
352 }
353
354 // Return the VReg holding the result of the given OpTypeXXX instruction.
355 Register getSPIRVTypeID(const SPIRVType *SpirvType) const;
356
357 // Return previous value of the current machine function
359 MachineFunction *Ret = CurMF;
360 CurMF = &MF;
361 return Ret;
362 }
363
364 // Return true if the type is an aggregate type.
366 return Type && (Type->getOpcode() == SPIRV::OpTypeStruct &&
367 Type->getOpcode() == SPIRV::OpTypeArray);
368 }
369
370 // Whether the given VReg has an OpTypeXXX instruction mapped to it with the
371 // given opcode (e.g. OpTypeFloat).
372 bool isScalarOfType(Register VReg, unsigned TypeOpcode) const;
373
374 // Return true if the given VReg's assigned SPIR-V type is either a scalar
375 // matching the given opcode, or a vector with an element type matching that
376 // opcode (e.g. OpTypeBool, or OpTypeVector %x 4, where %x is OpTypeBool).
377 bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const;
378
379 // Returns true if `Type` is a resource type. This could be an image type
380 // or a struct for a buffer decorated with the block decoration.
381 bool isResourceType(SPIRVType *Type) const;
382
383 // Return number of elements in a vector if the argument is associated with
384 // a vector type. Return 1 for a scalar type, and 0 for a missing type.
385 unsigned getScalarOrVectorComponentCount(Register VReg) const;
387
388 // Return the component type in a vector if the argument is associated with
389 // a vector type. Returns the argument itself for other types, and nullptr
390 // for a missing type.
393
394 // For vectors or scalars of booleans, integers and floats, return the scalar
395 // type's bitwidth. Otherwise calls llvm_unreachable().
396 unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const;
397
398 // For vectors or scalars of integers and floats, return total bitwidth of the
399 // argument. Otherwise returns 0.
400 unsigned getNumScalarOrVectorTotalBitWidth(const SPIRVType *Type) const;
401
402 // Returns either pointer to integer type, that may be a type of vector
403 // elements or an original type, or nullptr if the argument is niether
404 // an integer scalar, nor an integer vector
406
407 // For integer vectors or scalars, return whether the integers are signed.
408 bool isScalarOrVectorSigned(const SPIRVType *Type) const;
409
410 // Gets the storage class of the pointer type assigned to this vreg.
411 SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const;
412 SPIRV::StorageClass::StorageClass
414
415 // Return the number of bits SPIR-V pointers and size_t variables require.
416 unsigned getPointerSize() const { return PointerSize; }
417
418 // Returns true if two types are defined and are compatible in a sense of
419 // OpBitcast instruction
420 bool isBitcastCompatible(const SPIRVType *Type1,
421 const SPIRVType *Type2) const;
422
423 // Informs about removal of the machine instruction and invalidates data
424 // structures referring this instruction.
426
427private:
428 SPIRVType *getOpTypeBool(MachineIRBuilder &MIRBuilder);
429
430 const Type *adjustIntTypeByWidth(const Type *Ty) const;
431 unsigned adjustOpTypeIntWidth(unsigned Width) const;
432
434 MachineIRBuilder &MIRBuilder,
435 SPIRV::AccessQualifier::AccessQualifier AQ,
436 bool ExplicitLayoutRequired, bool EmitIR);
437
438 SPIRVType *getOpTypeInt(unsigned Width, MachineIRBuilder &MIRBuilder,
439 bool IsSigned = false);
440
441 SPIRVType *getOpTypeFloat(uint32_t Width, MachineIRBuilder &MIRBuilder);
442
443 SPIRVType *getOpTypeFloat(uint32_t Width, MachineIRBuilder &MIRBuilder,
444 SPIRV::FPEncoding::FPEncoding FPEncode);
445
446 SPIRVType *getOpTypeVoid(MachineIRBuilder &MIRBuilder);
447
448 SPIRVType *getOpTypeVector(uint32_t NumElems, SPIRVType *ElemType,
449 MachineIRBuilder &MIRBuilder);
450
451 SPIRVType *getOpTypeArray(uint32_t NumElems, SPIRVType *ElemType,
452 MachineIRBuilder &MIRBuilder,
453 bool ExplicitLayoutRequired, bool EmitIR);
454
455 SPIRVType *getOpTypeOpaque(const StructType *Ty,
456 MachineIRBuilder &MIRBuilder);
457
458 SPIRVType *getOpTypeStruct(const StructType *Ty, MachineIRBuilder &MIRBuilder,
459 SPIRV::AccessQualifier::AccessQualifier AccQual,
460 StructOffsetDecorator Decorator, bool EmitIR);
461
462 SPIRVType *getOpTypePointer(SPIRV::StorageClass::StorageClass SC,
463 SPIRVType *ElemType, MachineIRBuilder &MIRBuilder,
464 Register Reg);
465
466 SPIRVType *getOpTypeForwardPointer(SPIRV::StorageClass::StorageClass SC,
467 MachineIRBuilder &MIRBuilder);
468
469 SPIRVType *getOpTypeFunction(const FunctionType *Ty, SPIRVType *RetType,
470 const SmallVectorImpl<SPIRVType *> &ArgTypes,
471 MachineIRBuilder &MIRBuilder);
472
473 SPIRVType *
474 getOrCreateSpecialType(const Type *Ty, MachineIRBuilder &MIRBuilder,
475 SPIRV::AccessQualifier::AccessQualifier AccQual);
476
477 SPIRVType *finishCreatingSPIRVType(const Type *LLVMTy, SPIRVType *SpirvType);
478 Register getOrCreateBaseRegister(Constant *Val, MachineInstr &I,
479 SPIRVType *SpvType,
480 const SPIRVInstrInfo &TII, unsigned BitWidth,
481 bool ZeroAsNull);
482 Register getOrCreateCompositeOrNull(Constant *Val, MachineInstr &I,
483 SPIRVType *SpvType,
484 const SPIRVInstrInfo &TII, Constant *CA,
485 unsigned BitWidth, unsigned ElemCnt,
486 bool ZeroAsNull = true);
487
488 Register getOrCreateIntCompositeOrNull(uint64_t Val,
489 MachineIRBuilder &MIRBuilder,
490 SPIRVType *SpvType, bool EmitIR,
491 Constant *CA, unsigned BitWidth,
492 unsigned ElemCnt);
493
494 // Returns a pointer to a SPIR-V pointer type with the given base type and
495 // storage class. It is the responsibility of the caller to make sure the
496 // decorations on the base type are valid for the given storage class. For
497 // example, it has the correct offset and stride decorations.
498 SPIRVType *
499 getOrCreateSPIRVPointerTypeInternal(SPIRVType *BaseType,
500 MachineIRBuilder &MIRBuilder,
501 SPIRV::StorageClass::StorageClass SC);
502
503 void addStructOffsetDecorations(Register Reg, StructType *Ty,
504 MachineIRBuilder &MIRBuilder);
505 void addArrayStrideDecorations(Register Reg, Type *ElementType,
506 MachineIRBuilder &MIRBuilder);
507 bool hasBlockDecoration(SPIRVType *Type) const;
508
509 SPIRVType *
510 getOrCreateOpTypeImage(MachineIRBuilder &MIRBuilder, SPIRVType *SampledType,
511 SPIRV::Dim::Dim Dim, uint32_t Depth, uint32_t Arrayed,
512 uint32_t Multisampled, uint32_t Sampled,
513 SPIRV::ImageFormat::ImageFormat ImageFormat,
514 SPIRV::AccessQualifier::AccessQualifier AccQual);
515
516public:
518 SPIRVType *SpvType, bool EmitIR,
519 bool ZeroAsNull = true);
521 SPIRVType *SpvType, const SPIRVInstrInfo &TII,
522 bool ZeroAsNull = true);
524 SPIRVType *SpvType, const SPIRVInstrInfo &TII,
525 bool ZeroAsNull);
527 const SPIRVInstrInfo &TII,
528 bool ZeroAsNull = true);
530 SPIRVType *SpvType, const SPIRVInstrInfo &TII,
531 bool ZeroAsNull);
533 SPIRVType *SpvType = nullptr);
534
536 SPIRVType *SpvType, const SPIRVInstrInfo &TII,
537 bool ZeroAsNull = true);
539 SPIRVType *SpvType, const SPIRVInstrInfo &TII,
540 bool ZeroAsNull = true);
542 SPIRVType *SpvType,
543 const SPIRVInstrInfo &TII);
545 SPIRVType *SpvType, bool EmitIR);
547 SPIRVType *SpvType);
548 Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param,
549 unsigned FilerMode,
550 MachineIRBuilder &MIRBuilder);
552 const SPIRVInstrInfo &TII);
555 SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init,
556 bool IsConst,
557 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
558 MachineIRBuilder &MIRBuilder, bool IsInstSelector);
561 StringRef Name,
562 MachineIRBuilder &MIRBuilder);
563
564 // Convenient helpers for getting types with check for duplicates.
566 MachineIRBuilder &MIRBuilder);
568 const SPIRVInstrInfo &TII);
570 const SPIRVInstrInfo &TII,
571 unsigned SPIRVOPcode, Type *LLVMTy);
573 const SPIRVInstrInfo &TII);
575 bool EmitIR);
577 const SPIRVInstrInfo &TII);
579 unsigned NumElements,
580 MachineIRBuilder &MIRBuilder,
581 bool EmitIR);
583 unsigned NumElements, MachineInstr &I,
584 const SPIRVInstrInfo &TII);
585
586 // Returns a pointer to a SPIR-V pointer type with the given base type and
587 // storage class. The base type will be translated to a SPIR-V type, and the
588 // appropriate layout decorations will be added to the base type.
590 MachineIRBuilder &MIRBuilder,
591 SPIRV::StorageClass::StorageClass SC);
593 SPIRV::StorageClass::StorageClass SC);
594
595 // Returns a pointer to a SPIR-V pointer type with the given base type and
596 // storage class. It is the responsibility of the caller to make sure the
597 // decorations on the base type are valid for the given storage class. For
598 // example, it has the correct offset and stride decorations.
600 MachineIRBuilder &MIRBuilder,
601 SPIRV::StorageClass::StorageClass SC);
602
603 // Returns a pointer to a SPIR-V pointer type that is the same as `PtrType`
604 // except the stroage class has been changed to `SC`. It is the responsibility
605 // of the caller to be sure that the original and new storage class have the
606 // same layout requirements.
608 SPIRV::StorageClass::StorageClass SC,
609 MachineInstr &I);
610
612 Type *ElemType,
613 SPIRV::StorageClass::StorageClass SC,
614 bool IsWritable, bool EmitIr = false);
615
617
619 const TargetExtType *T, bool EmitIr = false);
620
621 SPIRVType *
622 getImageType(const TargetExtType *ExtensionType,
623 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
624 MachineIRBuilder &MIRBuilder);
625
627
629 MachineIRBuilder &MIRBuilder);
631 const TargetExtType *ExtensionType,
632 const SPIRVType *ElemType,
633 uint32_t Scope, uint32_t Rows,
634 uint32_t Columns, uint32_t Use,
635 bool EmitIR);
636 SPIRVType *
638 SPIRV::AccessQualifier::AccessQualifier AccQual);
641 const Type *Ty, SPIRVType *RetType,
642 const SmallVectorImpl<SPIRVType *> &ArgTypes,
643 MachineIRBuilder &MIRBuilder);
645 MachineIRBuilder &MIRBuilder,
646 unsigned Opcode);
647
649 MachineIRBuilder &MIRBuilder,
650 unsigned Opcode,
651 const ArrayRef<MCOperand> Operands);
652
653 const TargetRegisterClass *getRegClass(SPIRVType *SpvType) const;
654 LLT getRegType(SPIRVType *SpvType) const;
655
657 const MDNode *AliasingListMD);
659 uint32_t Dec, const MDNode *GVarMD);
660 // Replace all uses of a |Old| with |New| updates the global registry type
661 // mappings.
662 void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld = true);
663
664 void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg);
665 void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg);
666 void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType);
667};
668} // end namespace llvm
669#endif // LLLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Resource Implicit Binding
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineIRBuilder class.
Register Reg
#define T
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:282
This is the shared class of boolean and integer constants.
Definition Constants.h:87
This is an important base class in LLVM.
Definition Constant.h:43
Class to represent function types.
iterator end()
Definition Function.h:853
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2788
Metadata node.
Definition Metadata.h:1078
Helper class to build MachineInstr.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
SPIRVType * getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AccQual)
void recordFunctionDefinition(const Function *F, const MachineOperand *MO)
unsigned getNumScalarOrVectorTotalBitWidth(const SPIRVType *Type) const
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
const TypedPointerType * findReturnType(const Function *ArgF)
void addForwardCall(const Function *F, MachineInstr *MI)
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
SPIRVType * getResultType(Register VReg, MachineFunction *MF=nullptr)
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
SPIRVType * getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder, bool EmitIR)
const Value * getGlobalObject(const MachineFunction *MF, Register R)
void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg)
SPIRVType * getOrCreatePaddingType(MachineIRBuilder &MIRBuilder)
SPIRVType * assignFloatTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
MachineInstr * getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * assignVectTypeToVReg(SPIRVType *BaseType, unsigned NumElements, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init, bool IsConst, const std::optional< SPIRV::LinkageType::LinkageType > &LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
Type * findDeducedCompositeType(const Value *Val)
void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld=true)
SPIRVType * changePointerStorageClass(SPIRVType *PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
SPIRVType * getOrCreateUnknownType(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode, const ArrayRef< MCOperand > Operands)
bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const
unsigned getScalarOrVectorComponentCount(Register VReg) const
Register createConstInt(const ConstantInt *CI, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
SPIRVType * getOrCreateSPIRVFloatType(unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII)
bool isScalarOrVectorSigned(const SPIRVType *Type) const
void addDeducedElementType(Value *Val, Type *Ty)
SPIRVGlobalRegistry(unsigned PointerSize)
Register getOrCreateGlobalVariableWithBinding(const SPIRVType *VarType, uint32_t Set, uint32_t Binding, StringRef Name, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
SPIRVType * getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
const MachineInstr * getFunctionDefinition(const Function *F)
void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy)
const MachineOperand * getFunctionDefinitionByUse(const MachineOperand *Use)
SPIRVType * getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr)
SPIRVType * getPointeeType(SPIRVType *PtrType)
void invalidateMachineInstr(MachineInstr *MI)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
void addMutated(Value *Val, Type *Ty)
Register createConstFP(const ConstantFP *CF, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
void updateIfExistDeducedElementType(Value *OldVal, Value *NewVal, bool DeleteOld)
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
SPIRVType * assignIntTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
bool findValueAttrs(const MachineInstr *Key, Type *&Ty, StringRef &Name)
unsigned getPointeeTypeOp(Register PtrReg)
SPIRVType * getOrCreateOpTypeSampledImage(SPIRVType *ImageType, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateVulkanBufferType(MachineIRBuilder &MIRBuilder, Type *ElemType, SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr=false)
SPIRVType * getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
Type * findMutated(const Value *Val)
SPIRVType * getOrCreateLayoutType(MachineIRBuilder &MIRBuilder, const TargetExtType *T, bool EmitIr=false)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
SPIRVType * getScalarOrVectorComponentType(Register VReg) const
bool hasSPIRVTypeForVReg(Register VReg) const
void addDeducedCompositeType(Value *Val, Type *Ty)
SPIRVType * getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVType *RetType, const SmallVectorImpl< SPIRVType * > &ArgTypes, MachineIRBuilder &MIRBuilder)
void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg)
void recordFunctionPointer(const MachineOperand *MO, const Function *F)
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR)
SmallPtrSet< MachineInstr *, 8 > * getForwardCalls(const Function *F)
bool isAggregateType(SPIRVType *Type) const
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
void updateIfExistAssignPtrTypeInstr(Value *OldVal, Value *NewVal, bool DeleteOld)
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
SPIRVType * getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType, const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns, uint32_t Use, bool EmitIR)
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
MachineFunction * setCurrentFunc(MachineFunction &MF)
Register getOrCreateConstVector(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
SPIRVType * getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
SPIRVType * getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
bool isResourceType(SPIRVType *Type) const
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR, bool ZeroAsNull=true)
Type * getDeducedGlobalValueType(const GlobalValue *Global)
SPIRVType * assignTypeToVReg(const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
LLT getRegType(SPIRVType *SpvType) const
void addValueAttrs(MachineInstr *Key, std::pair< Type *, std::string > Val)
const Function * getFunctionByDefinition(const MachineInstr *MI)
void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec, const MDNode *GVarMD)
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
SPIRVType * getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
Type * findDeducedElementType(const Value *Val)
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder)
void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType)
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
CallInst * findAssignPtrTypeInstr(const Value *Val)
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, SPIRVType *SpvType)
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
const SPIRVType * retrieveScalarOrVectorIntType(const SPIRVType *Type) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Class to represent struct types.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
A few GPU targets, such as DXIL and SPIR-V, have typed pointers.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
FunctionType * getOriginalFunctionType(const Function &F)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
const MachineInstr SPIRVType
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
std::function< void(Register)> StructOffsetDecorator
@ Global
Append to llvm.global_dtors.
DWARFExpression::Operation Op
constexpr unsigned BitWidth