LLVM 24.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_SPIRVGLOBALREGISTRY_H
17#define LLVM_LIB_TARGET_SPIRV_SPIRVGLOBALREGISTRY_H
18
20#include "SPIRVIRMapping.h"
21#include "SPIRVInstrInfo.h"
22#include "SPIRVTypeInst.h"
23#include "llvm/ADT/DenseSet.h"
25#include "llvm/IR/Constant.h"
27
28namespace llvm {
29class SPIRVSubtarget;
30
31using StructOffsetDecorator = std::function<void(Register)>;
32
34 // Registers holding values which have types associated with them.
35 // Initialized upon VReg definition in IRTranslator.
36 // Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
37 // where Reg = OpType...
38 // while VRegToTypeMap tracks SPIR-V type assigned to other regs (i.e. not
39 // type-declaring ones).
41 VRegToTypeMap;
42
44
45 // map a Function to its definition (as a machine instruction operand)
48 // map function pointer (as a machine instruction operand) to the used
49 // Function
51 // Maps Functions to their calls (in a form of the machine instruction,
52 // OpFunctionCall) that happened before the definition is available
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)
60
61 SmallPtrSet<const Type *, 4> TypesInProcessing;
62 DenseMap<const Type *, SPIRVTypeInst> ForwardPointerTypes;
63
64 // Struct types decorated with Block, recorded at the point the decoration
65 // is emitted.
66 DenseSet<SPIRVTypeInst> BlockDecoratedTypes;
67
68 // Stores for each function the last inserted SPIR-V Type.
69 // See: SPIRVGlobalRegistry::createOpType.
71
72 // if a function returns a pointer, this is to map it into TypedPointerType
74
75 // Current target's datalayout.
76 DataLayout DL;
77
78 // Holds the maximum ID we have in the module.
79 unsigned Bound;
80
81 // Maps values associated with untyped pointers into deduced element types of
82 // untyped pointers.
83 DenseMap<Value *, Type *> DeducedElTys;
84 // Maps composite values to deduced types where untyped pointers are replaced
85 // with typed ones.
86 DenseMap<Value *, Type *> DeducedNestedTys;
87
88 // Element type for each untyped-pointer register, which
89 // OpTypeUntypedPointerKHR omits but OpUntypedVariableKHR needs as a Data
90 // Type.
92 UntypedPointerElementTypes;
93 // Maps values to "assign type" calls, thus being a registry of created
94 // Intrinsic::spv_assign_ptr_type instructions.
95 DenseMap<Value *, CallInst *> AssignPtrTypeInstr;
96
97 // Maps OpVariable and OpFunction-related v-regs to its LLVM IR definition.
99
100 // map of aliasing decorations to aliasing metadata, keyed per
101 // MachineFunction: the cached instructions define virtual registers, which
102 // are only valid in the function that created them.
104 AliasInstMDMap;
105
106 // Add a new OpTypeXXX instruction without checking for duplicates.
107 SPIRVTypeInst createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
108 SPIRV::AccessQualifier::AccessQualifier AQ,
109 bool ExplicitLayoutRequired, bool EmitIR);
111 findSPIRVType(const Type *Ty, MachineIRBuilder &MIRBuilder,
112 SPIRV::AccessQualifier::AccessQualifier accessQual,
113 bool ExplicitLayoutRequired, bool EmitIR);
115 restOfCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
116 SPIRV::AccessQualifier::AccessQualifier AccessQual,
117 bool ExplicitLayoutRequired, bool EmitIR);
118
119 // Internal function creating the Types/Constants at the correct position
120 // in the function by tweaking the passed "MIRBuilder" insertion point and
121 // restoring it to the correct position. "Op" should be the function creating
122 // the specific operation you need, and should return the newly created
123 // instruction.
124 const MachineInstr *createConstOrTypeAtFunctionEntry(
125 MachineIRBuilder &MIRBuilder,
126 std::function<MachineInstr *(MachineIRBuilder &)> Op);
127
128public:
130
132
133 void setBound(unsigned V) { Bound = V; }
134 unsigned getBound() { return Bound; }
135
136 void addGlobalObject(const Value *V, const MachineFunction *MF, Register R) {
137 Reg2GO[std::make_pair(MF, R)] = V;
138 }
140 auto It = Reg2GO.find(std::make_pair(MF, R));
141 return It == Reg2GO.end() ? nullptr : It->second;
142 }
143
144 // Add a record to the map of function return pointer types.
145 void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy) {
146 FunResPointerTypes[ArgF] = DerivedTy;
147 }
148 // Find a record in the map of function return pointer types.
150 auto It = FunResPointerTypes.find(ArgF);
151 return It == FunResPointerTypes.end() ? nullptr : It->second;
152 }
153
154 // A registry of "assign type" records:
155 // - Add a record.
156 void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI) {
157 AssignPtrTypeInstr[Val] = AssignPtrTyCI;
158 }
159 // - Remove a record.
161 AssignPtrTypeInstr.erase(OldVal);
162 }
163 // - Find a record.
165 auto It = AssignPtrTypeInstr.find(Val);
166 return It == AssignPtrTypeInstr.end() ? nullptr : It->second;
167 }
168 // - Find a record and update its key or add a new record, if found.
170 bool DeleteOld) {
171 if (CallInst *CI = findAssignPtrTypeInstr(OldVal)) {
172 if (DeleteOld)
173 AssignPtrTypeInstr.erase(OldVal);
174 AssignPtrTypeInstr[NewVal] = CI;
175 }
176 }
177
178 // A registry of mutated values
179 // (see `SPIRVPrepareFunctions::removeAggregateTypesFromSignature()`):
180 // - Add a record.
181 void addMutated(Value *Val, Type *Ty) { MutatedAggRet[Val] = Ty; }
182 // - Find a record.
183 Type *findMutated(const Value *Val) {
184 auto It = MutatedAggRet.find(Val);
185 return It == MutatedAggRet.end() ? nullptr : It->second;
186 }
187
188 // A registry of value's attributes (type, name)
189 // - Add a record.
190 void addValueAttrs(MachineInstr *Key, std::pair<Type *, std::string> Val) {
191 ValueAttrs[Key] = Val;
192 }
193 // - Find a record.
194 bool findValueAttrs(const MachineInstr *Key, Type *&Ty, StringRef &Name) {
195 auto It = ValueAttrs.find(Key);
196 if (It == ValueAttrs.end())
197 return false;
198 Ty = It->second.first;
199 Name = It->second.second;
200 return true;
201 }
202
203 // Deduced element types of untyped pointers and composites:
204 // - Add a record to the map of deduced element types.
205 void addDeducedElementType(Value *Val, Type *Ty) { DeducedElTys[Val] = Ty; }
206 // - Find a record in the map of deduced element types.
208 auto It = DeducedElTys.find(Val);
209 return It == DeducedElTys.end() ? nullptr : It->second;
210 }
211 // - Find a record and update its key or add a new record, if found.
213 bool DeleteOld) {
214 if (Type *Ty = findDeducedElementType(OldVal)) {
215 if (DeleteOld)
216 DeducedElTys.erase(OldVal);
217 DeducedElTys[NewVal] = Ty;
218 }
219 }
220 // - Add a record to the map of deduced composite types.
222 DeducedNestedTys[Val] = Ty;
223 }
224 // - Find a record in the map of deduced composite types.
226 auto It = DeducedNestedTys.find(Val);
227 return It == DeducedNestedTys.end() ? nullptr : It->second;
228 }
229
230 // Store the element type associated with an untyped-pointer register.
232 UntypedPointerElementTypes[{CurMF, Reg}] = ElemType;
233 }
234 // Get the element type associated with an untyped-pointer register.
236 auto It = UntypedPointerElementTypes.find({CurMF, Reg});
237 return It == UntypedPointerElementTypes.end() ? nullptr : It->second;
238 }
239 // - Find a type of the given Global value
241 // we may know element type if it was deduced earlier
242 Type *ElementTy = findDeducedElementType(Global);
243 if (!ElementTy) {
244 // or we may know element type if it's associated with a composite
245 // value
246 if (Value *GlobalElem =
247 Global->getNumOperands() > 0 ? Global->getOperand(0) : nullptr)
248 ElementTy = findDeducedCompositeType(GlobalElem);
249 else if (const Function *Fn = dyn_cast<Function>(Global))
250 ElementTy = SPIRV::getOriginalFunctionType(*Fn);
251 }
252 return ElementTy ? ElementTy : Global->getValueType();
253 }
254
255 // Map a machine operand that represents a use of a function via function
256 // pointer to a machine operand that represents the function definition.
257 // Return either the register or invalid value, because we have no context for
258 // a good diagnostic message in case of unexpectedly missing references.
260 auto ResF = InstrToFunction.find(Use);
261 if (ResF == InstrToFunction.end())
262 return nullptr;
263 auto ResReg = FunctionToInstr.find(ResF->second);
264 return ResReg == FunctionToInstr.end() ? nullptr : ResReg->second;
265 }
266
267 // Map a Function to a machine instruction that represents the function
268 // definition.
270 if (!F)
271 return nullptr;
272 auto MOIt = FunctionToInstr.find(F);
273 return MOIt == FunctionToInstr.end() ? nullptr : MOIt->second->getParent();
274 }
275
276 // Map a Function to a machine instruction that represents the function
277 // definition.
279 if (!MI)
280 return nullptr;
281 auto FIt = FunctionToInstrRev.find(MI);
282 return FIt == FunctionToInstrRev.end() ? nullptr : FIt->second;
283 }
284
285 // map function pointer (as a machine instruction operand) to the used
286 // Function
288 InstrToFunction[MO] = F;
289 }
290
291 // map a Function to its definition (as a machine instruction)
293 FunctionToInstr[F] = MO;
294 FunctionToInstrRev[MO->getParent()] = F;
295 }
296
297 // Return true if any OpConstantFunctionPointerINTEL were generated
298 bool hasConstFunPtr() { return !InstrToFunction.empty(); }
299
300 // Add a record about forward function call.
302 ForwardCalls[F].insert(MI);
303 }
304
305 // Map a Function to the vector of machine instructions that represents
306 // forward function calls or to nullptr if not found.
308 auto It = ForwardCalls.find(F);
309 return It == ForwardCalls.end() ? nullptr : &It->second;
310 }
311
312 // Get or create a SPIR-V type corresponding the given LLVM IR type,
313 // and map it to the given VReg.
315 MachineIRBuilder &MIRBuilder,
316 SPIRV::AccessQualifier::AccessQualifier AQ,
317 bool EmitIR);
320
321 // In cases where the SPIR-V type is already known, this function can be
322 // used to map it to the given VReg.
324 const MachineFunction &MF);
325
326 // Either generate a new OpTypeXXX instruction or return an existing one
327 // corresponding to the given LLVM IR type.
328 // EmitIR controls if we emit GMIR or SPV constants (e.g. for array sizes)
329 // because this method may be called from InstructionSelector and we don't
330 // want to emit extra IR instructions there.
332 SPIRV::AccessQualifier::AccessQualifier AQ,
333 bool EmitIR) {
334 MachineIRBuilder MIRBuilder(I);
335 return getOrCreateSPIRVType(Type, MIRBuilder, AQ, EmitIR);
336 }
337
339 MachineIRBuilder &MIRBuilder,
340 SPIRV::AccessQualifier::AccessQualifier AQ,
341 bool EmitIR) {
342 return getOrCreateSPIRVType(Type, MIRBuilder, AQ, false, EmitIR);
343 }
344
346 auto Res = SPIRVToLLVMType.find(Ty);
347 assert(Res != SPIRVToLLVMType.end());
348 return Res->second;
349 }
350
351 // Return a pointee's type, or nullptr otherwise.
353
354 // Either generate a new OpTypeXXX instruction or return an existing one
355 // corresponding to the given string containing the name of the builtin type.
356 // Return nullptr if unable to recognize SPIRV type name from `TypeStr`.
358 StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR,
359 SPIRV::StorageClass::StorageClass SC = SPIRV::StorageClass::Function,
360 SPIRV::AccessQualifier::AccessQualifier AQ =
361 SPIRV::AccessQualifier::ReadWrite);
362
363 // Return the SPIR-V type instruction corresponding to the given VReg, or
364 // nullptr if no such type instruction exists. The second argument MF
365 // allows to search for the association in a context of the machine functions
366 // than the current one, without switching between different "current" machine
367 // functions.
369 const MachineFunction *MF = nullptr) const;
370
371 // Return the result type of the instruction defining the register.
373
374 // Return the VReg holding the result of the given OpTypeXXX instruction.
375 Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const;
376
377 // Return previous value of the current machine function
379 MachineFunction *Ret = CurMF;
380 CurMF = &MF;
381 return Ret;
382 }
383
384 // Return true if the type is an aggregate type.
386 return Type && (Type->getOpcode() == SPIRV::OpTypeStruct ||
387 Type->getOpcode() == SPIRV::OpTypeArray);
388 }
389
390 // Whether the given VReg has an OpTypeXXX instruction mapped to it with the
391 // given opcode (e.g. OpTypeFloat).
392 bool isScalarOfType(Register VReg, unsigned TypeOpcode) const;
393
394 // Return true if the given VReg's assigned SPIR-V type is either a scalar
395 // matching the given opcode, or a vector with an element type matching that
396 // opcode (e.g. OpTypeBool, or OpTypeVector %x 4, where %x is OpTypeBool).
397 bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const;
398
399 // Returns true if `Type` is a resource type. This could be an image type
400 // or a struct for a buffer decorated with the block decoration.
402
403 // Return number of elements in a vector if the argument is associated with
404 // a vector type. Return 1 for a scalar type, and 0 for a missing type.
405 unsigned getScalarOrVectorComponentCount(Register VReg) const;
407
408 // Return the component type in a vector if the argument is associated with
409 // a vector type. Returns the argument itself for other types, and nullptr
410 // for a missing type.
412
413 // For vectors or scalars of booleans, integers and floats, return the scalar
414 // type's bitwidth. Otherwise calls llvm_unreachable().
416
417 // For vectors or scalars of integers and floats, return total bitwidth of the
418 // argument. Otherwise returns 0.
420
421 // True if a pointer to this element type must stay typed rather than become
422 // OpTypeUntypedPointerKHR. Such an element type is either a function type,
423 // which an untyped pointer cannot express, or an opaque builtin type such as
424 // an image or a sampler.
425 bool shouldKeepTypedPtrType(SPIRVTypeInst ElemType) const;
426
427 // True if a pointer to this element type should be emitted as
428 // OpTypeUntypedPointerKHR rather than OpTypePointer.
430 const SPIRVSubtarget &ST) const;
431
432 // Byte size of a pointer value's IR-deduced element type, or 0 if unknown.
433 // Array indexing and copy strides work in terms of the alloc size, so this
434 // reports the size a value of that type occupies in an array. For OpenCL
435 // that means a 3-component vector is as large as a 4-component one.
436 unsigned getDeducedPointeeByteSize(const Value *PtrVal) {
437 if (Type *ElemTy = findDeducedElementType(PtrVal))
438 return DL.getTypeAllocSize(ElemTy).getFixedValue();
439 return 0;
440 }
441
442 // Returns either pointer to integer type, that may be a type of vector
443 // elements or an original type, or nullptr if the argument is niether
444 // an integer scalar, nor an integer vector
446
447 // For integer vectors or scalars, return whether the integers are signed.
449
450 // Gets the storage class of the pointer type assigned to this vreg.
451 SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const;
452 SPIRV::StorageClass::StorageClass
454
455 // Return the number of bits SPIR-V pointers and size_t variables require.
456 unsigned getPointerSize() const {
457 return DL.getPointerSizeInBits(/* AS = */ 0);
458 }
459
460 // Returns true if two types are defined and are compatible in a sense of
461 // OpBitcast instruction
462 bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const;
463
464 // Informs about removal of the machine instruction and invalidates data
465 // structures referring this instruction.
467
468private:
469 SPIRVTypeInst getOpTypeBool(MachineIRBuilder &MIRBuilder);
470
471 const Type *adjustIntTypeByWidth(const Type *Ty) const;
472 unsigned adjustOpTypeIntWidth(unsigned Width) const;
473
475 MachineIRBuilder &MIRBuilder,
476 SPIRV::AccessQualifier::AccessQualifier AQ,
477 bool ExplicitLayoutRequired, bool EmitIR);
478
479 SPIRVTypeInst getOpTypeInt(unsigned Width, MachineIRBuilder &MIRBuilder,
480 bool IsSigned = false);
481
482 SPIRVTypeInst getOpTypeFloat(uint32_t Width, MachineIRBuilder &MIRBuilder);
483
484 SPIRVTypeInst getOpTypeFloat(uint32_t Width, MachineIRBuilder &MIRBuilder,
485 SPIRV::FPEncoding::FPEncoding FPEncode);
486
487 SPIRVTypeInst getOpTypeVectorImpl(uint32_t NumElems, SPIRVTypeInst ElemType,
488 MachineIRBuilder &MIRBuilder,
489 bool IsLongVectorEXT = false);
490
491 SPIRVTypeInst getOpTypeVector(uint32_t NumElems, SPIRVTypeInst ElemType,
492 MachineIRBuilder &MIRBuilder);
493
494 SPIRVTypeInst getOpTypeVectorIdEXT(uint32_t NumElems, SPIRVTypeInst ElemType,
495 MachineIRBuilder &MIRBuilder);
496
497 SPIRVTypeInst getOpTypeArray(uint32_t NumElems, SPIRVTypeInst ElemType,
498 MachineIRBuilder &MIRBuilder,
499 bool ExplicitLayoutRequired, bool EmitIR);
500
501 SPIRVTypeInst getOpTypeOpaque(const StructType *Ty,
502 MachineIRBuilder &MIRBuilder);
503
504 SPIRVTypeInst getOpTypeStruct(const StructType *Ty,
505 MachineIRBuilder &MIRBuilder,
506 SPIRV::AccessQualifier::AccessQualifier AccQual,
507 StructOffsetDecorator Decorator, bool EmitIR);
508
509 SPIRVTypeInst getOpTypePointer(SPIRV::StorageClass::StorageClass SC,
510 SPIRVTypeInst ElemType,
511 MachineIRBuilder &MIRBuilder, Register Reg);
512
514 getOpTypeFunction(const FunctionType *Ty, SPIRVTypeInst RetType,
515 const SmallVectorImpl<SPIRVTypeInst> &ArgTypes,
516 MachineIRBuilder &MIRBuilder);
517
519 getOrCreateSpecialType(const Type *Ty, MachineIRBuilder &MIRBuilder,
520 SPIRV::AccessQualifier::AccessQualifier AccQual);
521
522 SPIRVTypeInst finishCreatingSPIRVType(const Type *LLVMTy,
523 SPIRVTypeInst SpirvType);
524 Register getOrCreateBaseRegister(Constant *Val, MachineInstr &I,
525 SPIRVTypeInst SpvType,
526 const SPIRVInstrInfo &TII, unsigned BitWidth,
527 bool ZeroAsNull);
528 Register getOrCreateCompositeOrNull(Constant *Val, MachineInstr &I,
529 SPIRVTypeInst SpvType,
530 const SPIRVInstrInfo &TII, Constant *CA,
531 unsigned BitWidth, unsigned ElemCnt,
532 bool ZeroAsNull = true);
533
534 Register getOrCreateIntCompositeOrNull(uint64_t Val,
535 MachineIRBuilder &MIRBuilder,
536 SPIRVTypeInst SpvType, bool EmitIR,
537 Constant *CA, unsigned BitWidth,
538 unsigned ElemCnt);
539
540 // Returns a pointer to a SPIR-V pointer type with the given base type and
541 // storage class. It is the responsibility of the caller to make sure the
542 // decorations on the base type are valid for the given storage class. For
543 // example, it has the correct offset and stride decorations.
544 // ForceTyped keeps an OpTypePointer even when untyped pointers are available,
545 // for cases where the pointee type must be preserved (e.g. a byval/byref/sret
546 // aggregate argument).
547 SPIRVTypeInst getOrCreateSPIRVPointerTypeInternal(
549 SPIRV::StorageClass::StorageClass SC, bool ForceTyped = false);
550
551 void addStructOffsetDecorations(Register Reg, StructType *Ty,
552 MachineIRBuilder &MIRBuilder);
553 void addArrayStrideDecorations(Register Reg, Type *ElementType,
554 MachineIRBuilder &MIRBuilder);
555
557
559 getOrCreateOpTypeImage(MachineIRBuilder &MIRBuilder,
560 SPIRVTypeInst SampledType, SPIRV::Dim::Dim Dim,
561 uint32_t Depth, uint32_t Arrayed,
562 uint32_t Multisampled, uint32_t Sampled,
563 SPIRV::ImageFormat::ImageFormat ImageFormat,
564 SPIRV::AccessQualifier::AccessQualifier AccQual);
565
566public:
568 SPIRVTypeInst SpvType, bool EmitIR,
569 bool ZeroAsNull = true);
571 SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII,
572 bool ZeroAsNull = true);
574 SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII,
575 bool ZeroAsNull = true);
577 SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII,
578 bool ZeroAsNull);
580 SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII,
581 bool ZeroAsNull = true);
583 SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII,
584 bool ZeroAsNull);
586 SPIRVTypeInst SpvType = nullptr);
587
589 SPIRVTypeInst SpvType,
590 const SPIRVInstrInfo &TII,
591 bool ZeroAsNull = true);
593 SPIRVTypeInst SpvType,
594 const SPIRVInstrInfo &TII,
595 bool ZeroAsNull = true);
597 SPIRVTypeInst SpvType,
598 const SPIRVInstrInfo &TII,
599 bool ZeroAsNull = true);
601 SPIRVTypeInst SpvType,
602 const SPIRVInstrInfo &TII);
604 SPIRVTypeInst SpvType, bool EmitIR);
606 SPIRVTypeInst SpvType);
607 Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param,
608 unsigned FilerMode,
609 MachineIRBuilder &MIRBuilder);
611 const SPIRVInstrInfo &TII);
614 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
615 const MachineInstr *Init, bool IsConst,
616 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
617 MachineIRBuilder &MIRBuilder, bool IsInstSelector);
620 StringRef Name,
621 MachineIRBuilder &MIRBuilder);
622
623 // Convenient helpers for getting types with check for duplicates.
625 MachineIRBuilder &MIRBuilder);
627 const SPIRVInstrInfo &TII);
629 const SPIRVInstrInfo &TII,
630 unsigned SPIRVOPcode, Type *LLVMTy);
632 const SPIRVInstrInfo &TII);
634 bool EmitIR);
636 const SPIRVInstrInfo &TII);
638 unsigned NumElements,
639 MachineIRBuilder &MIRBuilder,
640 bool EmitIR);
642 unsigned NumElements,
644 const SPIRVInstrInfo &TII);
646
647 // Returns a pointer to a SPIR-V pointer type with the given base type and
648 // storage class. The base type will be translated to a SPIR-V type, and the
649 // appropriate layout decorations will be added to the base type.
650 // See getOrCreateSPIRVPointerTypeInternal for ForceTyped.
652 const Type *BaseType, MachineIRBuilder &MIRBuilder,
653 SPIRV::StorageClass::StorageClass SC, bool ForceTyped = false);
656 SPIRV::StorageClass::StorageClass SC,
657 bool ForceTyped = false);
658
659 // Like getOrCreateSPIRVPointerType, but always returns an OpTypePointer even
660 // when untyped pointers are available. Use this when the pointee type must be
661 // preserved (e.g. a byval/byref/sret aggregate argument).
664 MachineIRBuilder &MIRBuilder,
665 SPIRV::StorageClass::StorageClass SC) {
666 return getOrCreateSPIRVPointerType(BaseType, MIRBuilder, SC,
667 /*ForceTyped=*/true);
668 }
669
670 // Returns a pointer to a SPIR-V pointer type with the given base type and
671 // storage class. It is the responsibility of the caller to make sure the
672 // decorations on the base type are valid for the given storage class. For
673 // example, it has the correct offset and stride decorations.
676 MachineIRBuilder &MIRBuilder,
677 SPIRV::StorageClass::StorageClass SC);
678
679 // Returns a pointer to a SPIR-V pointer type that is the same as `PtrType`
680 // except the stroage class has been changed to `SC`. It is the responsibility
681 // of the caller to be sure that the original and new storage class have the
682 // same layout requirements.
684 SPIRV::StorageClass::StorageClass SC,
685 MachineInstr &I);
686
687 // Returns OpTypeUntypedPointerKHR for the given storage class.
689 getOrCreateSPIRVUntypedPointerType(SPIRV::StorageClass::StorageClass SC,
690 MachineIRBuilder &MIRBuilder);
691
694 SPIRV::StorageClass::StorageClass SC,
695 bool IsWritable, bool EmitIr = false);
696
698
700 Type *ElemType);
701
703 const TargetExtType *T,
704 bool EmitIr = false);
705
707 getImageType(const TargetExtType *ExtensionType,
708 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
709 MachineIRBuilder &MIRBuilder);
710
712
714 MachineIRBuilder &MIRBuilder);
716 const TargetExtType *ExtensionType,
717 SPIRVTypeInst ElemType,
718 uint32_t Scope, uint32_t Rows,
719 uint32_t Columns, uint32_t Use,
720 bool EmitIR);
723 SPIRV::AccessQualifier::AccessQualifier AccQual);
726 const Type *Ty, SPIRVTypeInst RetType,
727 const SmallVectorImpl<SPIRVTypeInst> &ArgTypes,
728 MachineIRBuilder &MIRBuilder);
730 MachineIRBuilder &MIRBuilder,
731 unsigned Opcode);
732
734 MachineIRBuilder &MIRBuilder,
735 unsigned Opcode,
737
738 const TargetRegisterClass *getRegClass(SPIRVTypeInst SpvType) const;
739 LLT getRegType(SPIRVTypeInst SpvType) const;
740
742 const MDNode *AliasingListMD);
744 uint32_t Dec, const MDNode *GVarMD);
745 // Replace all uses of a |Old| with |New| updates the global registry type
746 // mappings.
747 void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld = true);
748
749 void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg,
750 bool CanUseAnyVectorRank);
752 void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType);
753};
754} // end namespace llvm
755#endif // LLVM_LIB_TARGET_SPIRV_SPIRVGLOBALREGISTRY_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Resource Implicit Binding
This file defines the DenseSet and SmallDenseSet classes.
const HexagonInstrInfo * TII
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
SI Fold Operands
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
Class for arbitrary precision integers.
Definition APInt.h:78
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:420
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:44
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
Class to represent function types.
iterator end()
Definition Function.h:840
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2987
Metadata node.
Definition Metadata.h:1081
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
void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg, bool CanUseAnyVectorRank)
void recordFunctionDefinition(const Function *F, const MachineOperand *MO)
SPIRVTypeInst getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
const TypedPointerType * findReturnType(const Function *ArgF)
bool isScalarOrVectorSigned(SPIRVTypeInst Type) const
void addForwardCall(const Function *F, MachineInstr *MI)
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
const Value * getGlobalObject(const MachineFunction *MF, Register R)
SPIRVTypeInst getOrCreateOpTypeSampledImage(SPIRVTypeInst ImageType, MachineIRBuilder &MIRBuilder)
unsigned getNumScalarOrVectorTotalBitWidth(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
void assignSPIRVTypeToVReg(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
SPIRVTypeInst getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVTypeInst RetType, const SmallVectorImpl< SPIRVTypeInst > &ArgTypes, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC, bool ForceTyped=false)
void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg)
const TargetRegisterClass * getRegClass(SPIRVTypeInst SpvType) const
MachineInstr * getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD)
bool isAggregateType(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVTypedPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
void setUntypedPtrElementType(Register Reg, SPIRVTypeInst ElemType)
SPIRVTypeInst getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVVectorType(SPIRVTypeInst BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
SPIRVTypeInst getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
Register buildGlobalVariable(Register Reg, SPIRVTypeInst 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)
SPIRVTypeInst assignIntTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
SPIRVTypeInst getResultType(Register VReg, MachineFunction *MF=nullptr)
Type * findDeducedCompositeType(const Value *Val)
void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld=true)
SPIRVTypeInst getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
unsigned getScalarOrVectorComponentCount(Register VReg) const
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const
void addDeducedElementType(Value *Val, Type *Ty)
bool shouldKeepTypedPtrType(SPIRVTypeInst ElemType) const
SPIRVTypeInst getOrCreatePaddingType(MachineIRBuilder &MIRBuilder)
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
const MachineInstr * getFunctionDefinition(const Function *F)
LLT getRegType(SPIRVTypeInst SpvType) const
void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy)
const MachineOperand * getFunctionDefinitionByUse(const MachineOperand *Use)
SPIRVTypeInst getOpTypeVoid(MachineIRBuilder &MIRBuilder)
void invalidateMachineInstr(MachineInstr *MI)
bool isResourceType(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder, bool EmitIR)
void addMutated(Value *Val, Type *Ty)
void updateIfExistDeducedElementType(Value *OldVal, Value *NewVal, bool DeleteOld)
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII)
bool findValueAttrs(const MachineInstr *Key, Type *&Ty, StringRef &Name)
unsigned getDeducedPointeeByteSize(const Value *PtrVal)
SPIRVTypeInst retrieveScalarOrVectorIntType(SPIRVTypeInst Type) const
Register getOrCreateGlobalVariableWithBinding(SPIRVTypeInst VarType, uint32_t Set, uint32_t Binding, StringRef Name, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType, SPIRVTypeInst ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns, uint32_t Use, bool EmitIR)
SPIRVTypeInst changePointerStorageClass(SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)
Type * findMutated(const Value *Val)
SPIRVTypeInst getOrCreateUnknownType(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode, const ArrayRef< MCOperand > Operands)
Register getOrCreateConstVector(uint64_t Val, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVTypeInst SpvType=nullptr)
SPIRVTypeInst getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AccQual)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
SPIRVTypeInst getScalarOrVectorComponentType(SPIRVTypeInst Type) const
void addDeducedCompositeType(Value *Val, Type *Ty)
void recordFunctionPointer(const MachineOperand *MO, const Function *F)
SPIRVTypeInst getOrCreateSPIRVFloatType(unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII)
SPIRVTypeInst getOrCreateVulkanBufferType(MachineIRBuilder &MIRBuilder, Type *ElemType, SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr=false)
SPIRVTypeInst getPointeeType(SPIRVTypeInst PtrType)
SmallPtrSet< MachineInstr *, 8 > * getForwardCalls(const Function *F)
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVTypeInst SpvType, bool EmitIR)
void updateIfExistAssignPtrTypeInstr(Value *OldVal, Value *NewVal, bool DeleteOld)
SPIRVTypeInst assignTypeToVReg(const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
SPIRVTypeInst getOrCreateLayoutType(MachineIRBuilder &MIRBuilder, const TargetExtType *T, bool EmitIr=false)
MachineFunction * setCurrentFunc(MachineFunction &MF)
Register createConstInt(const ConstantInt *CI, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, SPIRVTypeInst SpvType)
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
SPIRVTypeInst getOrCreateSPIRVUntypedPointerType(SPIRV::StorageClass::StorageClass SC, MachineIRBuilder &MIRBuilder)
Type * getDeducedGlobalValueType(const GlobalValue *Global)
Register getOrCreateUndef(MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII)
SPIRVTypeInst getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
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
void removeAssignPtrTypeInstr(Value *OldVal)
bool shouldUseUntypedPointer(SPIRVTypeInst ElemType, const SPIRVSubtarget &ST) const
Type * findDeducedElementType(const Value *Val)
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getUntypedPtrElementType(Register Reg) const
void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType)
CallInst * findAssignPtrTypeInstr(const Value *Val)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVTypeInst SpvType, bool EmitIR, bool ZeroAsNull=true)
SPIRVTypeInst getOrCreateVulkanPushConstantType(MachineIRBuilder &MIRBuilder, Type *ElemType)
Register createConstFP(const ConstantFP *CF, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
SPIRVTypeInst getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder)
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...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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:46
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
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition Utils.cpp:163
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
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58