LLVM 24.0.0git
SPIRVUtils.h
Go to the documentation of this file.
1//===--- SPIRVUtils.h ---- SPIR-V Utility Functions -------------*- 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// This file contains miscellaneous utility functions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
14#define LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
15
17#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/StringMap.h"
22#include "llvm/IR/Dominators.h"
24#include "llvm/IR/IRBuilder.h"
27#include <queue>
28#include <set>
29#include <string>
30
31#include "SPIRVTypeInst.h"
32
33namespace llvm {
34class MCInst;
35class MachineFunction;
39class Register;
40class StringRef;
41class Triple;
42class SPIRVInstrInfo;
43class SPIRVSubtarget;
45
46// This class implements a partial ordering visitor, which visits a cyclic graph
47// in natural topological-like ordering. Topological ordering is not defined for
48// directed graphs with cycles, so this assumes cycles are a single node, and
49// ignores back-edges. The cycle is visited from the entry in the same
50// topological-like ordering.
51//
52// Note: this visitor REQUIRES a reducible graph.
53//
54// This means once we visit a node, we know all the possible ancestors have been
55// visited.
56//
57// clang-format off
58//
59// Given this graph:
60//
61// ,-> B -\
62// A -+ +---> D ----> E -> F -> G -> H
63// `-> C -/ ^ |
64// +-----------------+
65//
66// Visit order is:
67// A, [B, C in any order], D, E, F, G, H
68//
69// clang-format on
70//
71// Changing the function CFG between the construction of the visitor and
72// visiting is undefined. The visitor can be reused, but if the CFG is updated,
73// the visitor must be rebuilt.
76 LoopInfo LI;
77
79 std::queue<BasicBlock *> ToVisit;
80
81 struct OrderInfo {
82 size_t Rank;
83 size_t TraversalIndex;
84 };
85
86 using BlockToOrderInfoMap = DenseMap<BasicBlock *, OrderInfo>;
87 BlockToOrderInfoMap BlockToOrder;
88 std::vector<BasicBlock *> Order;
89
90 // Get all basic-blocks reachable from Start.
91 SmallPtrSet<BasicBlock *, 0> getReachableFrom(BasicBlock *Start);
92
93 // Internal function used to determine the partial ordering.
94 // Visits |BB| with the current rank being |Rank|.
95 size_t visit(BasicBlock *BB, size_t Rank);
96
97 bool CanBeVisited(BasicBlock *BB) const;
98
99public:
100 size_t GetNodeRank(BasicBlock *BB) const;
101
102 // Build the visitor to operate on the function F.
104
105 // Returns the dominator tree computed for the function this visitor
106 // operates on.
107 const DomTreeBuilder::BBDomTree &getDominatorTree() const { return DT; }
108
109 // Returns true is |LHS| comes before |RHS| in the partial ordering.
110 // If |LHS| and |RHS| have the same rank, the traversal order determines the
111 // order (order is stable).
112 bool compare(const BasicBlock *LHS, const BasicBlock *RHS) const;
113
114 // Visit the function starting from the basic block |Start|, and calling |Op|
115 // on each visited BB. This traversal ignores back-edges, meaning this won't
116 // visit a node to which |Start| is not an ancestor.
117 // If Op returns |true|, the visitor continues. If |Op| returns false, the
118 // visitor will stop at that rank. This means if 2 nodes share the same rank,
119 // and Op returns false when visiting the first, the second will be visited
120 // afterwards. But none of their successors will.
121 void partialOrderVisit(BasicBlock &Start,
122 std::function<bool(BasicBlock *)> Op);
123};
124
125namespace SPIRV {
127 const Type *Ty = nullptr;
128 unsigned FastMathFlags = 0;
129 // When SPV_KHR_float_controls2 ContractionOff and SignzeroInfNanPreserve are
130 // deprecated, and we replace them with FPFastMathDefault appropriate flags
131 // instead. However, we have no guarantee about the order in which we will
132 // process execution modes. Therefore it could happen that we first process
133 // ContractionOff, setting AllowContraction bit to 0, and then we process
134 // FPFastMathDefault enabling AllowContraction bit, effectively invalidating
135 // ContractionOff. Because of that, it's best to keep separate bits for the
136 // different execution modes, and we will try and combine them later when we
137 // emit OpExecutionMode instructions.
138 bool ContractionOff = false;
140 bool FPFastMathDefault = false;
141
145};
146
148 : public SmallVector<SPIRV::FPFastMathDefaultInfo, 3> {
150 switch (BitWidth) {
151 case 16: // half
152 return 0;
153 case 32: // float
154 return 1;
155 case 64: // double
156 return 2;
157 default:
158 report_fatal_error("Expected BitWidth to be 16, 32, 64", false);
159 }
161 "Unreachable code in computeFPFastMathDefaultInfoVecIndex");
162 }
163};
164
165// This code restores function args/retvalue types for composite cases
166// because the final types should still be aggregate whereas they're i32
167// during the translation to cope with aggregate flattening etc.
170// This handles retrieving the original ASM constraints, which we had to spoof
171// into having a single output.
173} // namespace SPIRV
174
175// Add the given string as a series of integer operand, inserting null
176// terminators and padding to make sure the operands all have 32-bit
177// little-endian words.
178void addStringImm(StringRef Str, MCInst &Inst);
179void addStringImm(StringRef Str, MachineInstrBuilder &MIB);
180
181// Read the series of integer operands back as a null-terminated string using
182// the reverse of the logic in addStringImm.
183std::string getStringImm(const MachineInstr &MI, unsigned StartIndex);
184
185// Returns the string constant that the register refers to. It is assumed that
186// Reg is a global value that contains a string.
187std::string getStringValueFromReg(Register Reg, MachineRegisterInfo &MRI);
188
189// Add the given numerical immediate to MIB.
190void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB);
191
192// Add an OpName instruction for the given target register.
193void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder);
194
195// Add an OpDecorate instruction for the given Reg.
196void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
197 SPIRV::Decoration::Decoration Dec,
198 ArrayRef<uint32_t> DecArgs, StringRef StrImm = "");
199void buildOpDecorate(Register Reg, MachineInstr &I, const SPIRVInstrInfo &TII,
200 SPIRV::Decoration::Decoration Dec,
201 ArrayRef<uint32_t> DecArgs, StringRef StrImm = "");
202
203// Add an OpDecorate instruction for the given Reg.
204void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
205 SPIRV::Decoration::Decoration Dec, uint32_t Member,
206 ArrayRef<uint32_t> DecArgs, StringRef StrImm = "");
207
208// Add an OpDecorate instruction by "spirv.Decorations" metadata node.
209void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
210 const MDNode *GVarMD, const SPIRVSubtarget &ST);
211
212// Return a valid position for the OpVariable instruction inside a function,
213// i.e., at the beginning of the first block of the function.
215
216// Return a valid position for the instruction at the end of the block before
217// terminators and debug instructions.
219
220// Returns true if a pointer to the storage class can be casted to/from a
221// pointer to the Generic storage class.
222constexpr bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC) {
223 switch (SC) {
224 case SPIRV::StorageClass::Workgroup:
225 case SPIRV::StorageClass::CrossWorkgroup:
226 case SPIRV::StorageClass::Function:
227 case SPIRV::StorageClass::CodeSectionINTEL:
228 return true;
229 default:
230 return false;
231 }
232}
233
234// Convert a SPIR-V storage class to the corresponding LLVM IR address space.
235// TODO: maybe the following two functions should be handled in the subtarget
236// to allow for different OpenCL vs Vulkan handling.
237constexpr unsigned
238storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC) {
239 switch (SC) {
240 case SPIRV::StorageClass::Function:
241 return SPIRVAS::Function;
242 case SPIRV::StorageClass::CrossWorkgroup:
244 case SPIRV::StorageClass::UniformConstant:
246 case SPIRV::StorageClass::Workgroup:
247 return SPIRVAS::Workgroup;
248 case SPIRV::StorageClass::Generic:
249 return SPIRVAS::Generic;
250 case SPIRV::StorageClass::DeviceOnlyINTEL:
252 case SPIRV::StorageClass::HostOnlyINTEL:
254 case SPIRV::StorageClass::Input:
255 return SPIRVAS::Input;
256 case SPIRV::StorageClass::Output:
257 return SPIRVAS::Output;
258 case SPIRV::StorageClass::CodeSectionINTEL:
260 case SPIRV::StorageClass::Private:
261 return SPIRVAS::Private;
262 case SPIRV::StorageClass::StorageBuffer:
264 case SPIRV::StorageClass::Uniform:
265 return SPIRVAS::Uniform;
266 case SPIRV::StorageClass::PushConstant:
268 default:
269 report_fatal_error("Unable to get address space id");
270 }
271}
272
273// Convert an LLVM IR address space to a SPIR-V storage class.
274SPIRV::StorageClass::StorageClass
275addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI);
276
277SPIRV::MemorySemantics::MemorySemantics
278getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC);
279
280SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord);
281
282uint32_t getMemSemanticsWithStorageClass(const Triple &TT, uint32_t OrderSem,
283 uint32_t StorageClassSem);
284
285SPIRV::Scope::Scope getMemScope(const Triple &TT, LLVMContext &Ctx,
286 SyncScope::ID Id);
287
288// Find def instruction for the given ConstReg, walking through
289// spv_track_constant and ASSIGN_TYPE instructions. Updates ConstReg by def
290// of OpConstant instruction.
291MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
292 const MachineRegisterInfo *MRI);
293
294// Get constant integer value of the given ConstReg.
295uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI);
296
297// Get constant integer value of the given ConstReg, sign-extended.
298int64_t getIConstValSext(Register ConstReg, const MachineRegisterInfo *MRI);
299
300// Check if MI is a SPIR-V specific intrinsic call.
301bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID);
302// Check if it's a SPIR-V specific intrinsic call.
303bool isSpvIntrinsic(const Value *Arg);
304
305// Get type of i-th operand of the metadata node.
306Type *getMDOperandAsType(const MDNode *N, unsigned I);
307
308// Get the i-th operand of the metadata node as a ConstantInt, or nullptr if it
309// is out of range or not a ConstantInt.
310ConstantInt *getMDOperandAsConstInt(const MDNode *N, unsigned I);
311
312// If OpenCL or SPIR-V builtin function name is recognized, return a demangled
313// name, otherwise return an empty string.
314std::string getOclOrSpirvBuiltinDemangledName(StringRef Name);
315
316// Check if a string contains a builtin prefix.
317bool hasBuiltinTypePrefix(StringRef Name);
318
319// Check if given LLVM type is a special opaque builtin type.
320bool isSpecialOpaqueType(const Type *Ty);
321
322// Check if the function is an SPIR-V entry point
323bool isEntryPoint(const Function &F);
324
325// Parse basic scalar type name, substring TypeName, and return LLVM type.
326Type *parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx);
327
328// Sort blocks in a partial ordering, so each block is after all its
329// dominators. This should match both the SPIR-V and the MIR requirements.
330// Returns true if the function was changed.
331bool sortBlocks(Function &F);
332
333// Create a stack slot in the entry block of F for a value of the given type.
334AllocaInst *createVariable(Function &F, Type *Type);
335
336// Create a value in BB set to the value associated with the branch the block
337// terminator will take.
338Value *
339createExitVariable(BasicBlock *BB,
340 const DenseMap<BasicBlock *, ConstantInt *> &TargetToValue);
341
342// Check for peeled array structs and recursively reconstitute them. In HLSL
343// CBuffers, arrays may have padding between the elements, but not after the
344// last element. To represent this in LLVM IR an array [N x T] will be
345// represented as {[N-1 x {T, spirv.Padding}], T}. The function
346// matchPeeledArrayPattern recognizes this pattern retrieving the type {T,
347// spirv.Padding}, and the size N.
348bool matchPeeledArrayPattern(const StructType *Ty, Type *&OriginalElementType,
349 uint64_t &TotalSize);
350
351// This function will turn the type {[N-1 x {T, spirv.Padding}], T} back into
352// [N x {T, spirv.Padding}]. So it can be translated into SPIR-V. The offset
353// decorations will be such that there will be no padding after the array when
354// relevant.
355Type *reconstitutePeeledArrayType(Type *Ty);
356
357inline bool hasInitializer(const GlobalVariable *GV) {
358 if (!GV->hasInitializer())
359 return false;
360 if (const auto *Init = GV->getInitializer(); isa<UndefValue>(Init))
361 return GV->isConstant() && Init->getType()->isAggregateType();
362 return true;
363}
364
365// True if this is an instance of TypedPointerType.
366inline bool isTypedPointerTy(const Type *T) {
367 return T && T->getTypeID() == Type::TypedPointerTyID;
368}
369
370// True if this is an instance of PointerType.
371inline bool isUntypedPointerTy(const Type *T) {
372 return T && T->getTypeID() == Type::PointerTyID;
373}
374
375// True if this is an instance of PointerType or TypedPointerType.
376inline bool isPointerTy(const Type *T) {
378}
379
380// True if this is a vector whose element type is an (untyped) PointerType.
381inline bool isUntypedPointerVectorTy(const Type *T) {
383 isUntypedPointerTy(T->getScalarType());
384}
385
386// Get the address space of this pointer or pointer vector type for instances of
387// PointerType or TypedPointerType.
388inline unsigned getPointerAddressSpace(const Type *T) {
389 Type *SubT = T->getScalarType();
390 return SubT->getTypeID() == Type::PointerTyID
391 ? cast<PointerType>(SubT)->getAddressSpace()
392 : cast<TypedPointerType>(SubT)->getAddressSpace();
393}
394
395// Return true if the Argument is decorated with a pointee type
396inline bool hasPointeeTypeAttr(Argument *Arg) {
397 return Arg->hasByValAttr() || Arg->hasByRefAttr() || Arg->hasStructRetAttr();
398}
399
400// Return the pointee type of the argument or nullptr otherwise
402 if (Arg->hasByValAttr())
403 return Arg->getParamByValType();
404 if (Arg->hasStructRetAttr())
405 return Arg->getParamStructRetType();
406 if (Arg->hasByRefAttr())
407 return Arg->getParamByRefType();
408 return nullptr;
409}
410
411#define TYPED_PTR_TARGET_EXT_NAME "spirv.$TypedPointerType"
412inline Type *getTypedPointerWrapper(Type *ElemTy, unsigned AS) {
414 {ElemTy}, {AS});
415}
416
417inline bool isTypedPointerWrapper(const TargetExtType *ExtTy) {
418 return ExtTy->getName() == TYPED_PTR_TARGET_EXT_NAME &&
419 ExtTy->getNumIntParameters() == 1 &&
420 ExtTy->getNumTypeParameters() == 1;
421}
422
423// True if this is an instance of PointerType or TypedPointerType.
424inline bool isPointerTyOrWrapper(const Type *Ty) {
425 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty))
426 return isTypedPointerWrapper(ExtTy);
427 return isPointerTy(Ty);
428}
429
430inline Type *applyWrappers(Type *Ty) {
431 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty)) {
432 if (isTypedPointerWrapper(ExtTy))
433 return TypedPointerType::get(applyWrappers(ExtTy->getTypeParameter(0)),
434 ExtTy->getIntParameter(0));
435 } else if (auto *VecTy = dyn_cast<VectorType>(Ty)) {
436 Type *ElemTy = VecTy->getElementType();
437 Type *NewElemTy = ElemTy->isTargetExtTy() ? applyWrappers(ElemTy) : ElemTy;
438 if (NewElemTy != ElemTy)
439 return VectorType::get(NewElemTy, VecTy->getElementCount());
440 }
441 return Ty;
442}
443
444inline Type *getPointeeType(const Type *Ty) {
445 if (Ty) {
446 if (auto PType = dyn_cast<TypedPointerType>(Ty))
447 return PType->getElementType();
448 else if (auto *ExtTy = dyn_cast<TargetExtType>(Ty))
449 if (isTypedPointerWrapper(ExtTy))
450 return ExtTy->getTypeParameter(0);
451 }
452 return nullptr;
453}
454
455inline bool isUntypedEquivalentToTyExt(Type *Ty1, Type *Ty2) {
456 if (!isUntypedPointerTy(Ty1) || !Ty2)
457 return false;
458 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty2))
459 if (isTypedPointerWrapper(ExtTy) &&
460 ExtTy->getTypeParameter(0) ==
462 ExtTy->getIntParameter(0) == cast<PointerType>(Ty1)->getAddressSpace())
463 return true;
464 return false;
465}
466
467inline bool isEquivalentTypes(Type *Ty1, Type *Ty2) {
468 return isUntypedEquivalentToTyExt(Ty1, Ty2) ||
470}
471
473 if (Type *NewTy = applyWrappers(Ty); NewTy != Ty)
474 return NewTy;
475 return isUntypedPointerTy(Ty)
478 : Ty;
479}
480
482 Type *OrigRetTy = FTy->getReturnType();
483 Type *RetTy = toTypedPointer(OrigRetTy);
484 bool IsUntypedPtr = false;
485 for (Type *PTy : FTy->params()) {
486 if (isUntypedPointerTy(PTy)) {
487 IsUntypedPtr = true;
488 break;
489 }
490 }
491 if (!IsUntypedPtr && RetTy == OrigRetTy)
492 return FTy;
493 SmallVector<Type *> ParamTys;
494 for (Type *PTy : FTy->params())
495 ParamTys.push_back(toTypedPointer(PTy));
496 return FunctionType::get(RetTy, ParamTys, FTy->isVarArg());
497}
498
499inline const Type *unifyPtrType(const Type *Ty) {
500 if (auto FTy = dyn_cast<FunctionType>(Ty))
501 return toTypedFunPointer(const_cast<FunctionType *>(FTy));
502 return toTypedPointer(const_cast<Type *>(Ty));
503}
504
505inline bool isVector1(Type *Ty) {
506 auto *FVTy = dyn_cast<FixedVectorType>(Ty);
507 return FVTy && FVTy->getNumElements() == 1;
508}
509
510// We define this predicate out of line to avoid having to include all OpTypes.
511bool isVectorType(SPIRVTypeInst SPVTy);
512
513// Per spec: "Vector types must be parameterized only with 2, 3, or
514// 4 components, plus any additional sizes enabled by capabilities.", and
515// we always enable the Vector16 capability.
516inline bool requiresLongVectorEXT(unsigned NumComponents) {
517 return NumComponents != 2 && NumComponents != 3 && NumComponents != 4 &&
518 NumComponents != 8 && NumComponents != 16;
519}
520
521inline bool isLongVectorEXT(const Type *Ty) {
522 if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
523 return requiresLongVectorEXT(FVTy->getNumElements());
524 return false;
525}
526
527// Modify an LLVM type to conform with future transformations in IRTranslator.
528// At the moment use cases comprise only a <1 x Type> vector. To extend when/if
529// needed.
530inline Type *normalizeType(Type *Ty, bool CanUseAnyVectorRank) {
531 if (CanUseAnyVectorRank)
532 return Ty;
533
534 auto *FVTy = dyn_cast<FixedVectorType>(Ty);
535 if (!FVTy || FVTy->getNumElements() != 1)
536 return Ty;
537 // If it's a <1 x Type> vector type, replace it by the element type, because
538 // it's not a legal vector type in LLT and IRTranslator will represent it as
539 // the scalar eventually.
540 return normalizeType(FVTy->getElementType(), CanUseAnyVectorRank);
541}
542
544 bool CanUseAnyVectorRank) {
545 return PoisonValue::get(normalizeType(Ty, CanUseAnyVectorRank));
546}
547
549 LLVMContext &Ctx = Arg->getContext();
552}
553
554CallInst *buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef<Type *> Types,
555 Value *Arg, Value *Arg2, ArrayRef<Constant *> Imms,
556 IRBuilder<> &B);
557
558MachineInstr *getVRegDef(MachineRegisterInfo &MRI, Register Reg);
559
560#define SPIRV_BACKEND_SERVICE_FUN_NAME "__spirv_backend_service_fun"
561#define SPIRV_WAS_AVAILABLE_EXTERNALLY_ATTR "spv.was-available-externally"
562
563void setRegClassType(Register Reg, const Type *Ty, SPIRVGlobalRegistry *GR,
564 MachineIRBuilder &MIRBuilder,
565 SPIRV::AccessQualifier::AccessQualifier AccessQual,
566 bool EmitIR, bool Force = false);
567void setRegClassType(Register Reg, SPIRVTypeInst SpvType,
568 SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI,
569 const MachineFunction &MF, bool Force = false);
570Register createVirtualRegister(SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR,
571 MachineRegisterInfo *MRI,
572 const MachineFunction &MF);
573Register createVirtualRegister(SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR,
574 MachineIRBuilder &MIRBuilder);
576 const Type *Ty, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIRBuilder,
577 SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR);
578
579// Return true if there is an opaque pointer type nested in the argument.
580bool isNestedPointer(const Type *Ty);
581
583
584inline FPDecorationId demangledPostfixToDecorationId(const std::string &S) {
585 static const StringMap<FPDecorationId> Mapping = {
586 {"rte", FPDecorationId::RTE},
587 {"rtz", FPDecorationId::RTZ},
588 {"rtp", FPDecorationId::RTP},
589 {"rtn", FPDecorationId::RTN},
590 {"sat", FPDecorationId::SAT}};
591 auto It = Mapping.find(S);
592 return It == Mapping.end() ? FPDecorationId::NONE : It->second;
593}
594
595SmallVector<MachineInstr *, 4>
596createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
597 unsigned MinWC, unsigned ContinuedOpcode,
598 ArrayRef<Register> Args, Register ReturnRegister,
600
601// Instruction selection directed by type folding.
602const std::set<unsigned> &getTypeFoldingSupportedOpcodes();
603bool isTypeFoldingSupported(unsigned Opcode);
604
605// Get loop controls from llvm.loop. metadata.
606SmallVector<unsigned, 1> getSpirvLoopControlOperandsFromLoopMetadata(Loop *L);
607SmallVector<unsigned, 1>
609
610// Traversing [g]MIR accounting for pseudo-instructions.
611MachineInstr *passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI);
612MachineInstr *getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI);
613MachineInstr *getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
614int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
615unsigned getArrayComponentCount(const MachineRegisterInfo *MRI,
616 const MachineInstr *ResType);
617
618std::optional<SPIRV::LinkageType::LinkageType>
619getSpirvLinkageTypeFor(const SPIRVSubtarget &ST, const GlobalValue &GV);
621} // namespace llvm
622#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
This file defines the StringMap class.
uint64_t uint64_t
uint64_t Imm
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
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
Machine Check Debug Module
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
Type::TypeID TypeID
#define T
MachineRegisterInfo & MRI
SPIR-V address space definition.
#define TYPED_PTR_TARGET_EXT_NAME
Definition SPIRVUtils.h:411
This file defines the SmallPtrSet class.
Value * RHS
Value * LHS
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI Type * getParamByRefType() const
If this is a byref argument, return its type.
Definition Function.cpp:228
LLVM_ABI bool hasByRefAttr() const
Return true if this argument has the byref attribute.
Definition Function.cpp:136
LLVM_ABI Type * getParamStructRetType() const
If this is an sret argument, return its type.
Definition Function.cpp:223
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:126
LLVM_ABI Type * getParamByValType() const
If this is a byval argument, return its type.
Definition Function.cpp:218
LLVM_ABI bool hasStructRetAttr() const
Return true if this argument has the sret attribute.
Definition Function.cpp:281
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Class to represent function types.
ArrayRef< Type * > params() const
bool isVarArg() const
Type * getReturnType() const
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
MachineInstrBundleIterator< MachineInstr > iterator
Helper class to build MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Metadata wrapper in the Value hierarchy.
Definition Metadata.h:184
static LLVM_ABI MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition Metadata.cpp:107
size_t GetNodeRank(BasicBlock *BB) const
void partialOrderVisit(BasicBlock &Start, std::function< bool(BasicBlock *)> Op)
bool compare(const BasicBlock *LHS, const BasicBlock *RHS) const
const DomTreeBuilder::BBDomTree & getDominatorTree() const
Definition SPIRVUtils.h:107
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
Definition Constants.h:1705
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
iterator end()
Definition StringMap.h:214
iterator find(StringRef Key)
Definition StringMap.h:227
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Class to represent target extensions types, which are generally unintrospectable from target-independ...
unsigned getNumIntParameters() const
static LLVM_ABI TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Definition Type.cpp:936
unsigned getNumTypeParameters() const
StringRef getName() const
Return the name for this target extension type.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
@ TypedPointerTyID
Typed pointer used by some GPU targets.
Definition Type.h:79
@ PointerTyID
Pointers.
Definition Type.h:74
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
TypeID getTypeID() const
Return the type id for the type.
Definition Type.h:138
static LLVM_ABI TypedPointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static ConstantAsMetadata * getConstant(Value *C)
Definition Metadata.h:492
LLVM Value Representation.
Definition Value.h:75
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
DomTreeBase< BasicBlock > BBDomTree
Definition Dominators.h:55
FunctionType * getOriginalFunctionType(const Function &F)
StringRef getOriginalAsmConstraints(const CallBase &CB)
This is an optimization pass for GlobalISel generic memory operations.
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
void addStringImm(StringRef Str, MCInst &Inst)
MachineBasicBlock::iterator getOpVariableMBBIt(MachineFunction &MF)
int64_t getIConstValSext(Register ConstReg, const MachineRegisterInfo *MRI)
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
Definition SPIRVUtils.h:417
bool isTypeFoldingSupported(unsigned Opcode)
uint32_t getMemSemanticsWithStorageClass(const Triple &TT, uint32_t OrderSem, uint32_t StorageClassSem)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:388
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
MachineInstr * getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI)
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
FPDecorationId demangledPostfixToDecorationId(const std::string &S)
Definition SPIRVUtils.h:584
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
bool requiresLongVectorEXT(unsigned NumComponents)
Definition SPIRVUtils.h:516
bool isUntypedPointerVectorTy(const Type *T)
Definition SPIRVUtils.h:381
bool isLongVectorEXT(const Type *Ty)
Definition SPIRVUtils.h:521
bool matchPeeledArrayPattern(const StructType *Ty, Type *&OriginalElementType, uint64_t &TotalSize)
Register createVirtualRegister(SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
unsigned getArrayComponentCount(const MachineRegisterInfo *MRI, const MachineInstr *ResType)
bool sortBlocks(Function &F)
Type * toTypedFunPointer(FunctionType *FTy)
Definition SPIRVUtils.h:481
FPDecorationId
Definition SPIRVUtils.h:582
AllocaInst * createVariable(Function &F, Type *Type)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
SPIRV::Scope::Scope getMemScope(const Triple &TT, LLVMContext &Ctx, SyncScope::ID Id)
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
SmallVector< MachineInstr *, 4 > createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode, unsigned MinWC, unsigned ContinuedOpcode, ArrayRef< Register > Args, Register ReturnRegister, Register TypeID)
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
Definition SPIRVUtils.h:238
bool isVectorType(SPIRVTypeInst SPVTy)
bool isNestedPointer(const Type *Ty)
Function * getOrCreateBackendServiceFunction(Module &M)
MetadataAsValue * buildMD(Value *Arg)
Definition SPIRVUtils.h:548
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)
bool isTypedPointerTy(const Type *T)
Definition SPIRVUtils.h:366
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
bool isUntypedEquivalentToTyExt(Type *Ty1, Type *Ty2)
Definition SPIRVUtils.h:455
SmallVector< unsigned, 1 > getSpirvLoopControlOperandsFromLoopMetadata(MDNode *LoopMD)
Type * normalizeType(Type *Ty, bool CanUseAnyVectorRank)
Definition SPIRVUtils.h:530
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * getTypedPointerWrapper(Type *ElemTy, unsigned AS)
Definition SPIRVUtils.h:412
Type * toTypedPointer(Type *Ty)
Definition SPIRVUtils.h:472
ConstantInt * getMDOperandAsConstInt(const MDNode *N, unsigned I)
bool isVector1(Type *Ty)
Definition SPIRVUtils.h:505
bool isSpecialOpaqueType(const Type *Ty)
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:376
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
void setRegClassType(Register Reg, SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
const Type * unifyPtrType(const Type *Ty)
Definition SPIRVUtils.h:499
constexpr bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC)
Definition SPIRVUtils.h:222
MachineInstr * passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
std::optional< SPIRV::LinkageType::LinkageType > getSpirvLinkageTypeFor(const SPIRVSubtarget &ST, const GlobalValue &GV)
bool isEntryPoint(const Function &F)
const std::set< unsigned > & getTypeFoldingSupportedOpcodes()
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
std::string getStringValueFromReg(Register Reg, MachineRegisterInfo &MRI)
int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
Type * getPointeeTypeByAttr(Argument *Arg)
Definition SPIRVUtils.h:401
bool hasPointeeTypeAttr(Argument *Arg)
Definition SPIRVUtils.h:396
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
constexpr unsigned BitWidth
Value * createExitVariable(BasicBlock *BB, const DenseMap< BasicBlock *, ConstantInt * > &TargetToValue)
bool isEquivalentTypes(Type *Ty1, Type *Ty2)
Definition SPIRVUtils.h:467
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool hasBuiltinTypePrefix(StringRef Name)
Type * getMDOperandAsType(const MDNode *N, unsigned I)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
bool hasInitializer(const GlobalVariable *GV)
Definition SPIRVUtils.h:357
Type * applyWrappers(Type *Ty)
Definition SPIRVUtils.h:430
bool isPointerTyOrWrapper(const Type *Ty)
Definition SPIRVUtils.h:424
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
Type * getPointeeType(const Type *Ty)
Definition SPIRVUtils.h:444
PoisonValue * getNormalizedPoisonValue(Type *Ty, bool CanUseAnyVectorRank)
Definition SPIRVUtils.h:543
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
bool isUntypedPointerTy(const Type *T)
Definition SPIRVUtils.h:371
Type * reconstitutePeeledArrayType(Type *Ty)
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)
#define N
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
Definition SPIRVUtils.h:149
FPFastMathDefaultInfo(const Type *Ty, unsigned FastMathFlags)
Definition SPIRVUtils.h:143