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);
1211 SPIRV::FPEncoding::BFloat16KHR);
1217 return getOpTypeVoid(MIRBuilder);
1221 AccQual, ExplicitLayoutRequired, EmitIR);
1227 AccQual, ExplicitLayoutRequired, EmitIR);
1229 ExplicitLayoutRequired, EmitIR);
1232 if (SType->isOpaque())
1233 return getOpTypeOpaque(SType, MIRBuilder);
1236 if (ExplicitLayoutRequired) {
1237 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1238 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1242 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1246 SPIRVTypeInst RetTy =
1247 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1248 ExplicitLayoutRequired, EmitIR);
1250 for (
const auto &ParamTy : FType->params())
1251 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1252 ExplicitLayoutRequired, EmitIR));
1253 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1259 const SPIRVSubtarget *
ST =
1260 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1263 SPIRVTypeInst SpvElementType =
nullptr;
1266 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1279 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1282 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1290 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1291 bool ExplicitLayoutRequired,
bool EmitIR) {
1296 TypesInProcessing.insert(Ty);
1297 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1298 ExplicitLayoutRequired, EmitIR);
1299 TypesInProcessing.erase(Ty);
1306 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1312 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1314 add(Ty, ExplicitLayoutRequired, SpirvType);
1327 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1328 if (t != VRegToTypeMap.end()) {
1329 auto tt = t->second.find(VReg);
1330 if (tt != t->second.end())
1346 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1347 bool ExplicitLayoutRequired,
bool EmitIR) {
1350 FVT && FVT->getNumElements() == 1)
1352 ExplicitLayoutRequired, EmitIR);
1357 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1359 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1369 TypesInProcessing.clear();
1370 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1371 ExplicitLayoutRequired, EmitIR);
1373 for (
auto &
CU : ForwardPointerTypes) {
1376 bool PtrNeedsLayout =
false;
1377 const Type *Ty2 =
CU.first;
1379 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1382 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1387 ForwardPointerTypes.clear();
1392 unsigned TypeOpcode)
const {
1394 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1395 return Type->getOpcode() == TypeOpcode;
1399 unsigned TypeOpcode)
const {
1401 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1402 if (
Type->getOpcode() == TypeOpcode)
1404 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1405 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1407 return ScalarType->
getOpcode() == TypeOpcode;
1413 switch (
Type->getOpcode()) {
1414 case SPIRV::OpTypeImage:
1415 case SPIRV::OpTypeSampler:
1416 case SPIRV::OpTypeSampledImage:
1418 case SPIRV::OpTypeStruct:
1419 return hasBlockDecoration(
Type);
1434 return Type->getOpcode() == SPIRV::OpTypeVector
1435 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1443 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1444 ?
Type->getOperand(1).getReg()
1445 :
Type->getOperand(0).getReg();
1456 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1457 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1459 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1461 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1469 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1470 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1478 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1488 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1495 return ElemType ? ElemType->
getOpcode() : 0;
1500 if (!Type1 || !Type2)
1506 if (Op1 == SPIRV::OpTypePointer &&
1509 if (Op2 == SPIRV::OpTypePointer &&
1514 return Bits1 > 0 && Bits1 == Bits2;
1517SPIRV::StorageClass::StorageClass
1521 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1525SPIRV::StorageClass::StorageClass
1527 return static_cast<SPIRV::StorageClass::StorageClass
>(
1533 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1544 ExplicitLayoutRequired, EmitIr);
1547 SPIRV::Decoration::Block, {});
1551 SPIRV::Decoration::NonWritable, 0, {});
1555 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1567 finishCreatingSPIRVType(
T, R);
1574 const auto SC = SPIRV::StorageClass::PushConstant;
1583 T, MIRBuilder, SPIRV::AccessQualifier::None,
1587 SPIRV::Decoration::Block, {});
1601 assert(ST->getNumElements() == Offsets.size());
1614 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1615 std::move(Decorator), EmitIr);
1616 add(
Key, SPIRVStructType);
1617 return SPIRVStructType;
1622 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1625 "SPIR-V image builtin type must have sampled type parameter!");
1628 SPIRV::AccessQualifier::ReadWrite,
true);
1631 "Invalid number of parameters for SPIR-V image builtin!");
1633 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1634 SPIRV::AccessQualifier::None;
1636 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1637 ? SPIRV::AccessQualifier::WriteOnly
1638 : SPIRV::AccessQualifier::AccessQualifier(
1644 MIRBuilder, SampledType,
1650 SPIRVToLLVMType[R] = ExtensionType;
1658 SPIRV::ImageFormat::ImageFormat ImageFormat,
1659 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1661 Depth, Arrayed, Multisampled, Sampled,
1662 ImageFormat, AccessQual);
1665 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1677 if (AccessQual != SPIRV::AccessQualifier::None)
1691 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1693 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1702 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1706 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1708 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1721 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1723 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1738 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1740 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1753 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1755 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1762 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1764 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1766 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1774 add(ExtensionType,
false, NewMI);
1782 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1786 add(Ty,
false, NewMI);
1796 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1802 if (Operand.isReg()) {
1803 MIB.
addUse(Operand.getReg());
1804 }
else if (Operand.isImm()) {
1805 MIB.
addImm(Operand.getImm());
1810 add(Ty,
false, NewMI);
1817 SPIRV::StorageClass::StorageClass SC,
1818 SPIRV::AccessQualifier::AccessQualifier AQ) {
1819 unsigned VecElts = 0;
1826 MIRBuilder, AQ,
false,
true);
1847 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1864 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1868SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1879 unsigned SPIRVOPcode,
Type *Ty) {
1884 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1887 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1891 if (!Ty->isFloatTy()) {
1892 return NewTypeMI.addImm(0);
1897 add(Ty,
false, NewMI);
1898 return finishCreatingSPIRVType(Ty, NewMI);
1938 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1949 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1952 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1955 add(Ty,
false, NewMI);
1956 return finishCreatingSPIRVType(Ty, NewMI);
1965 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1973 assert(NumElements >= 2 &&
"SPIR-V vectors must have at least 2 components");
1981 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1984 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
1989 add(Ty,
false, NewMI);
1990 return finishCreatingSPIRVType(Ty, NewMI);
1995 SPIRV::StorageClass::StorageClass SC) {
2002 SPIRV::StorageClass::StorageClass SC) {
2005 .canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2007 F.getContext().diagnose(
2009 "Function used as a data pointer requires "
2010 "SPV_INTEL_function_pointers extension",
2015 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2018 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
2022 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2024 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2031 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2036 SPIRV::StorageClass::StorageClass SC) {
2042 "The base type was not correctly laid out for the given storage class.");
2046SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2048 SPIRV::StorageClass::StorageClass SC) {
2055 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2059 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2065 return finishCreatingSPIRVType(Ty, NewMI);
2078 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2079 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2085 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2088 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2091 const auto &ST =
CurMF->getSubtarget();
2093 *ST.getRegisterInfo(),
2094 *ST.getRegBankInfo());
2105 case SPIRV::OpTypeFloat:
2106 return &SPIRV::fIDRegClass;
2107 case SPIRV::OpTypePointer:
2108 return &SPIRV::pIDRegClass;
2109 case SPIRV::OpTypeVector: {
2111 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2112 if (ElemOpcode == SPIRV::OpTypeFloat)
2113 return &SPIRV::vfIDRegClass;
2114 if (ElemOpcode == SPIRV::OpTypePointer)
2115 return &SPIRV::vpIDRegClass;
2116 return &SPIRV::viIDRegClass;
2119 return &SPIRV::iIDRegClass;
2124 static_cast<SPIRV::StorageClass::StorageClass
>(
2129 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2131 case SPIRV::OpTypeInt:
2132 case SPIRV::OpTypeFloat:
2133 case SPIRV::OpTypeBool:
2135 case SPIRV::OpTypePointer:
2137 case SPIRV::OpTypeVector: {
2140 switch (ElemType ? ElemType->
getOpcode() : 0) {
2141 case SPIRV::OpTypePointer:
2144 case SPIRV::OpTypeInt:
2145 case SPIRV::OpTypeFloat:
2146 case SPIRV::OpTypeBool:
2168 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2175 if (ScopeMD->getNumOperands() < 2)
2181 auto D = AliasInstMDMap.find(DomainMD);
2182 if (
D != AliasInstMDMap.end())
2189 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2191 auto S = AliasInstMDMap.find(ScopeMD);
2192 if (S != AliasInstMDMap.end())
2195 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2200 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2208 for (
auto *Scope : ScopeList)
2209 MIB.
addUse(Scope->getOperand(0).getReg());
2211 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2217 const MDNode *AliasingListMD) {
2244 B.CreateIntrinsic(Intrinsic::spv_value_md,
2246 AssignCI =
B.CreateIntrinsicWithoutFolding(Intrinsic::fake_use, {Arg});
2249 OfType, Arg, {},
B);
2259 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2260 if (AssignPtrTyCI ==
nullptr ||
2261 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2263 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2277 Intrinsic::spv_assign_ptr_type)
2286void SPIRVGlobalRegistry::addStructOffsetDecorations(
2289 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2295void SPIRVGlobalRegistry::addArrayStrideDecorations(
2297 uint32_t SizeInBytes = DL.getTypeAllocSize(ElementType);
2304 for (
const MachineInstr &Use :
2305 Type->getMF()->getRegInfo().use_instructions(Def)) {
2306 if (
Use.getOpcode() != SPIRV::OpDecorate)
2309 if (
Use.getOperand(1).getImm() == SPIRV::Decoration::Block)
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
static constexpr Value * getValue(Ty &ValueOrUse)
Promote Memory to Register
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool storageClassRequiresExplictLayout(SPIRV::StorageClass::StorageClass SC)
static Register createTypeVReg(MachineRegisterInfo &MRI)
static bool allowEmitFakeUse(const Value *Arg)
static unsigned typeToAddressSpace(const Type *Ty)
unsigned getAS(SPIRVTypeInst SpvType)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
uint64_t getNumElements() const
Type * getElementType() const
void setArgOperand(unsigned i, Value *v)
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValue() const
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
const APInt & getValue() const
Return the constant as an APInt value reference.
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
static LLVM_ABI ConstantTargetNone * get(TargetExtType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
Module * getParent()
Get the module that this global value is contained inside of...
@ ExternalLinkage
Externally visible function.
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
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isFP128Ty() const
Return true if this is 'fp128'.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isAggregateType() const
Return true if the type is an aggregate type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI TypedPointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
'undef' values are things that do not have specified contents.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
IRHandle handle(const Type *Ty)
IRHandle irhandle_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
IRHandle irhandle_padding()
IRHandle irhandle_vkbuffer(const Type *ElementType, StorageClass::StorageClass SC, bool IsWriteable)
IRHandle irhandle_sampler()
TargetExtType * parseBuiltinTypeNameToTargetExtType(std::string TypeName, LLVMContext &Context)
Translates a string representing a SPIR-V or OpenCL builtin type to a TargetExtType that can be furth...
IRHandle irhandle_event()
SPIRVTypeInst lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
IRHandle irhandle_pipe(uint8_t AQ)
IRHandle irhandle_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
unsigned getNumElements(Type *Ty)
This is an optimization pass for GlobalISel generic memory operations.
void addStringImm(StringRef Str, MCInst &Inst)
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getPointerAddressSpace(const Type *T)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
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)
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * getTypedPointerWrapper(Type *ElemTy, unsigned AS)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Type * toTypedPointer(Type *Ty)
bool isSpecialOpaqueType(const Type *Ty)
bool isPointerTy(const Type *T)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
const Type * unifyPtrType(const Type *Ty)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
std::function< void(Register)> StructOffsetDecorator
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool hasBuiltinTypePrefix(StringRef Name)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
bool isPointerTyOrWrapper(const Type *Ty)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
PoisonValue * getNormalizedPoisonValue(Type *Ty)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
MCRegisterClass TargetRegisterClass
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.