52#include "llvm/IR/IntrinsicsSPIRV.h"
59class SPIRVLegalizePointerCastImpl {
66 {Arg->
getType()}, OfType, Arg, {},
B);
67 GR->addAssignPtrTypeInstr(Arg, AssignCI);
70 static FixedVectorType *makeVectorFromTotalBits(
Type *ElemTy,
73 assert(ElemBits && TotalBits % ElemBits == 0 &&
74 "TotalBits must be divisible by element bit size");
79 FixedVectorType *DstTy) {
82 "shuffle resize expects identical element types");
85 const unsigned NumSource = SrcTy->getNumElements();
87 SmallVector<int>
Mask(NumNeeded);
88 for (
unsigned I = 0;
I < NumNeeded; ++
I)
89 Mask[
I] = (
I < NumSource) ?
static_cast<int>(
I) : -1;
91 Value *Resized =
B.CreateShuffleVector(V, V, Mask);
92 buildAssignType(
B, DstTy, Resized);
101 FixedVectorType *TargetType,
Value *Source,
102 Align OriginalAlign) {
103 LoadInst *NewLoad =
B.CreateLoad(SourceType, Source);
105 buildAssignType(
B, SourceType, NewLoad);
106 Value *AssignValue = NewLoad;
108 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
109 TypeSize TargetTypeSize =
DL.getTypeSizeInBits(TargetType);
110 TypeSize SourceTypeSize =
DL.getTypeSizeInBits(SourceType);
112 Value *BitcastSrcVal = NewLoad;
113 FixedVectorType *BitcastSrcTy =
117 if (TargetTypeSize != SourceTypeSize) {
118 unsigned TargetElemBits =
119 TargetType->getElementType()->getScalarSizeInBits();
120 if (SourceTypeSize % TargetElemBits == 0) {
123 BitcastDstTy = makeVectorFromTotalBits(
TargetType->getElementType(),
127 BitcastSrcTy = makeVectorFromTotalBits(SourceType->
getElementType(),
129 BitcastSrcVal = resizeVectorBitsWithShuffle(
B, NewLoad, BitcastSrcTy);
133 B.CreateIntrinsic(Intrinsic::spv_bitcast,
134 {BitcastDstTy, BitcastSrcTy}, {BitcastSrcVal});
135 buildAssignType(
B, BitcastDstTy, AssignValue);
136 if (BitcastDstTy == TargetType)
141 const unsigned NumTarget =
TargetType->getNumElements();
142 const unsigned NumSource = AssignVecTy->getNumElements();
148 if (NumTarget > NumSource) {
150 buildAssignType(
B, TargetType, Result);
151 for (
unsigned I = 0;
I < NumSource; ++
I) {
153 Result = makeInsertElement(
B, Result, Scalar,
I);
158 assert(NumTarget < NumSource);
159 SmallVector<int>
Mask( NumTarget);
160 for (
unsigned I = 0;
I < NumTarget; ++
I)
162 Value *Output =
B.CreateShuffleVector(AssignValue, AssignValue, Mask);
163 buildAssignType(
B, TargetType, Output);
169 bool isCompatibleMemoryLayout(
Type *ToTy,
Type *FromTy) {
178 if (
SAT->getElementType() == DVT->getElementType())
181 if (MAT->getElementType() == DVT->getElementType())
189 std::optional<std::pair<Value *, Type *>>
191 Type *PointerType,
Type *TargetElemType,
193 Type *CurrentTy = GR->findDeducedElementType(BasePtr);
194 assert(CurrentTy &&
"Could not deduce aggregate type");
195 SmallVector<Value *, 8>
Args{
B.getInt1(IsInBounds),
197 Args.push_back(
B.getInt32(0));
199 while (!isCompatibleMemoryLayout(TargetElemType, CurrentTy)) {
201 if (
ST->getNumElements() == 0)
203 CurrentTy =
ST->getTypeAtIndex(0u);
205 CurrentTy = AT->getElementType();
207 CurrentTy = VT->getElementType();
211 Args.push_back(
B.getInt32(0));
215 if (
Args.size() > 3) {
217 GEP =
B.CreateIntrinsic(Intrinsic::spv_gep, {
Types}, {
Args});
218 GR->buildAssignPtr(
B, CurrentTy,
GEP);
221 return std::make_pair(
GEP, CurrentTy);
224 static IntrinsicInst *getResourceGetPointer(
Value *Ptr) {
226 if (
II->getIntrinsicID() == Intrinsic::spv_resource_getpointer)
235 if (IntrinsicInst *ResourcePtr = getResourceGetPointer(BasePtr)) {
236 Value *Handle = ResourcePtr->getOperand(0);
237 Value *BaseOffset = ResourcePtr->getOperand(1);
241 ConstantInt::get(CI->getType(), CI->getZExtValue() + ByteOffset);
243 NewOffset =
B.CreateAdd(
244 BaseOffset, ConstantInt::get(BaseOffset->
getType(), ByteOffset));
246 ResourcePtr->getOperandBundlesAsDefs(OpBundles);
247 CallInst *ResourcePtrAtOffset =
B.CreateCall(
248 ResourcePtr->getFunctionType(), ResourcePtr->getCalledOperand(),
249 {Handle, NewOffset}, OpBundles);
250 ResourcePtrAtOffset->
setAttributes(ResourcePtr->getAttributes());
251 ResourcePtrAtOffset->
setCallingConv(ResourcePtr->getCallingConv());
252 Type *I8Ty = Type::getInt8Ty(
B.getContext());
253 GR->buildAssignPtr(
B, I8Ty, ResourcePtrAtOffset);
254 return ResourcePtrAtOffset;
257 "byte layout pointer must come from spv.resource.getpointer");
262 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
268 return B.CreateIntCast(Scalar, IntTy,
false);
269 return B.CreateIntrinsic(Intrinsic::spv_bitcast, {IntTy, Ty}, {
Scalar});
273 if (
IntVal->getType() == ScalarTy)
276 return B.CreateIntCast(IntVal, ScalarTy,
false);
277 return B.CreateIntrinsic(Intrinsic::spv_bitcast,
283 LLVMContext &Ctx =
B.getContext();
284 Type *I8Ty = Type::getInt8Ty(Ctx);
285 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
288 buildAssignType(
B,
IntVal->getType(), IntVal);
289 unsigned NumBytes =
DL.getTypeStoreSize(Src->getType());
291 auto StoreByte = [&](
unsigned I,
Value *Shifted) {
293 buildAssignType(
B, I8Ty, Byte);
294 Value *Ptr = gepByteOffset(
B, Dst,
I);
295 StoreInst *
SI =
B.CreateStore(Byte, Ptr);
300 StoreByte(0, IntVal);
302 for (
unsigned I = 1;
I < NumBytes; ++
I) {
304 B.CreateLShr(IntVal, ConstantInt::get(
IntVal->getType(), 8 *
I));
305 StoreByte(
I, Shifted);
311 LLVMContext &Ctx =
B.getContext();
312 Type *I8Ty = Type::getInt8Ty(Ctx);
313 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
314 unsigned NumBytes =
DL.getTypeStoreSize(AccessTy);
318 for (
unsigned I = 0;
I < NumBytes; ++
I) {
319 Value *Ptr = gepByteOffset(
B, Src,
I);
320 LoadInst *LI =
B.CreateLoad(I8Ty, Ptr);
322 buildAssignType(
B, I8Ty, LI);
324 buildAssignType(
B, IntTy, Extended);
329 Value *Shifted =
B.CreateShl(Extended, ConstantInt::get(IntTy, 8 *
I));
330 buildAssignType(
B, IntTy, Shifted);
331 IntVal =
B.CreateOr(IntVal, Shifted);
333 buildAssignType(
B, IntTy, IntVal);
337 if (Result != IntVal)
338 buildAssignType(
B, AccessTy, Result);
346 Value *OriginalPtr) {
347 Type *OriginalElemTy = GR->findDeducedElementType(OriginalPtr);
348 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
349 if (OriginalElemTy && OriginalElemTy == Type::getInt8Ty(
B.getContext()) &&
357 Value *CastedPtr, LoadInst *IllegalLoad) {
358 Type *CastedElemTy = GR->findDeducedElementType(CastedPtr);
359 if (!CastedElemTy || CastedElemTy != AccessTy)
363 if (shouldReinterpretByteWise(
B, AccessTy, OriginalPtr)) {
364 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
367 unsigned ElemSize =
DL.getTypeStoreSize(VT->getElementType());
368 SmallVector<Value *, 4> LoadedElements;
369 for (
unsigned I = 0;
I < VT->getNumElements(); ++
I) {
370 Value *ElemPtr = gepByteOffset(
B, OriginalPtr,
I * ElemSize);
371 LoadedElements.
push_back(loadScalarFromByteLayout(
372 B, VT->getElementType(), ElemPtr,
375 Loaded = buildVectorFromLoadedElements(
B, VT, LoadedElements);
377 Loaded = loadScalarFromByteLayout(
B, AccessTy, OriginalPtr, Alignment);
378 buildAssignType(
B, AccessTy, Loaded);
380 GR->replaceAllUsesWith(IllegalLoad, Loaded,
true);
381 DeadInstructions.push_back(IllegalLoad);
385 GR->buildAssignPtr(
B, AccessTy, OriginalPtr);
386 LoadInst *LI =
B.CreateLoad(AccessTy, OriginalPtr);
388 buildAssignType(
B, AccessTy, LI);
389 GR->replaceAllUsesWith(IllegalLoad, LI,
true);
390 DeadInstructions.push_back(IllegalLoad);
395 Value *CastedPtr,
Value *StoreSrc, Align Alignment) {
396 Type *CastedElemTy = GR->findDeducedElementType(CastedPtr);
397 if (!CastedElemTy || CastedElemTy != AccessTy)
400 if (shouldReinterpretByteWise(
B, AccessTy, OriginalPtr)) {
401 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
403 unsigned ElemSize =
DL.getTypeStoreSize(VT->getElementType());
404 for (
unsigned I = 0;
I < VT->getNumElements(); ++
I) {
405 Value *Elem = extractScalarFromVector(
B, StoreSrc,
I);
406 Value *ElemPtr = gepByteOffset(
B, OriginalPtr,
I * ElemSize);
407 storeScalarToByteLayout(
B, Elem, ElemPtr,
411 storeScalarToByteLayout(
B, StoreSrc, OriginalPtr, Alignment);
416 GR->buildAssignPtr(
B, AccessTy, OriginalPtr);
417 StoreInst *
SI =
B.CreateStore(StoreSrc, OriginalPtr);
418 SI->setAlignment(Alignment);
426 LoadInst *IllegalLoad,
Value *CastedPtr) {
427 auto ResultOpt = getPointerToFirstCompatibleType(
430 if (tryReinterpretLoad(
B, ElementType, Source, CastedPtr, IllegalLoad))
433 "Could not find compatible memory layout.");
435 auto [
GEP, CurrentTy] = *ResultOpt;
443 if (ElementType == CurrentTy) {
444 LoadInst *LI =
B.CreateLoad(ElementType,
GEP);
446 buildAssignType(
B, ElementType, LI);
450 return loadVectorFromVector(
B, SVT, DVT,
GEP, IllegalLoad->
getAlign());
451 if (
SAT && DVT &&
SAT->getElementType() == DVT->getElementType())
452 return loadVectorFromArray(
B, DVT,
GEP, IllegalLoad->
getAlign());
453 if (MAT && DVT && MAT->getElementType() == DVT->getElementType())
454 return loadVectorFromMatrixArray(
B, DVT,
GEP, MAT,
461 buildVectorFromLoadedElements(
IRBuilder<> &
B, FixedVectorType *TargetType,
462 SmallVector<Value *, 4> &LoadedElements) {
466 bool CanUseAnyVectorRank = TM.getSubtargetImpl()->canUseExtension(
467 SPIRV::Extension::SPV_EXT_long_vector);
468 if (
TargetType->getNumElements() == 1 && !CanUseAnyVectorRank) {
470 Value *NewVector =
B.CreateIntrinsic(
472 buildAssignType(
B, TargetType, NewVector);
478 buildAssignType(
B, TargetType, NewVector);
486 NewVector =
B.CreateIntrinsic(Intrinsic::spv_insertelt, {
Types}, {
Args});
487 buildAssignType(
B, TargetType, NewVector);
495 Value *Source, FixedVectorType *ArrElemVecTy,
496 Align OriginalAlign) {
499 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
500 uint64_t ArrElemVecSize =
DL.getTypeAllocSize(ArrElemVecTy);
502 SmallVector<Value *, 4> LoadedElements;
505 unsigned ArrayIndex =
I / ScalarsPerArrayElement;
506 unsigned ElementIndexInArrayElem =
I % ScalarsPerArrayElement;
508 std::array<Value *, 4>
Args = {
509 B.getInt1(
false),
Source,
B.getInt32(0),
510 ConstantInt::get(
B.getInt32Ty(), ArrayIndex)};
511 auto *ElementPtr =
B.CreateIntrinsic(Intrinsic::spv_gep, {
Types}, {
Args});
512 GR->buildAssignPtr(
B, ArrElemVecTy, ElementPtr);
513 LoadInst *LoadVec =
B.CreateLoad(ArrElemVecTy, ElementPtr);
516 buildAssignType(
B, ArrElemVecTy, LoadVec);
517 LoadedElements.
push_back(makeExtractElement(
B, TargetElemTy, LoadVec,
518 ElementIndexInArrayElem));
520 return buildVectorFromLoadedElements(
B, TargetType, LoadedElements);
525 Value *Source, Align OriginalAlign) {
527 SmallVector<Value *, 4> LoadedElements;
529 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
533 std::array<Value *, 4>
Args = {
B.getInt1(
false),
Source,
535 ConstantInt::get(
B.getInt32Ty(),
I)};
536 auto *ElementPtr =
B.CreateIntrinsic(Intrinsic::spv_gep, {
Types}, {
Args});
537 GR->buildAssignPtr(
B,
TargetType->getElementType(), ElementPtr);
540 LoadInst *
Load =
B.CreateLoad(
TargetType->getElementType(), ElementPtr);
545 return buildVectorFromLoadedElements(
B, TargetType, LoadedElements);
550 Value *DstArrayPtr, ArrayType *ArrTy,
556 unsigned SrcNumElements = SrcVecTy->getNumElements();
558 SrcNumElements % ScalarsPerArrayElement == 0 &&
559 "Source vector size must be a multiple of array element vector size");
563 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
564 uint64_t ArrElemVecSize =
DL.getTypeAllocSize(ArrElemVecTy);
566 for (
unsigned I = 0;
I < SrcNumElements;
I += ScalarsPerArrayElement) {
567 unsigned ArrayIndex =
I / ScalarsPerArrayElement;
569 std::array<Value *, 4>
Args = {
570 B.getInt1(
false), DstArrayPtr,
B.getInt32(0),
571 ConstantInt::get(
B.getInt32Ty(), ArrayIndex)};
572 auto *ElementPtr =
B.CreateIntrinsic(Intrinsic::spv_gep, {
Types}, {
Args});
573 GR->buildAssignPtr(
B, ArrElemVecTy, ElementPtr);
577 for (
unsigned J = 0; J < ScalarsPerArrayElement; ++J)
578 Elements.push_back(makeExtractElement(
B, ElemTy, SrcVector,
I + J));
581 Value *Vec = buildVectorFromLoadedElements(
B, ArrElemVecTy, Elements);
582 StoreInst *
SI =
B.CreateStore(Vec, ElementPtr);
589 Value *DstArrayPtr, ArrayType *ArrTy,
592 Type *ElemTy = ArrTy->getElementType();
595 assert(VecTy->getElementType() == ElemTy &&
596 "Element types of array and vector must be the same.");
599 const DataLayout &
DL =
B.GetInsertBlock()->getModule()->getDataLayout();
600 uint64_t ElemSize =
DL.getTypeAllocSize(ElemTy);
602 for (
unsigned I = 0,
E = VecTy->getNumElements();
I <
E; ++
I) {
604 std::array<Value *, 4>
Args = {
B.getInt1(
false), DstArrayPtr,
606 ConstantInt::get(
B.getInt32Ty(),
I)};
607 auto *ElementPtr =
B.CreateIntrinsic(Intrinsic::spv_gep, {
Types}, {
Args});
608 GR->buildAssignPtr(
B, ElemTy, ElementPtr);
611 bool CanUseAnyVectorRank = TM.getSubtargetImpl()->canUseExtension(
612 SPIRV::Extension::SPV_EXT_long_vector);
613 Value *Element = (
E == 1 && !CanUseAnyVectorRank)
615 : makeExtractElement(
B, ElemTy, SrcVector,
I);
616 StoreInst *
SI =
B.CreateStore(Element, ElementPtr);
624 Value *OriginalOperand) {
625 Type *ToTy = GR->findDeducedElementType(CastedOperand);
626 B.SetInsertPoint(LI);
629 buildLegalizedLoad(
B, ToTy, OriginalOperand, LI, CastedOperand);
633 GR->replaceAllUsesWith(LI, Output,
true);
634 DeadInstructions.push_back(LI);
640 Type *Int32Ty = Type::getInt32Ty(
B.getContext());
644 Value *NewI =
B.CreateIntrinsic(Intrinsic::spv_insertelt, {
Types}, {
Args});
645 buildAssignType(
B,
Vector->getType(), NewI);
653 Type *Int32Ty = Type::getInt32Ty(
B.getContext());
656 Value *NewI =
B.CreateIntrinsic(Intrinsic::spv_extractelt, {
Types}, {
Args});
657 buildAssignType(
B, ElementType, NewI);
667 Type *ElemTy = VecTy->getElementType();
668 if (VecTy->getNumElements() == 1) {
670 B.CreateIntrinsic(Intrinsic::spv_bitcast, {ElemTy, VecTy}, {
Vector});
671 buildAssignType(
B, ElemTy, Scalar);
674 return makeExtractElement(
B, ElemTy,
Vector, Index);
682 FixedVectorType *DstType =
691 [[maybe_unused]]
auto dstBitWidth =
693 [[maybe_unused]]
auto srcBitWidth =
695 assert(dstBitWidth == srcBitWidth &&
696 "Unsupported bitcast between vectors of different sizes.");
699 B.CreateIntrinsic(Intrinsic::spv_bitcast, {DstType, SrcType}, {Src});
700 buildAssignType(
B, DstType, Src);
703 StoreInst *
SI =
B.CreateStore(Src, Dst);
704 SI->setAlignment(Alignment);
709 LoadInst *LI =
B.CreateLoad(DstType, Dst);
711 Value *OldValues = LI;
712 buildAssignType(
B, OldValues->
getType(), OldValues);
715 Value *Element = extractScalarFromVector(
B, Src,
I);
716 OldValues = makeInsertElement(
B, OldValues, Element,
I);
719 StoreInst *
SI =
B.CreateStore(OldValues, Dst);
720 SI->setAlignment(Alignment);
727 Align Alignment,
Value *CastedPtr,
728 Instruction *IllegalStore) {
729 auto ResultOpt = getPointerToFirstCompatibleType(
B, Dst, Dst->getType(),
730 Src->getType(),
true);
732 if (tryReinterpretStore(
B, Src->getType(), Dst, CastedPtr, Src,
736 "Could not find compatible memory layout.");
738 auto [
GEP, CurrentTy] = *ResultOpt;
746 if (Src->getType() == CurrentTy) {
747 StoreInst *
SI =
B.CreateStore(Src,
GEP);
748 SI->setAlignment(Alignment);
752 storeVectorFromVector(
B, Src,
GEP, Alignment);
755 if (DAT && SVT && SVT->getElementType() == DAT->getElementType()) {
756 storeArrayFromVector(
B, Src,
GEP, DAT, Alignment);
759 if (DMAT && SVT && DMAT->getElementType() == SVT->getElementType()) {
760 storeMatrixArrayFromVector(
B, Src,
GEP, DAT, Alignment);
770 Value *Dst,
Value *CastedOperand, Align Alignment) {
771 B.SetInsertPoint(IllegalStore);
772 buildLegalizedStore(
B, Src, Dst, Alignment, CastedOperand, IllegalStore);
773 DeadInstructions.push_back(IllegalStore);
776 void legalizePointerCast(IntrinsicInst *
II) {
778 Value *OriginalOperand =
II->getOperand(0);
781 std::vector<Value *>
Users;
782 for (Use &U :
II->uses())
783 Users.push_back(
U.getUser());
787 transformLoad(
B, LI, CastedOperand, OriginalOperand);
792 transformStore(
B, SI,
SI->getValueOperand(), OriginalOperand,
793 CastedOperand,
SI->getAlign());
798 if (Intrin->getIntrinsicID() == Intrinsic::spv_assign_ptr_type) {
799 DeadInstructions.push_back(Intrin);
803 if (Intrin->getIntrinsicID() == Intrinsic::spv_gep) {
804 GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
809 if (Intrin->getIntrinsicID() == Intrinsic::spv_store) {
813 transformStore(
B, Intrin, Intrin->getArgOperand(0), OriginalOperand,
814 CastedOperand, Alignment);
822 DeadInstructions.push_back(
II);
826 SPIRVLegalizePointerCastImpl(
const SPIRVTargetMachine &TM) : TM(TM) {}
829 const SPIRVSubtarget &
ST = TM.getSubtarget<SPIRVSubtarget>(
F);
830 GR =
ST.getSPIRVGlobalRegistry();
831 DeadInstructions.clear();
833 std::vector<IntrinsicInst *> WorkList;
837 if (
II &&
II->getIntrinsicID() == Intrinsic::spv_ptrcast)
838 WorkList.push_back(
II);
842 for (IntrinsicInst *
II : WorkList)
843 legalizePointerCast(
II);
845 for (Instruction *
I : DeadInstructions)
846 I->eraseFromParent();
848 return DeadInstructions.size() != 0;
852 const SPIRVTargetMachine &TM;
853 SPIRVGlobalRegistry *GR =
nullptr;
854 std::vector<Instruction *> DeadInstructions;
857class SPIRVLegalizePointerCastLegacy :
public FunctionPass {
860 SPIRVLegalizePointerCastLegacy(
const SPIRVTargetMachine &TM)
861 : FunctionPass(ID), TM(TM) {}
864 return SPIRVLegalizePointerCastImpl(TM).run(
F);
868 const SPIRVTargetMachine &TM;
878char SPIRVLegalizePointerCastLegacy::ID = 0;
880 "SPIRV legalize pointer cast pass",
false,
false)
883 return new SPIRVLegalizePointerCastLegacy(*TM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runOnFunction(Function &F, bool PostInlining)
iv Induction Variable Users
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
void setCallingConv(CallingConv::ID CC)
void setAttributes(AttributeList A)
Set the attributes for this call.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
void setAlignment(Align Align)
Type * getPointerOperandType() const
Align getAlign() const
Return the alignment of the access that is being performed.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
void push_back(const T &Elt)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Type * getType() const
All values are typed, get the type of this value.
Type * getElementType() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
ElementType
The element type of an SRV or UAV resource.
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.
@ Load
The value being inserted comes from a load (InsertElement only).
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
FunctionPass * createSPIRVLegalizePointerCastPass(SPIRVTargetMachine *TM)