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) {
841 if (&GVBuilder.
getMBB() != &EntryBB)
844 auto MIB = GVBuilder.
buildInstr(SPIRV::OpVariable)
852 if (IsInstSelector) {
853 const auto &Subtarget =
CurMF->getSubtarget();
855 *Subtarget.getRegisterInfo(),
856 *Subtarget.getRegBankInfo());
864 auto MRI = MIRBuilder.
getMRI();
865 if (Reg != ResVReg) {
868 MRI->setType(Reg, RegLLTy);
887 if (IsConst && !ST.isShader())
892 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
897 {
static_cast<uint32_t>(*LinkageType)}, Name);
899 SPIRV::BuiltIn::BuiltIn BuiltInId;
902 {
static_cast<uint32_t>(BuiltInId)});
908 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
925 std::nullopt, MIRBuilder,
false);
927 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
928 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
937 bool ExplicitLayoutRequired,
940 "Invalid array element type");
948 ArrayType = createConstOrTypeAtFunctionEntry(
950 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
961 ArrayType = createConstOrTypeAtFunctionEntry(
962 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
963 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
969 if (!
ST.isShader()) {
971 "Runtime arrays are not allowed in non-shader "
975 ArrayType = createConstOrTypeAtFunctionEntry(
976 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
977 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
985 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
993SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
998 return createConstOrTypeAtFunctionEntry(
999 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1009 SPIRV::AccessQualifier::AccessQualifier AccQual,
1011 Type *OriginalElementType =
nullptr;
1012 uint64_t TotalSize = 0;
1014 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
1015 OriginalElementType, MIRBuilder, AccQual,
1016 Decorator !=
nullptr, EmitIR);
1017 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
1018 Decorator !=
nullptr,
1022 const SPIRVSubtarget &
ST =
1025 constexpr unsigned MaxWordCount = UINT16_MAX;
1028 size_t MaxNumElements = MaxWordCount - 2;
1029 size_t SPIRVStructNumElements = NumElements;
1030 if (NumElements > MaxNumElements) {
1032 SPIRVStructNumElements = MaxNumElements;
1033 MaxNumElements = MaxWordCount - 1;
1036 for (
const auto &Elem : Ty->
elements()) {
1037 SPIRVTypeInst ElemTy = findSPIRVType(
1039 Decorator !=
nullptr, EmitIR);
1041 "Invalid struct element type");
1050 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1051 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1054 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1055 MIBStruct.
addUse(FieldTypes[
I]);
1056 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1057 I += MaxNumElements) {
1059 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1060 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1061 MIBCont.
addUse(FieldTypes[J]);
1067 Decorator(SPVType->defs().begin()->getReg());
1074 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1080 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1085 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1087 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1089 .
addImm(
static_cast<uint32_t
>(SC))
1096 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1098 return MIRBuilder.
buildInstr(SPIRV::OpTypeForwardPointer)
1100 .
addImm(
static_cast<uint32_t
>(SC));
1108 const SPIRVSubtarget *
ST =
1109 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1110 if (Ty->isVarArg() &&
ST->isShader()) {
1112 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1113 Fn,
"SPIR-V shaders do not support variadic functions",
1116 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1118 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1121 for (
auto &ArgType : ArgTypes)
1135 add(Ty,
false, NewMI);
1136 return finishCreatingSPIRVType(Ty, NewMI);
1141 SPIRV::AccessQualifier::AccessQualifier AccQual,
1142 bool ExplicitLayoutRequired,
bool EmitIR) {
1145 FVT && FVT->getNumElements() == 1)
1146 return findSPIRVType(FVT->getElementType(), MIRBuilder, AccQual,
1147 ExplicitLayoutRequired, EmitIR);
1148 Ty = adjustIntTypeByWidth(Ty);
1151 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1153 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1155 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1160 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1161 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1162 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1163 return SpirvType->
uses().
begin()->getReg();
1164 return SpirvType->
defs().
begin()->getReg();
1175const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1177 unsigned SrcBitWidth = IType->getBitWidth();
1178 if (SrcBitWidth > 1) {
1179 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1190 SPIRV::AccessQualifier::AccessQualifier AccQual,
1191 bool ExplicitLayoutRequired,
bool EmitIR) {
1193 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1195 if (
const MachineInstr *
MI =
1196 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1200 const unsigned Width = IType->getBitWidth();
1201 return Width == 1 ? getOpTypeBool(MIRBuilder)
1202 : getOpTypeInt(Width, MIRBuilder,
false);
1207 SPIRV::FPEncoding::BFloat16KHR);
1213 return getOpTypeVoid(MIRBuilder);
1217 AccQual, ExplicitLayoutRequired, EmitIR);
1223 AccQual, ExplicitLayoutRequired, EmitIR);
1225 ExplicitLayoutRequired, EmitIR);
1228 if (SType->isOpaque())
1229 return getOpTypeOpaque(SType, MIRBuilder);
1232 if (ExplicitLayoutRequired) {
1233 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1234 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1238 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1242 SPIRVTypeInst RetTy =
1243 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1244 ExplicitLayoutRequired, EmitIR);
1246 for (
const auto &ParamTy : FType->params())
1247 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1248 ExplicitLayoutRequired, EmitIR));
1249 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1255 const SPIRVSubtarget *
ST =
1256 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1259 SPIRVTypeInst SpvElementType =
nullptr;
1262 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1275 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1278 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1286 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1287 bool ExplicitLayoutRequired,
bool EmitIR) {
1292 TypesInProcessing.insert(Ty);
1293 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1294 ExplicitLayoutRequired, EmitIR);
1295 TypesInProcessing.erase(Ty);
1302 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1308 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1310 add(Ty, ExplicitLayoutRequired, SpirvType);
1323 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1324 if (t != VRegToTypeMap.end()) {
1325 auto tt = t->second.find(VReg);
1326 if (tt != t->second.end())
1342 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1343 bool ExplicitLayoutRequired,
bool EmitIR) {
1346 FVT && FVT->getNumElements() == 1)
1348 ExplicitLayoutRequired, EmitIR);
1353 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1355 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1365 TypesInProcessing.clear();
1366 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1367 ExplicitLayoutRequired, EmitIR);
1369 for (
auto &
CU : ForwardPointerTypes) {
1372 bool PtrNeedsLayout =
false;
1373 const Type *Ty2 =
CU.first;
1375 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1378 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1383 ForwardPointerTypes.clear();
1388 unsigned TypeOpcode)
const {
1390 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1391 return Type->getOpcode() == TypeOpcode;
1395 unsigned TypeOpcode)
const {
1397 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1398 if (
Type->getOpcode() == TypeOpcode)
1400 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1401 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1403 return ScalarType->
getOpcode() == TypeOpcode;
1409 switch (
Type->getOpcode()) {
1410 case SPIRV::OpTypeImage:
1411 case SPIRV::OpTypeSampler:
1412 case SPIRV::OpTypeSampledImage:
1414 case SPIRV::OpTypeStruct:
1415 return hasBlockDecoration(
Type);
1430 return Type->getOpcode() == SPIRV::OpTypeVector
1431 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1439 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1440 ?
Type->getOperand(1).getReg()
1441 :
Type->getOperand(0).getReg();
1452 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1453 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1455 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1457 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1465 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1466 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1474 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1484 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1491 return ElemType ? ElemType->
getOpcode() : 0;
1496 if (!Type1 || !Type2)
1502 if (Op1 == SPIRV::OpTypePointer &&
1505 if (Op2 == SPIRV::OpTypePointer &&
1510 return Bits1 > 0 && Bits1 == Bits2;
1513SPIRV::StorageClass::StorageClass
1517 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1521SPIRV::StorageClass::StorageClass
1523 return static_cast<SPIRV::StorageClass::StorageClass
>(
1529 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1540 ExplicitLayoutRequired, EmitIr);
1543 SPIRV::Decoration::Block, {});
1547 SPIRV::Decoration::NonWritable, 0, {});
1551 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1563 finishCreatingSPIRVType(
T, R);
1570 const auto SC = SPIRV::StorageClass::PushConstant;
1579 T, MIRBuilder, SPIRV::AccessQualifier::None,
1583 SPIRV::Decoration::Block, {});
1597 assert(ST->getNumElements() == Offsets.size());
1610 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1611 std::move(Decorator), EmitIr);
1612 add(
Key, SPIRVStructType);
1613 return SPIRVStructType;
1618 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1621 "SPIR-V image builtin type must have sampled type parameter!");
1624 SPIRV::AccessQualifier::ReadWrite,
true);
1627 "Invalid number of parameters for SPIR-V image builtin!");
1629 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1630 SPIRV::AccessQualifier::None;
1632 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1633 ? SPIRV::AccessQualifier::WriteOnly
1634 : SPIRV::AccessQualifier::AccessQualifier(
1640 MIRBuilder, SampledType,
1646 SPIRVToLLVMType[R] = ExtensionType;
1654 SPIRV::ImageFormat::ImageFormat ImageFormat,
1655 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1657 Depth, Arrayed, Multisampled, Sampled,
1658 ImageFormat, AccessQual);
1661 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1673 if (AccessQual != SPIRV::AccessQualifier::None)
1687 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1689 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1698 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1702 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1704 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1717 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1719 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1734 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1736 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1749 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1751 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1758 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1760 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1762 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1770 add(ExtensionType,
false, NewMI);
1778 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1782 add(Ty,
false, NewMI);
1792 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1798 if (Operand.isReg()) {
1799 MIB.
addUse(Operand.getReg());
1800 }
else if (Operand.isImm()) {
1801 MIB.
addImm(Operand.getImm());
1806 add(Ty,
false, NewMI);
1813 SPIRV::StorageClass::StorageClass SC,
1814 SPIRV::AccessQualifier::AccessQualifier AQ) {
1815 unsigned VecElts = 0;
1822 MIRBuilder, AQ,
false,
true);
1843 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1860 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1864SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1875 unsigned SPIRVOPcode,
Type *Ty) {
1880 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1883 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1887 if (!Ty->isFloatTy()) {
1888 return NewTypeMI.addImm(0);
1893 add(Ty,
false, NewMI);
1894 return finishCreatingSPIRVType(Ty, NewMI);
1934 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1945 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1948 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1951 add(Ty,
false, NewMI);
1952 return finishCreatingSPIRVType(Ty, NewMI);
1961 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1969 assert(NumElements >= 2 &&
"SPIR-V vectors must have at least 2 components");
1977 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1980 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
1985 add(Ty,
false, NewMI);
1986 return finishCreatingSPIRVType(Ty, NewMI);
1991 SPIRV::StorageClass::StorageClass SC) {
1998 SPIRV::StorageClass::StorageClass SC) {
2001 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2004 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
2008 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2010 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2017 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2022 SPIRV::StorageClass::StorageClass SC) {
2028 "The base type was not correctly laid out for the given storage class.");
2032SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2034 SPIRV::StorageClass::StorageClass SC) {
2041 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2045 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2051 return finishCreatingSPIRVType(Ty, NewMI);
2064 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2065 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2071 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2074 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2077 const auto &ST =
CurMF->getSubtarget();
2079 *ST.getRegisterInfo(),
2080 *ST.getRegBankInfo());
2091 case SPIRV::OpTypeFloat:
2092 return &SPIRV::fIDRegClass;
2093 case SPIRV::OpTypePointer:
2094 return &SPIRV::pIDRegClass;
2095 case SPIRV::OpTypeVector: {
2097 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2098 if (ElemOpcode == SPIRV::OpTypeFloat)
2099 return &SPIRV::vfIDRegClass;
2100 if (ElemOpcode == SPIRV::OpTypePointer)
2101 return &SPIRV::vpIDRegClass;
2102 return &SPIRV::viIDRegClass;
2105 return &SPIRV::iIDRegClass;
2110 static_cast<SPIRV::StorageClass::StorageClass
>(
2115 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2117 case SPIRV::OpTypeInt:
2118 case SPIRV::OpTypeFloat:
2119 case SPIRV::OpTypeBool:
2121 case SPIRV::OpTypePointer:
2123 case SPIRV::OpTypeVector: {
2126 switch (ElemType ? ElemType->
getOpcode() : 0) {
2127 case SPIRV::OpTypePointer:
2130 case SPIRV::OpTypeInt:
2131 case SPIRV::OpTypeFloat:
2132 case SPIRV::OpTypeBool:
2154 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2161 if (ScopeMD->getNumOperands() < 2)
2167 auto D = AliasInstMDMap.find(DomainMD);
2168 if (
D != AliasInstMDMap.end())
2175 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2177 auto S = AliasInstMDMap.find(ScopeMD);
2178 if (S != AliasInstMDMap.end())
2181 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2186 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2194 for (
auto *Scope : ScopeList)
2195 MIB.
addUse(Scope->getOperand(0).getReg());
2197 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2203 const MDNode *AliasingListMD) {
2230 B.CreateIntrinsic(Intrinsic::spv_value_md,
2232 AssignCI =
B.CreateIntrinsic(Intrinsic::fake_use, {Arg});
2235 OfType, Arg, {},
B);
2245 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2246 if (AssignPtrTyCI ==
nullptr ||
2247 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2249 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2263 Intrinsic::spv_assign_ptr_type)
2272void SPIRVGlobalRegistry::addStructOffsetDecorations(
2275 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2281void SPIRVGlobalRegistry::addArrayStrideDecorations(
2283 uint32_t SizeInBytes = DL.getTypeSizeInBits(ElementType) / 8;
2290 for (
const MachineInstr &Use :
2291 Type->getMF()->getRegInfo().use_instructions(Def)) {
2292 if (
Use.getOpcode() != SPIRV::OpDecorate)
2295 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 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)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
MetadataAsValue * buildMD(Value *Arg)
bool isTypedPointerTy(const Type *T)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
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.
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
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)
FunctionAddr VTableAddr Next
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)
bool isPointerTyOrWrapper(const Type *Ty)
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.