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) {}
123 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
133 VRegToTypeMap[&MF][VReg] = SpirvType;
147 return createConstOrTypeAtFunctionEntry(
148 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
149 return MIRBuilder.
buildInstr(SPIRV::OpTypeBool)
154unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(
unsigned Width)
const {
156 if (
ST.canUseExtension(
157 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
158 (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)))
162 else if (Width <= 16)
164 else if (Width <= 32)
166 else if (Width <= 64)
168 else if (Width <= 128)
173SPIRVTypeInst SPIRVGlobalRegistry::getOpTypeInt(
unsigned Width,
176 Width = adjustOpTypeIntWidth(Width);
177 const SPIRVSubtarget &
ST =
179 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
181 if (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
183 .
addImm(SPIRV::Extension::SPV_INTEL_int4);
185 .
addImm(SPIRV::Capability::Int4TypeINTEL);
188 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers)) {
190 .
addImm(SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
192 .
addImm(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
194 return MIRBuilder.
buildInstr(SPIRV::OpTypeInt)
197 .
addImm(IsSigned ? 1 : 0);
202SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
204 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
206 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
213SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
215 SPIRV::FPEncoding::FPEncoding FPEncode) {
216 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
218 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
226 return createConstOrTypeAtFunctionEntry(
227 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
228 return MIRBuilder.
buildInstr(SPIRV::OpTypeVoid)
253 "Cannot invalidate aliasing instructions.");
254 assert(
MI->getOpcode() != SPIRV::OpFunction &&
255 "Cannot invalidate OpFunction.");
257 if (
MI->getOpcode() == SPIRV::OpFunctionCall) {
259 auto It = ForwardCalls.find(
F);
260 if (It != ForwardCalls.end()) {
261 It->second.erase(
MI);
262 if (It->second.empty())
263 ForwardCalls.erase(It);
269 auto It = LastInsertedTypeMap.find(MF);
270 if (It != LastInsertedTypeMap.end() && It->second ==
MI)
271 LastInsertedTypeMap.erase(MF);
276const MachineInstr *SPIRVGlobalRegistry::createConstOrTypeAtFunctionEntry(
283 auto LastInsertedType = LastInsertedTypeMap.find(
CurMF);
284 if (LastInsertedType != LastInsertedTypeMap.end()) {
285 auto It = LastInsertedType->second->getIterator();
289 if (It->getParent() != NewMBB)
290 InsertAt = oldInsertPoint->getParent() == NewMBB
293 else if (It->getNextNode())
294 InsertAt = It->getNextNode()->getIterator();
300 auto Result = LastInsertedTypeMap.try_emplace(
CurMF,
nullptr);
302 LastInsertedType = Result.first;
305 MachineInstr *ConstOrType =
Op(MIRBuilder);
309 LastInsertedType->second = ConstOrType;
312 while (
auto *
Next = LastInsertedType->second->getNextNode()) {
313 unsigned Opc =
Next->getOpcode();
314 if (
Opc == SPIRV::OpTypeStructContinuedINTEL ||
315 Opc == SPIRV::OpConstantCompositeContinuedINTEL ||
316 Opc == SPIRV::OpSpecConstantCompositeContinuedINTEL ||
317 Opc == SPIRV::OpCompositeConstructContinuedINTEL)
318 LastInsertedType->second =
Next;
328SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
SPIRVTypeInst ElemType,
331 assert(NumElems >= 2 &&
"SPIR-V OpTypeVector requires at least 2 components");
333 if (EleOpc == SPIRV::OpTypePointer) {
336 SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
340 "Vector of pointers requires SPV_INTEL_masked_gather_scatter "
345 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
346 EleOpc == SPIRV::OpTypeBool) &&
347 "Invalid vector element type");
350 return createConstOrTypeAtFunctionEntry(
351 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
352 return MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
364 auto *
const CF = ConstantFP::get(Ctx, Val);
366 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
367 MI->getOpcode() == SPIRV::OpConstantF))
368 return MI->getOperand(0).getReg();
379 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
380 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
386 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
391 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
395 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
402 const auto &ST =
CurMF->getSubtarget();
404 *ST.getRegisterInfo(),
405 *ST.getRegBankInfo());
417 SpvType,
TII, ZeroAsNull);
425 auto *
const CI = ConstantInt::get(
428 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
429 MI->getOpcode() == SPIRV::OpConstantI))
430 return MI->getOperand(0).getReg();
441 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
442 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
448 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
454 : SPIRV::OpConstantTrue)
457 }
else if (!CI->
isZero() || !ZeroAsNull) {
458 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
463 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
467 const auto &ST =
CurMF->getSubtarget();
469 *ST.getRegisterInfo(),
470 *ST.getRegBankInfo());
480 bool EmitIR,
bool ZeroAsNull) {
482 auto &MF = MIRBuilder.
getMF();
486 auto *
const CI = ConstantInt::get(
const_cast<IntegerType *
>(Ty), Val,
500 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
506 if (Val || !ZeroAsNull) {
507 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
512 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
516 const auto &Subtarget =
CurMF->getSubtarget();
518 *Subtarget.getRegisterInfo(),
519 *Subtarget.getRegBankInfo());
529 auto &MF = MIRBuilder.
getMF();
533 SPIRV::AccessQualifier::ReadWrite,
true);
534 auto *
const CF = ConstantFP::get(Ctx, Val);
540 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
541 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
544 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
547 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
550 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
557Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
561 if (SpvType->
getOpcode() == SPIRV::OpTypeVector ||
562 SpvType->
getOpcode() == SPIRV::OpTypeArray) {
566 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
571 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
577Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
580 unsigned ElemCnt,
bool ZeroAsNull) {
588 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
591 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
595 MachineInstr *DepMI =
596 const_cast<MachineInstr *
>(
static_cast<const MachineInstr *
>(SpvType));
598 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
599 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
600 MachineInstrBuilder MIB;
602 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
605 for (
unsigned i = 0; i < ElemCnt; ++i)
608 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
612 const auto &Subtarget =
CurMF->getSubtarget();
614 *Subtarget.getRegisterInfo(),
615 *Subtarget.getRegBankInfo());
628 I, SpvType,
TII, ZeroAsNull);
638 "Expected vector type for constant vector creation");
642 "Expected integer element type for APInt constant vector");
647 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
662 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
666 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
678 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
693 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(I64Ty, Num)});
694 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
698Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
715 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
721 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
724 for (
unsigned i = 0; i < ElemCnt; ++i)
729 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
744 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
748 return getOrCreateIntCompositeOrNull(
749 Val, MIRBuilder, SpvType, EmitIR, ConstVec, BW,
767 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
768 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
771 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
773 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
783 unsigned Param,
unsigned FilerMode,
796 MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
807 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
809 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
818 GVar = M->getGlobalVariable(Name);
819 if (GVar ==
nullptr) {
843 if (&GVBuilder.
getMBB() != &EntryBB)
846 auto MIB = GVBuilder.
buildInstr(SPIRV::OpVariable)
854 if (IsInstSelector) {
855 const auto &Subtarget =
CurMF->getSubtarget();
857 *Subtarget.getRegisterInfo(),
858 *Subtarget.getRegBankInfo());
866 auto MRI = MIRBuilder.
getMRI();
867 if (Reg != ResVReg) {
870 MRI->setType(Reg, RegLLTy);
889 if (IsConst && !ST.isShader())
894 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
899 {
static_cast<uint32_t>(*LinkageType)}, Name);
901 SPIRV::BuiltIn::BuiltIn BuiltInId;
904 {
static_cast<uint32_t>(BuiltInId)});
910 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
927 std::nullopt, MIRBuilder,
false);
929 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
930 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
939 bool ExplicitLayoutRequired,
942 "Invalid array element type");
950 ArrayType = createConstOrTypeAtFunctionEntry(
952 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
963 ArrayType = createConstOrTypeAtFunctionEntry(
964 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
965 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
971 if (!
ST.isShader()) {
973 "Runtime arrays are not allowed in non-shader "
977 ArrayType = createConstOrTypeAtFunctionEntry(
978 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
979 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
987 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
995SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
1000 return createConstOrTypeAtFunctionEntry(
1001 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1011 SPIRV::AccessQualifier::AccessQualifier AccQual,
1013 Type *OriginalElementType =
nullptr;
1014 uint64_t TotalSize = 0;
1016 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
1017 OriginalElementType, MIRBuilder, AccQual,
1018 Decorator !=
nullptr, EmitIR);
1019 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
1020 Decorator !=
nullptr,
1024 const SPIRVSubtarget &
ST =
1027 constexpr unsigned MaxWordCount = UINT16_MAX;
1030 size_t MaxNumElements = MaxWordCount - 2;
1031 size_t SPIRVStructNumElements = NumElements;
1032 if (NumElements > MaxNumElements) {
1034 SPIRVStructNumElements = MaxNumElements;
1035 MaxNumElements = MaxWordCount - 1;
1038 for (
const auto &Elem : Ty->
elements()) {
1039 SPIRVTypeInst ElemTy = findSPIRVType(
1041 Decorator !=
nullptr, EmitIR);
1043 "Invalid struct element type");
1052 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1053 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1056 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1057 MIBStruct.
addUse(FieldTypes[
I]);
1058 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1059 I += MaxNumElements) {
1061 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1062 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1063 MIBCont.
addUse(FieldTypes[J]);
1069 Decorator(SPVType->defs().begin()->getReg());
1076 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1082 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1087 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1089 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1091 .
addImm(
static_cast<uint32_t
>(SC))
1098 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1100 return MIRBuilder.
buildInstr(SPIRV::OpTypeForwardPointer)
1102 .
addImm(
static_cast<uint32_t
>(SC));
1110 const SPIRVSubtarget *
ST =
1111 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1112 if (Ty->isVarArg() &&
ST->isShader()) {
1114 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1115 Fn,
"SPIR-V shaders do not support variadic functions",
1118 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1120 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1123 for (
auto &ArgType : ArgTypes)
1137 add(Ty,
false, NewMI);
1138 return finishCreatingSPIRVType(Ty, NewMI);
1143 SPIRV::AccessQualifier::AccessQualifier AccQual,
1144 bool ExplicitLayoutRequired,
bool EmitIR) {
1147 FVT && FVT->getNumElements() == 1)
1148 return findSPIRVType(FVT->getElementType(), MIRBuilder, AccQual,
1149 ExplicitLayoutRequired, EmitIR);
1150 Ty = adjustIntTypeByWidth(Ty);
1153 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1155 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1157 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1162 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1163 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1164 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1165 return SpirvType->
uses().
begin()->getReg();
1166 return SpirvType->
defs().
begin()->getReg();
1177const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1179 unsigned SrcBitWidth = IType->getBitWidth();
1180 if (SrcBitWidth > 1) {
1181 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1192 SPIRV::AccessQualifier::AccessQualifier AccQual,
1193 bool ExplicitLayoutRequired,
bool EmitIR) {
1195 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1197 if (
const MachineInstr *
MI =
1198 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1202 const unsigned Width = IType->getBitWidth();
1203 return Width == 1 ? getOpTypeBool(MIRBuilder)
1204 : getOpTypeInt(Width, MIRBuilder,
false);
1209 SPIRV::FPEncoding::BFloat16KHR);
1215 return getOpTypeVoid(MIRBuilder);
1219 AccQual, ExplicitLayoutRequired, EmitIR);
1225 AccQual, ExplicitLayoutRequired, EmitIR);
1227 ExplicitLayoutRequired, EmitIR);
1230 if (SType->isOpaque())
1231 return getOpTypeOpaque(SType, MIRBuilder);
1234 if (ExplicitLayoutRequired) {
1235 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1236 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1240 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1244 SPIRVTypeInst RetTy =
1245 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1246 ExplicitLayoutRequired, EmitIR);
1248 for (
const auto &ParamTy : FType->params())
1249 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1250 ExplicitLayoutRequired, EmitIR));
1251 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1257 const SPIRVSubtarget *
ST =
1258 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1261 SPIRVTypeInst SpvElementType =
nullptr;
1264 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1277 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1280 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1288 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1289 bool ExplicitLayoutRequired,
bool EmitIR) {
1294 TypesInProcessing.insert(Ty);
1295 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1296 ExplicitLayoutRequired, EmitIR);
1297 TypesInProcessing.erase(Ty);
1304 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1310 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1312 add(Ty, ExplicitLayoutRequired, SpirvType);
1325 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1326 if (t != VRegToTypeMap.end()) {
1327 auto tt = t->second.find(VReg);
1328 if (tt != t->second.end())
1344 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1345 bool ExplicitLayoutRequired,
bool EmitIR) {
1348 FVT && FVT->getNumElements() == 1)
1350 ExplicitLayoutRequired, EmitIR);
1355 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1357 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1367 TypesInProcessing.clear();
1368 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1369 ExplicitLayoutRequired, EmitIR);
1371 for (
auto &
CU : ForwardPointerTypes) {
1374 bool PtrNeedsLayout =
false;
1375 const Type *Ty2 =
CU.first;
1377 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1380 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1385 ForwardPointerTypes.clear();
1390 unsigned TypeOpcode)
const {
1392 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1393 return Type->getOpcode() == TypeOpcode;
1397 unsigned TypeOpcode)
const {
1399 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1400 if (
Type->getOpcode() == TypeOpcode)
1402 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1403 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1405 return ScalarType->
getOpcode() == TypeOpcode;
1411 switch (
Type->getOpcode()) {
1412 case SPIRV::OpTypeImage:
1413 case SPIRV::OpTypeSampler:
1414 case SPIRV::OpTypeSampledImage:
1416 case SPIRV::OpTypeStruct:
1417 return hasBlockDecoration(
Type);
1432 return Type->getOpcode() == SPIRV::OpTypeVector
1433 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1441 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1442 ?
Type->getOperand(1).getReg()
1443 :
Type->getOperand(0).getReg();
1454 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1455 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1457 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1459 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1467 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1468 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1476 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1486 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1493 return ElemType ? ElemType->
getOpcode() : 0;
1498 if (!Type1 || !Type2)
1504 if (Op1 == SPIRV::OpTypePointer &&
1507 if (Op2 == SPIRV::OpTypePointer &&
1512 return Bits1 > 0 && Bits1 == Bits2;
1515SPIRV::StorageClass::StorageClass
1519 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1523SPIRV::StorageClass::StorageClass
1525 return static_cast<SPIRV::StorageClass::StorageClass
>(
1531 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1542 ExplicitLayoutRequired, EmitIr);
1545 SPIRV::Decoration::Block, {});
1549 SPIRV::Decoration::NonWritable, 0, {});
1553 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1565 finishCreatingSPIRVType(
T, R);
1572 const auto SC = SPIRV::StorageClass::PushConstant;
1581 T, MIRBuilder, SPIRV::AccessQualifier::None,
1585 SPIRV::Decoration::Block, {});
1599 assert(ST->getNumElements() == Offsets.size());
1612 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1613 std::move(Decorator), EmitIr);
1614 add(
Key, SPIRVStructType);
1615 return SPIRVStructType;
1620 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1623 "SPIR-V image builtin type must have sampled type parameter!");
1626 SPIRV::AccessQualifier::ReadWrite,
true);
1629 "Invalid number of parameters for SPIR-V image builtin!");
1631 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1632 SPIRV::AccessQualifier::None;
1634 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1635 ? SPIRV::AccessQualifier::WriteOnly
1636 : SPIRV::AccessQualifier::AccessQualifier(
1642 MIRBuilder, SampledType,
1648 SPIRVToLLVMType[R] = ExtensionType;
1656 SPIRV::ImageFormat::ImageFormat ImageFormat,
1657 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1659 Depth, Arrayed, Multisampled, Sampled,
1660 ImageFormat, AccessQual);
1663 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1675 if (AccessQual != SPIRV::AccessQualifier::None)
1689 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1691 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1700 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1704 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1706 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1719 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1721 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1736 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1738 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1751 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1753 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1760 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1762 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1764 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1772 add(ExtensionType,
false, NewMI);
1780 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1784 add(Ty,
false, NewMI);
1794 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1800 if (Operand.isReg()) {
1801 MIB.
addUse(Operand.getReg());
1802 }
else if (Operand.isImm()) {
1803 MIB.
addImm(Operand.getImm());
1808 add(Ty,
false, NewMI);
1815 SPIRV::StorageClass::StorageClass SC,
1816 SPIRV::AccessQualifier::AccessQualifier AQ) {
1817 unsigned VecElts = 0;
1824 MIRBuilder, AQ,
false,
true);
1845 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1862 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1866SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1877 unsigned SPIRVOPcode,
Type *Ty) {
1882 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1885 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1889 if (!Ty->isFloatTy()) {
1890 return NewTypeMI.addImm(0);
1895 add(Ty,
false, NewMI);
1896 return finishCreatingSPIRVType(Ty, NewMI);
1936 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1947 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1950 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1953 add(Ty,
false, NewMI);
1954 return finishCreatingSPIRVType(Ty, NewMI);
1963 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1971 assert(NumElements >= 2 &&
"SPIR-V vectors must have at least 2 components");
1979 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1982 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
1987 add(Ty,
false, NewMI);
1988 return finishCreatingSPIRVType(Ty, NewMI);
1993 SPIRV::StorageClass::StorageClass SC) {
2000 SPIRV::StorageClass::StorageClass SC) {
2003 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2006 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
2010 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2012 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2019 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2024 SPIRV::StorageClass::StorageClass SC) {
2030 "The base type was not correctly laid out for the given storage class.");
2034SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2036 SPIRV::StorageClass::StorageClass SC) {
2043 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2047 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2053 return finishCreatingSPIRVType(Ty, NewMI);
2066 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2067 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2073 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2076 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2079 const auto &ST =
CurMF->getSubtarget();
2081 *ST.getRegisterInfo(),
2082 *ST.getRegBankInfo());
2093 case SPIRV::OpTypeFloat:
2094 return &SPIRV::fIDRegClass;
2095 case SPIRV::OpTypePointer:
2096 return &SPIRV::pIDRegClass;
2097 case SPIRV::OpTypeVector: {
2099 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2100 if (ElemOpcode == SPIRV::OpTypeFloat)
2101 return &SPIRV::vfIDRegClass;
2102 if (ElemOpcode == SPIRV::OpTypePointer)
2103 return &SPIRV::vpIDRegClass;
2104 return &SPIRV::viIDRegClass;
2107 return &SPIRV::iIDRegClass;
2112 static_cast<SPIRV::StorageClass::StorageClass
>(
2117 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2119 case SPIRV::OpTypeInt:
2120 case SPIRV::OpTypeFloat:
2121 case SPIRV::OpTypeBool:
2123 case SPIRV::OpTypePointer:
2125 case SPIRV::OpTypeVector: {
2128 switch (ElemType ? ElemType->
getOpcode() : 0) {
2129 case SPIRV::OpTypePointer:
2132 case SPIRV::OpTypeInt:
2133 case SPIRV::OpTypeFloat:
2134 case SPIRV::OpTypeBool:
2156 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2163 if (ScopeMD->getNumOperands() < 2)
2169 auto D = AliasInstMDMap.find(DomainMD);
2170 if (
D != AliasInstMDMap.end())
2177 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2179 auto S = AliasInstMDMap.find(ScopeMD);
2180 if (S != AliasInstMDMap.end())
2183 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2188 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2196 for (
auto *Scope : ScopeList)
2197 MIB.
addUse(Scope->getOperand(0).getReg());
2199 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2205 const MDNode *AliasingListMD) {
2232 B.CreateIntrinsic(Intrinsic::spv_value_md,
2234 AssignCI =
B.CreateIntrinsicWithoutFolding(Intrinsic::fake_use, {Arg});
2237 OfType, Arg, {},
B);
2247 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2248 if (AssignPtrTyCI ==
nullptr ||
2249 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2251 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2265 Intrinsic::spv_assign_ptr_type)
2274void SPIRVGlobalRegistry::addStructOffsetDecorations(
2277 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2283void SPIRVGlobalRegistry::addArrayStrideDecorations(
2285 uint32_t SizeInBytes = DL.getTypeSizeInBits(ElementType) / 8;
2292 for (
const MachineInstr &Use :
2293 Type->getMF()->getRegInfo().use_instructions(Def)) {
2294 if (
Use.getOpcode() != SPIRV::OpDecorate)
2297 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 unsigned getNumElements(Type *Ty)
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)
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.
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.
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.
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(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type 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
SPIRVTypeInst assignVectTypeToVReg(SPIRVTypeInst BaseType, unsigned NumElements, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
void assignSPIRVTypeToVReg(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
SPIRVTypeInst getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVTypeInst RetType, const SmallVectorImpl< SPIRVTypeInst > &ArgTypes, MachineIRBuilder &MIRBuilder)
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
SPIRVTypeInst assignFloatTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const
void addDeducedElementType(Value *Val, Type *Ty)
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)
SPIRVTypeInst getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
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)
unsigned getPointeeTypeOp(Register PtrReg)
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
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
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
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_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
This is an optimization pass for GlobalISel generic memory operations.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
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)
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
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)
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)
void addStringImm(const StringRef &Str, MCInst &Inst)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
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.