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;
127 MRI.setRegClass(Res, &SPIRV::TYPERegClass);
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(
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(
269 assert(oldInsertPoint.isValid() &&
"Builder must have insertion point set!");
273 auto LastInsertedType = LastInsertedTypeMap.find(
CurMF);
274 if (LastInsertedType != LastInsertedTypeMap.end()) {
275 auto It = LastInsertedType->second->getIterator();
279 if (It->getParent() != NewMBB)
280 InsertAt = oldInsertPoint->getParent() == NewMBB
283 else if (It->getNextNode())
284 InsertAt = It->getNextNode()->getIterator();
290 auto Result = LastInsertedTypeMap.try_emplace(
CurMF,
nullptr);
292 LastInsertedType = Result.first;
295 MachineInstr *ConstOrType =
Op(MIRBuilder);
299 LastInsertedType->second = ConstOrType;
302 while (
auto *
Next = LastInsertedType->second->getNextNode()) {
303 unsigned Opc =
Next->getOpcode();
304 if (
Opc == SPIRV::OpTypeStructContinuedINTEL ||
305 Opc == SPIRV::OpConstantCompositeContinuedINTEL ||
306 Opc == SPIRV::OpSpecConstantCompositeContinuedINTEL ||
307 Opc == SPIRV::OpCompositeConstructContinuedINTEL)
308 LastInsertedType->second =
Next;
319 bool IsLongVectorEXT) {
323 SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
327 "Vector of pointers requires SPV_INTEL_masked_gather_scatter "
332 [[maybe_unused]]
auto EleOpc = ElemType->
getOpcode();
333 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
334 EleOpc == SPIRV::OpTypeBool) &&
335 "Invalid vector element type");
338 return createConstOrTypeAtFunctionEntry(
339 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
341 IsLongVectorEXT ? SPIRV::OpTypeVectorIdEXT : SPIRV::OpTypeVector;
345 if (!IsLongVectorEXT)
346 return MIB.
addImm(NumElems);
351 Int32Ty, *
ST.getInstrInfo()));
356SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
SPIRVTypeInst ElemType,
358 assert(NumElems >= 2 &&
"SPIR-V OpTypeVector requires at least 2 components");
359 return getOpTypeVectorImpl(NumElems, ElemType, MIRBuilder);
364 assert(NumElems != 2 && NumElems != 3 && NumElems != 4 &&
366 (NumElems != 8 && NumElems != 16)) &&
367 "SPIR-V OpTypeVectorIdExt should only be used for extended vectors");
368 return getOpTypeVectorImpl(NumElems, ElemType, MIRBuilder,
true);
376 auto *
const CF = ConstantFP::get(Ctx, Val);
378 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
379 MI->getOpcode() == SPIRV::OpConstantF))
380 return MI->getOperand(0).getReg();
391 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
392 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
398 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
403 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
407 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
414 constrainSelectedInstRegOperands(MIB);
426 SpvType,
TII, ZeroAsNull);
434 auto *
const CI = ConstantInt::get(
437 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
438 MI->getOpcode() == SPIRV::OpConstantI))
439 return MI->getOperand(0).getReg();
450 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
451 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
457 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
463 : SPIRV::OpConstantTrue)
466 }
else if (!CI->
isZero() || !ZeroAsNull) {
467 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
472 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
476 constrainSelectedInstRegOperands(MIB);
486 bool EmitIR,
bool ZeroAsNull) {
488 auto &MF = MIRBuilder.
getMF();
492 auto *
const CI = ConstantInt::get(
const_cast<IntegerType *
>(Ty), Val,
501 Res =
MRI.createGenericVirtualRegister(LLTy);
502 MRI.setRegClass(Res, &SPIRV::iIDRegClass);
506 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
512 if (Val || !ZeroAsNull) {
513 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
518 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
522 constrainSelectedInstRegOperands(MIB);
532 auto &MF = MIRBuilder.
getMF();
536 SPIRV::AccessQualifier::ReadWrite,
true);
537 auto *
const CF = ConstantFP::get(Ctx, Val);
543 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
544 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
547 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
550 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
553 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
560Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
568 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
573 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
579Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
582 unsigned ElemCnt,
bool ZeroAsNull) {
590 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
593 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
597 MachineInstr *DepMI =
598 const_cast<MachineInstr *
>(
static_cast<const MachineInstr *
>(SpvType));
600 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
601 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
602 MachineInstrBuilder MIB;
604 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
607 for (
unsigned i = 0; i < ElemCnt; ++i)
610 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
614 constrainSelectedInstRegOperands(MIB);
627 I, SpvType,
TII, ZeroAsNull);
637 "Expected vector type for constant vector creation");
640 [[maybe_unused]]
const auto &ST =
I.getMF()->getSubtarget<
SPIRVSubtarget>();
644 SPIRV::Extension::SPV_INTEL_masked_gather_scatter))) &&
645 "Expected either integer element type for APInt constant vector or "
646 "pointer type if the SPV_INTEL_masked_gather_scatter extension is "
650 ConstVal = ConstantInt::get(LLVMBaseTy, Val);
660 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
675 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
679 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
691 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
706 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(I64Ty, Num)});
707 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
711Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
728 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
734 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
737 for (
unsigned i = 0; i < ElemCnt; ++i)
742 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
757 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
761 return getOrCreateIntCompositeOrNull(
762 Val, MIRBuilder, SpvType, EmitIR, ConstVec, BW,
780 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
781 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
784 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
786 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
796 unsigned Param,
unsigned FilerMode,
809 MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
820 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
822 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
831 GVar = M->getGlobalVariable(Name);
832 if (GVar ==
nullptr) {
856 if (&GVBuilder.
getMBB() != &EntryBB)
861 const bool UseUntypedPointers =
862 BaseType->getOpcode() == SPIRV::OpTypeUntypedPointerKHR;
863 const unsigned VariableOpcode =
864 UseUntypedPointers ? SPIRV::OpUntypedVariableKHR : SPIRV::OpVariable;
866 auto MIB = GVBuilder.
buildInstr(VariableOpcode)
873 if (UseUntypedPointers) {
877 SPIRV::AccessQualifier::ReadWrite,
883 "Could not deduce the data type of untyped global variable '" +
889 SPIRV::AccessQualifier::ReadWrite,
899 if (IsInstSelector) {
900 constrainSelectedInstRegOperands(MIB);
909 if (Reg != ResVReg) {
912 MRI->setType(Reg, RegLLTy);
931 if (IsConst && !ST.isShader())
936 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
941 {
static_cast<uint32_t>(*LinkageType)}, Name);
943 SPIRV::BuiltIn::BuiltIn BuiltInId;
946 {
static_cast<uint32_t>(BuiltInId)});
952 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
969 std::nullopt, MIRBuilder,
false);
971 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
972 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
981 bool ExplicitLayoutRequired,
984 "Invalid array element type");
992 ArrayType = createConstOrTypeAtFunctionEntry(
994 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
1005 ArrayType = createConstOrTypeAtFunctionEntry(
1006 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1007 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
1010 .
addUse(NumElementsVReg);
1013 if (!
ST.isShader()) {
1015 "Runtime arrays are not allowed in non-shader "
1019 ArrayType = createConstOrTypeAtFunctionEntry(
1020 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1021 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
1029 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
1037SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
1042 return createConstOrTypeAtFunctionEntry(
1043 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1053 SPIRV::AccessQualifier::AccessQualifier AccQual,
1055 Type *OriginalElementType =
nullptr;
1058 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
1059 OriginalElementType, MIRBuilder, AccQual,
1060 Decorator !=
nullptr, EmitIR);
1061 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
1062 Decorator !=
nullptr,
1066 const SPIRVSubtarget &
ST =
1069 constexpr unsigned MaxWordCount = UINT16_MAX;
1072 size_t MaxNumElements = MaxWordCount - 2;
1073 size_t SPIRVStructNumElements = NumElements;
1074 if (NumElements > MaxNumElements) {
1076 SPIRVStructNumElements = MaxNumElements;
1077 MaxNumElements = MaxWordCount - 1;
1080 for (
const auto &Elem : Ty->
elements()) {
1081 SPIRVTypeInst ElemTy = findSPIRVType(
1083 Decorator !=
nullptr, EmitIR);
1085 "Invalid struct element type");
1094 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1095 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1098 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1099 MIBStruct.
addUse(FieldTypes[
I]);
1100 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1101 I += MaxNumElements) {
1103 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1104 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1105 MIBCont.
addUse(FieldTypes[J]);
1111 Decorator(SPVType->defs().begin()->getReg());
1118 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1124 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1127 const SPIRVSubtarget &
ST =
1135 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1137 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1139 .
addImm(
static_cast<uint32_t
>(SC))
1148 const SPIRVSubtarget *
ST =
1149 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1150 if (Ty->isVarArg() &&
ST->isShader()) {
1152 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1153 Fn,
"SPIR-V shaders do not support variadic functions",
1156 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1158 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1161 for (
auto &ArgType : ArgTypes)
1175 add(Ty,
false, NewMI);
1176 return finishCreatingSPIRVType(Ty, NewMI);
1181 SPIRV::AccessQualifier::AccessQualifier AccQual,
1182 bool ExplicitLayoutRequired,
bool EmitIR) {
1186 FVT && FVT->getNumElements() == 1 &&
1187 !STI.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1188 return findSPIRVType(FVT->getElementType(), MIRBuilder, AccQual,
1189 ExplicitLayoutRequired, EmitIR);
1190 Ty = adjustIntTypeByWidth(Ty);
1193 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1195 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1197 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1202 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1203 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1204 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1205 return SpirvType->
uses().
begin()->getReg();
1206 return SpirvType->
defs().
begin()->getReg();
1217const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1219 unsigned SrcBitWidth = IType->getBitWidth();
1220 if (SrcBitWidth > 1) {
1221 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1232 SPIRV::AccessQualifier::AccessQualifier AccQual,
1233 bool ExplicitLayoutRequired,
bool EmitIR) {
1235 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1237 if (
const MachineInstr *
MI =
1238 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1242 const unsigned Width = IType->getBitWidth();
1243 return Width == 1 ? getOpTypeBool(MIRBuilder)
1244 : getOpTypeInt(Width, MIRBuilder,
false);
1251 SPIRV::FPEncoding::BFloat16KHR);
1261 AccQual, ExplicitLayoutRequired, EmitIR);
1265 STI.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1266 return getOpTypeVectorIdEXT(NumElts, El, MIRBuilder);
1267 return getOpTypeVector(NumElts, El, MIRBuilder);
1271 AccQual, ExplicitLayoutRequired, EmitIR);
1273 ExplicitLayoutRequired, EmitIR);
1276 if (SType->isOpaque())
1277 return getOpTypeOpaque(SType, MIRBuilder);
1280 if (ExplicitLayoutRequired) {
1281 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1282 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1286 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1290 SPIRVTypeInst RetTy =
1291 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1292 ExplicitLayoutRequired, EmitIR);
1294 for (
const auto &ParamTy : FType->params())
1295 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1296 ExplicitLayoutRequired, EmitIR));
1297 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1303 const SPIRVSubtarget *
ST =
1304 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1307 SPIRVTypeInst SpvElementType =
nullptr;
1310 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1323 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1326 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1334 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1335 bool ExplicitLayoutRequired,
bool EmitIR) {
1340 TypesInProcessing.insert(Ty);
1341 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1342 ExplicitLayoutRequired, EmitIR);
1343 TypesInProcessing.erase(Ty);
1350 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1351 SpirvType->
getOpcode() == SPIRV::OpTypeUntypedPointerKHR ||
1357 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1359 add(Ty, ExplicitLayoutRequired, SpirvType);
1372 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1373 if (t != VRegToTypeMap.end()) {
1374 auto tt = t->second.find(VReg);
1375 if (tt != t->second.end())
1391 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1392 bool ExplicitLayoutRequired,
bool EmitIR) {
1397 FVT && FVT->getNumElements() == 1 &&
1398 !STI.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1400 ExplicitLayoutRequired, EmitIR);
1405 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1407 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1417 TypesInProcessing.clear();
1418 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1419 ExplicitLayoutRequired, EmitIR);
1421 for (
auto &
CU : ForwardPointerTypes) {
1424 bool PtrNeedsLayout =
false;
1425 const Type *Ty2 =
CU.first;
1427 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1430 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1435 ForwardPointerTypes.clear();
1440 unsigned TypeOpcode)
const {
1442 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1443 return Type->getOpcode() == TypeOpcode;
1447 unsigned TypeOpcode)
const {
1449 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1450 if (
Type->getOpcode() == TypeOpcode)
1454 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1456 return ScalarType->
getOpcode() == TypeOpcode;
1460 switch (
Type->getOpcode()) {
1461 case SPIRV::OpTypeImage:
1462 case SPIRV::OpTypeSampler:
1463 case SPIRV::OpTypeSampledImage:
1465 case SPIRV::OpTypeStruct:
1466 return BlockDecoratedTypes.contains(
Type);
1482 return (
Type->getOpcode() == SPIRV::OpTypeVector)
1483 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1493 :
Type->getOperand(0).getReg();
1504 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1505 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1507 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1509 if (ScalarType->
getOpcode() == SPIRV::OpTypePointer)
1512 "Attempting to get bit width of non-integer/float/pointer type.");
1520 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1521 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1529 if (ElemType && ElemType->
getOpcode() == SPIRV::OpTypeFunction)
1531 auto It = SPIRVToLLVMType.find(ElemType);
1532 return It != SPIRVToLLVMType.end() && It->second &&
1539 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers) &&
1546 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1556 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1563 if (!Type1 || !Type2)
1576 return Bits1 > 0 && Bits1 == Bits2;
1579SPIRV::StorageClass::StorageClass
1583 "Pointer type is expected");
1587SPIRV::StorageClass::StorageClass
1589 return static_cast<SPIRV::StorageClass::StorageClass
>(
1595 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1606 ExplicitLayoutRequired, EmitIr);
1609 SPIRV::Decoration::Block, {});
1610 BlockDecoratedTypes.insert(BlockType);
1614 SPIRV::Decoration::NonWritable, 0, {});
1618 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1630 finishCreatingSPIRVType(
T, R);
1637 const auto SC = SPIRV::StorageClass::PushConstant;
1646 T, MIRBuilder, SPIRV::AccessQualifier::None,
1650 SPIRV::Decoration::Block, {});
1651 BlockDecoratedTypes.insert(BlockType);
1665 assert(ST->getNumElements() == Offsets.size());
1678 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1679 std::move(Decorator), EmitIr);
1680 add(
Key, SPIRVStructType);
1681 return SPIRVStructType;
1686 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1689 "SPIR-V image builtin type must have sampled type parameter!");
1692 SPIRV::AccessQualifier::ReadWrite,
true);
1695 "Invalid number of parameters for SPIR-V image builtin!");
1697 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1698 SPIRV::AccessQualifier::None;
1700 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1701 ? SPIRV::AccessQualifier::WriteOnly
1702 : SPIRV::AccessQualifier::AccessQualifier(
1708 MIRBuilder, SampledType,
1714 SPIRVToLLVMType[R] = ExtensionType;
1722 SPIRV::ImageFormat::ImageFormat ImageFormat,
1723 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1725 Depth, Arrayed, Multisampled, Sampled,
1726 ImageFormat, AccessQual);
1729 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1741 if (AccessQual != SPIRV::AccessQualifier::None)
1755 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1757 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1766 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1770 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1772 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1785 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1787 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1802 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1804 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1817 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1819 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1826 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1828 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1830 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1838 add(ExtensionType,
false, NewMI);
1846 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1850 add(Ty,
false, NewMI);
1860 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1866 if (Operand.isReg()) {
1867 MIB.
addUse(Operand.getReg());
1868 }
else if (Operand.isImm()) {
1869 MIB.
addImm(Operand.getImm());
1874 add(Ty,
false, NewMI);
1881 SPIRV::StorageClass::StorageClass SC,
1882 SPIRV::AccessQualifier::AccessQualifier AQ) {
1883 unsigned VecElts = 0;
1890 MIRBuilder, AQ,
false,
true);
1911 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1928 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1932SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1943 unsigned SPIRVOPcode,
Type *Ty) {
1948 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1951 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1955 if (!Ty->isFloatTy()) {
1956 return NewTypeMI.addImm(0);
1961 add(Ty,
false, NewMI);
1962 return finishCreatingSPIRVType(Ty, NewMI);
2002 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
2013 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2016 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
2019 add(Ty,
false, NewMI);
2020 return finishCreatingSPIRVType(Ty, NewMI);
2029 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
2036 if (!STI.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
2039 assert(NumElements >= 2 &&
2040 "SPIR-V vectors must have at least 2 components");
2048 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2056 add(Ty,
false, NewMI);
2057 return finishCreatingSPIRVType(Ty, NewMI);
2069 SPIRV::StorageClass::StorageClass SC,
bool ForceTyped) {
2072 .canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2074 F.getContext().diagnose(
2076 "Function used as a data pointer requires "
2077 "SPV_INTEL_function_pointers extension",
2082 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2085 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC,
2090 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2092 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2099 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2104 SPIRV::StorageClass::StorageClass SC) {
2109 (R->getOpcode() == SPIRV::OpTypeUntypedPointerKHR ||
2111 "The base type was not correctly laid out for the given storage class.");
2115SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2117 SPIRV::StorageClass::StorageClass SC,
bool ForceTyped) {
2130 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2134 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2140 return finishCreatingSPIRVType(Ty, NewMI);
2147 assert(ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers) &&
2148 !ST.isShader() &&
"Untyped pointers are not available");
2157 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2161 MIRBuilder.
getTII().
get(SPIRV::OpTypeUntypedPointerKHR))
2166 return finishCreatingSPIRVType(Ty, NewMI);
2179 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2180 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2186 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2189 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2192 constrainSelectedInstRegOperands(MIB);
2203 case SPIRV::OpTypeFloat:
2204 return &SPIRV::fIDRegClass;
2205 case SPIRV::OpTypePointer:
2206 return &SPIRV::pIDRegClass;
2207 case SPIRV::OpTypeVector:
2208 case SPIRV::OpTypeVectorIdEXT: {
2210 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2211 if (ElemOpcode == SPIRV::OpTypeFloat)
2212 return &SPIRV::vfIDRegClass;
2213 if (ElemOpcode == SPIRV::OpTypePointer)
2214 return &SPIRV::vpIDRegClass;
2215 return &SPIRV::viIDRegClass;
2218 return &SPIRV::iIDRegClass;
2223 static_cast<SPIRV::StorageClass::StorageClass
>(
2228 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2230 case SPIRV::OpTypeInt:
2231 case SPIRV::OpTypeFloat:
2232 case SPIRV::OpTypeBool:
2234 case SPIRV::OpTypePointer:
2235 case SPIRV::OpTypeUntypedPointerKHR:
2237 case SPIRV::OpTypeVector:
2238 case SPIRV::OpTypeVectorIdEXT: {
2241 switch (ElemType ? ElemType->
getOpcode() : 0) {
2242 case SPIRV::OpTypePointer:
2243 case SPIRV::OpTypeUntypedPointerKHR:
2246 case SPIRV::OpTypeInt:
2247 case SPIRV::OpTypeFloat:
2248 case SPIRV::OpTypeBool:
2272 if (
auto L = AliasInstMDMap.find({MF, AliasingListMD});
2273 L != AliasInstMDMap.end())
2280 if (ScopeMD->getNumOperands() < 2)
2286 auto D = AliasInstMDMap.find({MF, DomainMD});
2287 if (
D != AliasInstMDMap.end())
2289 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2294 AliasInstMDMap.insert(
2295 std::make_pair(std::make_pair(MF, DomainMD),
Domain));
2297 auto S = AliasInstMDMap.find({MF, ScopeMD});
2298 if (S != AliasInstMDMap.end())
2300 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2301 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2306 AliasInstMDMap.insert(std::make_pair(std::make_pair(MF, ScopeMD), Scope));
2311 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2314 for (
auto *Scope : ScopeList)
2315 MIB.
addUse(Scope->getOperand(0).getReg());
2318 std::make_pair(std::make_pair(MF, AliasingListMD),
List));
2324 const MDNode *AliasingListMD) {
2342 bool CanUseAnyVectorRank) {
2351 B.CreateIntrinsic(Intrinsic::spv_value_md,
2353 AssignCI =
B.CreateIntrinsicWithoutFolding(Intrinsic::fake_use, {Arg});
2356 OfType, Arg, {},
B);
2366 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2367 if (AssignPtrTyCI ==
nullptr ||
2368 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2370 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2384 Intrinsic::spv_assign_ptr_type)
2393void SPIRVGlobalRegistry::addStructOffsetDecorations(
2396 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2402void SPIRVGlobalRegistry::addArrayStrideDecorations(
2404 uint32_t SizeInBytes = DL.getTypeAllocSize(ElementType);
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
MachineRegisterInfo & MRI
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.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
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 LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
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.
static constexpr ElementCount getFixed(ScalarTy MinVal)
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.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
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 LLVM_READONLY 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...
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
void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg, bool CanUseAnyVectorRank)
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)
SPIRVTypeInst getOpTypeVoid(MachineIRBuilder &MIRBuilder)
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
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.
bool isPointerTy() const
True if this is an instance of PointerType.
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)
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 isVectorType(SPIRVTypeInst SPVTy)
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)
int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
bool isLongVectorEXT(const Type *Ty, bool CanUseVector16=true)
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, bool CanUseAnyVectorRank)
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.