28#include "llvm/IR/IntrinsicsSPIRV.h"
43 if (LI->getType()->isAggregateType())
50 return PType->getAddressSpace();
52 return PType->getAddressSpace();
55 return ExtTy->getIntParameter(0);
62 case SPIRV::StorageClass::Uniform:
63 case SPIRV::StorageClass::PushConstant:
64 case SPIRV::StorageClass::StorageBuffer:
65 case SPIRV::StorageClass::PhysicalStorageBufferEXT:
67 case SPIRV::StorageClass::UniformConstant:
68 case SPIRV::StorageClass::Input:
69 case SPIRV::StorageClass::Output:
70 case SPIRV::StorageClass::Workgroup:
71 case SPIRV::StorageClass::CrossWorkgroup:
72 case SPIRV::StorageClass::Private:
73 case SPIRV::StorageClass::Function:
74 case SPIRV::StorageClass::Generic:
75 case SPIRV::StorageClass::AtomicCounter:
76 case SPIRV::StorageClass::Image:
77 case SPIRV::StorageClass::CallableDataNV:
78 case SPIRV::StorageClass::IncomingCallableDataNV:
79 case SPIRV::StorageClass::RayPayloadNV:
80 case SPIRV::StorageClass::HitAttributeNV:
81 case SPIRV::StorageClass::IncomingRayPayloadNV:
82 case SPIRV::StorageClass::ShaderRecordBufferNV:
83 case SPIRV::StorageClass::CodeSectionINTEL:
84 case SPIRV::StorageClass::DeviceOnlyINTEL:
85 case SPIRV::StorageClass::HostOnlyINTEL:
92 : DL(DL), Bound(0),
CurMF(nullptr) {}
94void SPIRVGlobalRegistry::constrainSelectedInstRegOperands(
98 *ST.getRegBankInfo());
112 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
122 VRegToTypeMap[&MF][VReg] = SpirvType;
136 return createConstOrTypeAtFunctionEntry(
137 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
138 return MIRBuilder.
buildInstr(SPIRV::OpTypeBool)
143unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(
unsigned Width)
const {
145 if (
ST.canUseExtension(
146 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
147 (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)))
151 else if (Width <= 16)
153 else if (Width <= 32)
155 else if (Width <= 64)
157 else if (Width <= 128)
162SPIRVTypeInst SPIRVGlobalRegistry::getOpTypeInt(
unsigned Width,
165 Width = adjustOpTypeIntWidth(Width);
166 const SPIRVSubtarget &
ST =
168 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
170 if (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
172 .
addImm(SPIRV::Extension::SPV_INTEL_int4);
174 .
addImm(SPIRV::Capability::Int4TypeINTEL);
177 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers)) {
179 .
addImm(SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
181 .
addImm(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
183 return MIRBuilder.
buildInstr(SPIRV::OpTypeInt)
186 .
addImm(IsSigned ? 1 : 0);
191SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
193 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
195 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
202SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
204 SPIRV::FPEncoding::FPEncoding FPEncode) {
205 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
207 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
215 return createConstOrTypeAtFunctionEntry(
216 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
217 return MIRBuilder.
buildInstr(SPIRV::OpTypeVoid)
242 "Cannot invalidate aliasing instructions.");
243 assert(
MI->getOpcode() != SPIRV::OpFunction &&
244 "Cannot invalidate OpFunction.");
246 if (
MI->getOpcode() == SPIRV::OpFunctionCall) {
248 auto It = ForwardCalls.find(
F);
249 if (It != ForwardCalls.end()) {
250 It->second.erase(
MI);
251 if (It->second.empty())
252 ForwardCalls.erase(It);
258 auto It = LastInsertedTypeMap.find(MF);
259 if (It != LastInsertedTypeMap.end() && It->second ==
MI)
260 LastInsertedTypeMap.erase(MF);
265const MachineInstr *SPIRVGlobalRegistry::createConstOrTypeAtFunctionEntry(
272 auto LastInsertedType = LastInsertedTypeMap.find(
CurMF);
273 if (LastInsertedType != LastInsertedTypeMap.end()) {
274 auto It = LastInsertedType->second->getIterator();
278 if (It->getParent() != NewMBB)
279 InsertAt = oldInsertPoint->getParent() == NewMBB
282 else if (It->getNextNode())
283 InsertAt = It->getNextNode()->getIterator();
289 auto Result = LastInsertedTypeMap.try_emplace(
CurMF,
nullptr);
291 LastInsertedType = Result.first;
294 MachineInstr *ConstOrType =
Op(MIRBuilder);
298 LastInsertedType->second = ConstOrType;
301 while (
auto *
Next = LastInsertedType->second->getNextNode()) {
302 unsigned Opc =
Next->getOpcode();
303 if (
Opc == SPIRV::OpTypeStructContinuedINTEL ||
304 Opc == SPIRV::OpConstantCompositeContinuedINTEL ||
305 Opc == SPIRV::OpSpecConstantCompositeContinuedINTEL ||
306 Opc == SPIRV::OpCompositeConstructContinuedINTEL)
307 LastInsertedType->second =
Next;
317SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
SPIRVTypeInst ElemType,
319 assert(NumElems >= 2 &&
"SPIR-V OpTypeVector requires at least 2 components");
324 SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
328 "Vector of pointers requires SPV_INTEL_masked_gather_scatter "
333 [[maybe_unused]]
auto EleOpc = ElemType->
getOpcode();
334 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
335 EleOpc == SPIRV::OpTypeBool) &&
336 "Invalid vector element type");
339 return createConstOrTypeAtFunctionEntry(
340 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
341 return MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
353 auto *
const CF = ConstantFP::get(Ctx, Val);
355 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
356 MI->getOpcode() == SPIRV::OpConstantF))
357 return MI->getOperand(0).getReg();
368 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
369 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
375 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
380 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
384 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
391 constrainSelectedInstRegOperands(MIB);
403 SpvType,
TII, ZeroAsNull);
411 auto *
const CI = ConstantInt::get(
414 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
415 MI->getOpcode() == SPIRV::OpConstantI))
416 return MI->getOperand(0).getReg();
427 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
428 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
434 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
440 : SPIRV::OpConstantTrue)
443 }
else if (!CI->
isZero() || !ZeroAsNull) {
444 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
449 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
453 constrainSelectedInstRegOperands(MIB);
463 bool EmitIR,
bool ZeroAsNull) {
465 auto &MF = MIRBuilder.
getMF();
469 auto *
const CI = ConstantInt::get(
const_cast<IntegerType *
>(Ty), Val,
483 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
489 if (Val || !ZeroAsNull) {
490 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
495 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
499 constrainSelectedInstRegOperands(MIB);
509 auto &MF = MIRBuilder.
getMF();
513 SPIRV::AccessQualifier::ReadWrite,
true);
514 auto *
const CF = ConstantFP::get(Ctx, Val);
520 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
521 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
524 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
527 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
530 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
537Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
541 if (SpvType->
getOpcode() == SPIRV::OpTypeVector ||
542 SpvType->
getOpcode() == SPIRV::OpTypeArray) {
546 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
551 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
557Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
560 unsigned ElemCnt,
bool ZeroAsNull) {
568 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
571 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
575 MachineInstr *DepMI =
576 const_cast<MachineInstr *
>(
static_cast<const MachineInstr *
>(SpvType));
578 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
579 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
580 MachineInstrBuilder MIB;
582 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
585 for (
unsigned i = 0; i < ElemCnt; ++i)
588 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
592 constrainSelectedInstRegOperands(MIB);
605 I, SpvType,
TII, ZeroAsNull);
615 "Expected vector type for constant vector creation");
619 "Expected integer element type for APInt constant vector");
624 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
639 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
643 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
655 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
670 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(I64Ty, Num)});
671 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
675Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
692 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
698 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
701 for (
unsigned i = 0; i < ElemCnt; ++i)
706 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
721 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
725 return getOrCreateIntCompositeOrNull(
726 Val, MIRBuilder, SpvType, EmitIR, ConstVec, BW,
744 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
745 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
748 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
750 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
760 unsigned Param,
unsigned FilerMode,
773 MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
784 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
786 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
795 GVar = M->getGlobalVariable(Name);
796 if (GVar ==
nullptr) {
820 if (&GVBuilder.
getMBB() != &EntryBB)
825 const bool UseUntypedPointers =
826 BaseType->getOpcode() == SPIRV::OpTypeUntypedPointerKHR;
827 const unsigned VariableOpcode =
828 UseUntypedPointers ? SPIRV::OpUntypedVariableKHR : SPIRV::OpVariable;
830 auto MIB = GVBuilder.
buildInstr(VariableOpcode)
837 if (UseUntypedPointers) {
841 SPIRV::AccessQualifier::ReadWrite,
847 "Could not deduce the data type of untyped global variable '" +
853 SPIRV::AccessQualifier::ReadWrite,
863 if (IsInstSelector) {
864 constrainSelectedInstRegOperands(MIB);
872 auto MRI = MIRBuilder.
getMRI();
873 if (Reg != ResVReg) {
876 MRI->setType(Reg, RegLLTy);
895 if (IsConst && !ST.isShader())
900 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
905 {
static_cast<uint32_t>(*LinkageType)}, Name);
907 SPIRV::BuiltIn::BuiltIn BuiltInId;
910 {
static_cast<uint32_t>(BuiltInId)});
916 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
933 std::nullopt, MIRBuilder,
false);
935 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
936 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
945 bool ExplicitLayoutRequired,
948 "Invalid array element type");
956 ArrayType = createConstOrTypeAtFunctionEntry(
958 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
969 ArrayType = createConstOrTypeAtFunctionEntry(
970 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
971 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
977 if (!
ST.isShader()) {
979 "Runtime arrays are not allowed in non-shader "
983 ArrayType = createConstOrTypeAtFunctionEntry(
984 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
985 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
993 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
1001SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
1006 return createConstOrTypeAtFunctionEntry(
1007 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1017 SPIRV::AccessQualifier::AccessQualifier AccQual,
1019 Type *OriginalElementType =
nullptr;
1020 uint64_t TotalSize = 0;
1022 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
1023 OriginalElementType, MIRBuilder, AccQual,
1024 Decorator !=
nullptr, EmitIR);
1025 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
1026 Decorator !=
nullptr,
1030 const SPIRVSubtarget &
ST =
1033 constexpr unsigned MaxWordCount = UINT16_MAX;
1036 size_t MaxNumElements = MaxWordCount - 2;
1037 size_t SPIRVStructNumElements = NumElements;
1038 if (NumElements > MaxNumElements) {
1040 SPIRVStructNumElements = MaxNumElements;
1041 MaxNumElements = MaxWordCount - 1;
1044 for (
const auto &Elem : Ty->
elements()) {
1045 SPIRVTypeInst ElemTy = findSPIRVType(
1047 Decorator !=
nullptr, EmitIR);
1049 "Invalid struct element type");
1058 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1059 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1062 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1063 MIBStruct.
addUse(FieldTypes[
I]);
1064 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1065 I += MaxNumElements) {
1067 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1068 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1069 MIBCont.
addUse(FieldTypes[J]);
1075 Decorator(SPVType->defs().begin()->getReg());
1082 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1088 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1091 const SPIRVSubtarget &
ST =
1099 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1101 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1103 .
addImm(
static_cast<uint32_t
>(SC))
1112 const SPIRVSubtarget *
ST =
1113 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1114 if (Ty->isVarArg() &&
ST->isShader()) {
1116 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1117 Fn,
"SPIR-V shaders do not support variadic functions",
1120 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1122 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1125 for (
auto &ArgType : ArgTypes)
1139 add(Ty,
false, NewMI);
1140 return finishCreatingSPIRVType(Ty, NewMI);
1145 SPIRV::AccessQualifier::AccessQualifier AccQual,
1146 bool ExplicitLayoutRequired,
bool EmitIR) {
1149 FVT && FVT->getNumElements() == 1)
1150 return findSPIRVType(FVT->getElementType(), MIRBuilder, AccQual,
1151 ExplicitLayoutRequired, EmitIR);
1152 Ty = adjustIntTypeByWidth(Ty);
1155 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1157 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1159 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1164 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1165 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1166 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1167 return SpirvType->
uses().
begin()->getReg();
1168 return SpirvType->
defs().
begin()->getReg();
1179const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1181 unsigned SrcBitWidth = IType->getBitWidth();
1182 if (SrcBitWidth > 1) {
1183 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1194 SPIRV::AccessQualifier::AccessQualifier AccQual,
1195 bool ExplicitLayoutRequired,
bool EmitIR) {
1197 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1199 if (
const MachineInstr *
MI =
1200 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1204 const unsigned Width = IType->getBitWidth();
1205 return Width == 1 ? getOpTypeBool(MIRBuilder)
1206 : getOpTypeInt(Width, MIRBuilder,
false);
1213 SPIRV::FPEncoding::BFloat16KHR);
1219 return getOpTypeVoid(MIRBuilder);
1223 AccQual, ExplicitLayoutRequired, EmitIR);
1229 AccQual, ExplicitLayoutRequired, EmitIR);
1231 ExplicitLayoutRequired, EmitIR);
1234 if (SType->isOpaque())
1235 return getOpTypeOpaque(SType, MIRBuilder);
1238 if (ExplicitLayoutRequired) {
1239 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1240 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1244 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1248 SPIRVTypeInst RetTy =
1249 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1250 ExplicitLayoutRequired, EmitIR);
1252 for (
const auto &ParamTy : FType->params())
1253 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1254 ExplicitLayoutRequired, EmitIR));
1255 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1261 const SPIRVSubtarget *
ST =
1262 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1265 SPIRVTypeInst SpvElementType =
nullptr;
1268 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1281 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1284 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1292 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1293 bool ExplicitLayoutRequired,
bool EmitIR) {
1298 TypesInProcessing.insert(Ty);
1299 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1300 ExplicitLayoutRequired, EmitIR);
1301 TypesInProcessing.erase(Ty);
1308 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1314 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1316 add(Ty, ExplicitLayoutRequired, SpirvType);
1329 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1330 if (t != VRegToTypeMap.end()) {
1331 auto tt = t->second.find(VReg);
1332 if (tt != t->second.end())
1348 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1349 bool ExplicitLayoutRequired,
bool EmitIR) {
1352 FVT && FVT->getNumElements() == 1)
1354 ExplicitLayoutRequired, EmitIR);
1359 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1361 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1371 TypesInProcessing.clear();
1372 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1373 ExplicitLayoutRequired, EmitIR);
1375 for (
auto &
CU : ForwardPointerTypes) {
1378 bool PtrNeedsLayout =
false;
1379 const Type *Ty2 =
CU.first;
1381 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1384 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1389 ForwardPointerTypes.clear();
1394 unsigned TypeOpcode)
const {
1396 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1397 return Type->getOpcode() == TypeOpcode;
1401 unsigned TypeOpcode)
const {
1403 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1404 if (
Type->getOpcode() == TypeOpcode)
1406 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1407 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1409 return ScalarType->
getOpcode() == TypeOpcode;
1415 switch (
Type->getOpcode()) {
1416 case SPIRV::OpTypeImage:
1417 case SPIRV::OpTypeSampler:
1418 case SPIRV::OpTypeSampledImage:
1420 case SPIRV::OpTypeStruct:
1421 return hasBlockDecoration(
Type);
1436 return Type->getOpcode() == SPIRV::OpTypeVector
1437 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1445 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1446 ?
Type->getOperand(1).getReg()
1447 :
Type->getOperand(0).getReg();
1458 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1459 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1461 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1463 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1471 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1472 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1480 if (ElemType && ElemType->
getOpcode() == SPIRV::OpTypeFunction)
1482 auto It = SPIRVToLLVMType.find(ElemType);
1483 return It != SPIRVToLLVMType.end() && It->second &&
1490 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers) &&
1497 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1507 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1514 if (!Type1 || !Type2)
1527 return Bits1 > 0 && Bits1 == Bits2;
1530SPIRV::StorageClass::StorageClass
1534 "Pointer type is expected");
1538SPIRV::StorageClass::StorageClass
1540 return static_cast<SPIRV::StorageClass::StorageClass
>(
1546 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1557 ExplicitLayoutRequired, EmitIr);
1560 SPIRV::Decoration::Block, {});
1564 SPIRV::Decoration::NonWritable, 0, {});
1568 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1580 finishCreatingSPIRVType(
T, R);
1587 const auto SC = SPIRV::StorageClass::PushConstant;
1596 T, MIRBuilder, SPIRV::AccessQualifier::None,
1600 SPIRV::Decoration::Block, {});
1614 assert(ST->getNumElements() == Offsets.size());
1627 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1628 std::move(Decorator), EmitIr);
1629 add(
Key, SPIRVStructType);
1630 return SPIRVStructType;
1635 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1638 "SPIR-V image builtin type must have sampled type parameter!");
1641 SPIRV::AccessQualifier::ReadWrite,
true);
1644 "Invalid number of parameters for SPIR-V image builtin!");
1646 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1647 SPIRV::AccessQualifier::None;
1649 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1650 ? SPIRV::AccessQualifier::WriteOnly
1651 : SPIRV::AccessQualifier::AccessQualifier(
1657 MIRBuilder, SampledType,
1663 SPIRVToLLVMType[R] = ExtensionType;
1671 SPIRV::ImageFormat::ImageFormat ImageFormat,
1672 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1674 Depth, Arrayed, Multisampled, Sampled,
1675 ImageFormat, AccessQual);
1678 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1690 if (AccessQual != SPIRV::AccessQualifier::None)
1704 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1706 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1715 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1719 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1721 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1734 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1736 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1751 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1753 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1766 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1768 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1775 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1777 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1779 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1787 add(ExtensionType,
false, NewMI);
1795 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1799 add(Ty,
false, NewMI);
1809 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1815 if (Operand.isReg()) {
1816 MIB.
addUse(Operand.getReg());
1817 }
else if (Operand.isImm()) {
1818 MIB.
addImm(Operand.getImm());
1823 add(Ty,
false, NewMI);
1830 SPIRV::StorageClass::StorageClass SC,
1831 SPIRV::AccessQualifier::AccessQualifier AQ) {
1832 unsigned VecElts = 0;
1839 MIRBuilder, AQ,
false,
true);
1860 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1877 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1881SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1892 unsigned SPIRVOPcode,
Type *Ty) {
1897 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1900 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1904 if (!Ty->isFloatTy()) {
1905 return NewTypeMI.addImm(0);
1910 add(Ty,
false, NewMI);
1911 return finishCreatingSPIRVType(Ty, NewMI);
1951 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1962 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1965 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1968 add(Ty,
false, NewMI);
1969 return finishCreatingSPIRVType(Ty, NewMI);
1978 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1986 assert(NumElements >= 2 &&
"SPIR-V vectors must have at least 2 components");
1994 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1997 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
2002 add(Ty,
false, NewMI);
2003 return finishCreatingSPIRVType(Ty, NewMI);
2015 SPIRV::StorageClass::StorageClass SC,
bool ForceTyped) {
2018 .canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2020 F.getContext().diagnose(
2022 "Function used as a data pointer requires "
2023 "SPV_INTEL_function_pointers extension",
2028 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2031 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC,
2036 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2038 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2045 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2050 SPIRV::StorageClass::StorageClass SC) {
2055 (R->getOpcode() == SPIRV::OpTypeUntypedPointerKHR ||
2057 "The base type was not correctly laid out for the given storage class.");
2061SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2063 SPIRV::StorageClass::StorageClass SC,
bool ForceTyped) {
2076 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2080 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2086 return finishCreatingSPIRVType(Ty, NewMI);
2093 assert(ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers) &&
2094 !ST.isShader() &&
"Untyped pointers are not available");
2103 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2107 MIRBuilder.
getTII().
get(SPIRV::OpTypeUntypedPointerKHR))
2112 return finishCreatingSPIRVType(Ty, NewMI);
2125 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2126 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2132 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2135 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2138 constrainSelectedInstRegOperands(MIB);
2149 case SPIRV::OpTypeFloat:
2150 return &SPIRV::fIDRegClass;
2151 case SPIRV::OpTypePointer:
2152 return &SPIRV::pIDRegClass;
2153 case SPIRV::OpTypeVector: {
2155 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2156 if (ElemOpcode == SPIRV::OpTypeFloat)
2157 return &SPIRV::vfIDRegClass;
2158 if (ElemOpcode == SPIRV::OpTypePointer)
2159 return &SPIRV::vpIDRegClass;
2160 return &SPIRV::viIDRegClass;
2163 return &SPIRV::iIDRegClass;
2168 static_cast<SPIRV::StorageClass::StorageClass
>(
2173 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2175 case SPIRV::OpTypeInt:
2176 case SPIRV::OpTypeFloat:
2177 case SPIRV::OpTypeBool:
2179 case SPIRV::OpTypePointer:
2180 case SPIRV::OpTypeUntypedPointerKHR:
2182 case SPIRV::OpTypeVector: {
2185 switch (ElemType ? ElemType->
getOpcode() : 0) {
2186 case SPIRV::OpTypePointer:
2187 case SPIRV::OpTypeUntypedPointerKHR:
2190 case SPIRV::OpTypeInt:
2191 case SPIRV::OpTypeFloat:
2192 case SPIRV::OpTypeBool:
2214 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2221 if (ScopeMD->getNumOperands() < 2)
2227 auto D = AliasInstMDMap.find(DomainMD);
2228 if (
D != AliasInstMDMap.end())
2235 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2237 auto S = AliasInstMDMap.find(ScopeMD);
2238 if (S != AliasInstMDMap.end())
2241 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2246 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2254 for (
auto *Scope : ScopeList)
2255 MIB.
addUse(Scope->getOperand(0).getReg());
2257 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2263 const MDNode *AliasingListMD) {
2290 B.CreateIntrinsic(Intrinsic::spv_value_md,
2292 AssignCI =
B.CreateIntrinsicWithoutFolding(Intrinsic::fake_use, {Arg});
2295 OfType, Arg, {},
B);
2305 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2306 if (AssignPtrTyCI ==
nullptr ||
2307 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2309 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2323 Intrinsic::spv_assign_ptr_type)
2332void SPIRVGlobalRegistry::addStructOffsetDecorations(
2335 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2341void SPIRVGlobalRegistry::addArrayStrideDecorations(
2343 uint32_t SizeInBytes = DL.getTypeAllocSize(ElementType);
2350 for (
const MachineInstr &Use :
2351 Type->getMF()->getRegInfo().use_instructions(Def)) {
2352 if (
Use.getOpcode() != SPIRV::OpDecorate)
2355 if (
Use.getOperand(1).getImm() == SPIRV::Decoration::Block)
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
static constexpr Value * getValue(Ty &ValueOrUse)
Promote Memory to Register
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool storageClassRequiresExplictLayout(SPIRV::StorageClass::StorageClass SC)
static Register createTypeVReg(MachineRegisterInfo &MRI)
static bool allowEmitFakeUse(const Value *Arg)
static unsigned typeToAddressSpace(const Type *Ty)
unsigned getAS(SPIRVTypeInst SpvType)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
uint64_t getNumElements() const
Type * getElementType() const
void setArgOperand(unsigned i, Value *v)
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValue() const
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
const APInt & getValue() const
Return the constant as an APInt value reference.
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
static LLVM_ABI ConstantTargetNone * get(TargetExtType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
Module * getParent()
Get the module that this global value is contained inside of...
@ ExternalLinkage
Externally visible function.
Type * getValueType() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
Helper class to build MachineInstr.
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
LLVMContext & getContext() const
const TargetInstrInfo & getTII()
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
const DebugLoc & getDL()
Getter for DebugLoc.
MachineFunction & getMF()
Getter for the function we currently build.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineIRBuilderState & getState()
Getter for the State.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
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.
constexpr bool isValid() const
SPIRVTypeInst getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
bool isScalarOrVectorSigned(SPIRVTypeInst Type) const
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
SPIRVTypeInst getOrCreateOpTypeSampledImage(SPIRVTypeInst ImageType, MachineIRBuilder &MIRBuilder)
unsigned getNumScalarOrVectorTotalBitWidth(SPIRVTypeInst Type) const
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)
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
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)
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)
unsigned getPointerSize() const
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
LLT getRegType(SPIRVTypeInst SpvType) const
SPIRVGlobalRegistry(DataLayout DL)
void invalidateMachineInstr(MachineInstr *MI)
bool isResourceType(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder, bool EmitIR)
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)
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)
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 buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg)
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)
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)
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)
Register getOrCreateUndef(MachineInstr &I, SPIRVTypeInst SpvType, const SPIRVInstrInfo &TII)
SPIRVTypeInst getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec, const MDNode *GVarMD)
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
bool shouldUseUntypedPointer(SPIRVTypeInst ElemType, const SPIRVSubtarget &ST) const
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder)
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)
const MachineInstr * findMI(SPIRV::IRHandle Handle, const MachineFunction *MF)
bool erase(const MachineInstr *MI)
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI)
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Class to represent struct types.
ArrayRef< Type * > elements() const
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
unsigned getNumElements() const
Random access to the elements.
bool hasName() const
Return true if this is a named struct that has a non-empty name.
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
unsigned getNumIntParameters() const
Type * getTypeParameter(unsigned i) const
unsigned getNumTypeParameters() const
unsigned getIntParameter(unsigned i) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
Type * getArrayElementType() const
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
LLVM_ABI uint64_t getArrayNumElements() const
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isFP128Ty() const
Return true if this is 'fp128'.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isAggregateType() const
Return true if the type is an aggregate type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
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.
'undef' values are things that do not have specified contents.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
IRHandle handle(const Type *Ty)
IRHandle irhandle_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
IRHandle irhandle_padding()
IRHandle irhandle_vkbuffer(const Type *ElementType, StorageClass::StorageClass SC, bool IsWriteable)
IRHandle irhandle_untyped_pointer(unsigned AddressSpace)
IRHandle irhandle_sampler()
TargetExtType * parseBuiltinTypeNameToTargetExtType(std::string TypeName, LLVMContext &Context)
Translates a string representing a SPIR-V or OpenCL builtin type to a TargetExtType that can be furth...
IRHandle irhandle_event()
SPIRVTypeInst lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
IRHandle irhandle_pipe(uint8_t AQ)
IRHandle irhandle_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
unsigned getNumElements(Type *Ty)
This is an optimization pass for GlobalISel generic memory operations.
void addStringImm(StringRef Str, MCInst &Inst)
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getPointerAddressSpace(const Type *T)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
bool matchPeeledArrayPattern(const StructType *Ty, Type *&OriginalElementType, uint64_t &TotalSize)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
MetadataAsValue * buildMD(Value *Arg)
bool isTypedPointerTy(const Type *T)
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * getTypedPointerWrapper(Type *ElemTy, unsigned AS)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Type * toTypedPointer(Type *Ty)
bool isSpecialOpaqueType(const Type *Ty)
bool isPointerTy(const Type *T)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
const Type * unifyPtrType(const Type *Ty)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
std::function< void(Register)> StructOffsetDecorator
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool hasBuiltinTypePrefix(StringRef Name)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
bool isPointerTyOrWrapper(const Type *Ty)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
PoisonValue * getNormalizedPoisonValue(Type *Ty)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
MCRegisterClass TargetRegisterClass
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.