28#include "llvm/IR/IntrinsicsSPIRV.h"
43 if (LI->getType()->isAggregateType())
50 return PType->getAddressSpace();
52 return PType->getAddressSpace();
55 return ExtTy->getIntParameter(0);
62 case SPIRV::StorageClass::Uniform:
63 case SPIRV::StorageClass::PushConstant:
64 case SPIRV::StorageClass::StorageBuffer:
65 case SPIRV::StorageClass::PhysicalStorageBufferEXT:
67 case SPIRV::StorageClass::UniformConstant:
68 case SPIRV::StorageClass::Input:
69 case SPIRV::StorageClass::Output:
70 case SPIRV::StorageClass::Workgroup:
71 case SPIRV::StorageClass::CrossWorkgroup:
72 case SPIRV::StorageClass::Private:
73 case SPIRV::StorageClass::Function:
74 case SPIRV::StorageClass::Generic:
75 case SPIRV::StorageClass::AtomicCounter:
76 case SPIRV::StorageClass::Image:
77 case SPIRV::StorageClass::CallableDataNV:
78 case SPIRV::StorageClass::IncomingCallableDataNV:
79 case SPIRV::StorageClass::RayPayloadNV:
80 case SPIRV::StorageClass::HitAttributeNV:
81 case SPIRV::StorageClass::IncomingRayPayloadNV:
82 case SPIRV::StorageClass::ShaderRecordBufferNV:
83 case SPIRV::StorageClass::CodeSectionINTEL:
84 case SPIRV::StorageClass::DeviceOnlyINTEL:
85 case SPIRV::StorageClass::HostOnlyINTEL:
92 : DL(DL), Bound(0),
CurMF(nullptr) {}
94void SPIRVGlobalRegistry::constrainSelectedInstRegOperands(
98 *ST.getRegBankInfo());
130 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
140 VRegToTypeMap[&MF][VReg] = SpirvType;
154 return createConstOrTypeAtFunctionEntry(
155 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
156 return MIRBuilder.
buildInstr(SPIRV::OpTypeBool)
161unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(
unsigned Width)
const {
163 if (
ST.canUseExtension(
164 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
165 (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)))
169 else if (Width <= 16)
171 else if (Width <= 32)
173 else if (Width <= 64)
175 else if (Width <= 128)
180SPIRVTypeInst SPIRVGlobalRegistry::getOpTypeInt(
unsigned Width,
183 Width = adjustOpTypeIntWidth(Width);
184 const SPIRVSubtarget &
ST =
186 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
188 if (Width == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
190 .
addImm(SPIRV::Extension::SPV_INTEL_int4);
192 .
addImm(SPIRV::Capability::Int4TypeINTEL);
195 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers)) {
197 .
addImm(SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
199 .
addImm(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
201 return MIRBuilder.
buildInstr(SPIRV::OpTypeInt)
204 .
addImm(IsSigned ? 1 : 0);
209SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
211 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
213 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
220SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
222 SPIRV::FPEncoding::FPEncoding FPEncode) {
223 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
225 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
233 return createConstOrTypeAtFunctionEntry(
234 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
235 return MIRBuilder.
buildInstr(SPIRV::OpTypeVoid)
260 "Cannot invalidate aliasing instructions.");
261 assert(
MI->getOpcode() != SPIRV::OpFunction &&
262 "Cannot invalidate OpFunction.");
264 if (
MI->getOpcode() == SPIRV::OpFunctionCall) {
266 auto It = ForwardCalls.find(
F);
267 if (It != ForwardCalls.end()) {
268 It->second.erase(
MI);
269 if (It->second.empty())
270 ForwardCalls.erase(It);
276 auto It = LastInsertedTypeMap.find(MF);
277 if (It != LastInsertedTypeMap.end() && It->second ==
MI)
278 LastInsertedTypeMap.erase(MF);
283const MachineInstr *SPIRVGlobalRegistry::createConstOrTypeAtFunctionEntry(
290 auto LastInsertedType = LastInsertedTypeMap.find(
CurMF);
291 if (LastInsertedType != LastInsertedTypeMap.end()) {
292 auto It = LastInsertedType->second->getIterator();
296 if (It->getParent() != NewMBB)
297 InsertAt = oldInsertPoint->getParent() == NewMBB
300 else if (It->getNextNode())
301 InsertAt = It->getNextNode()->getIterator();
307 auto Result = LastInsertedTypeMap.try_emplace(
CurMF,
nullptr);
309 LastInsertedType = Result.first;
312 MachineInstr *ConstOrType =
Op(MIRBuilder);
316 LastInsertedType->second = ConstOrType;
319 while (
auto *
Next = LastInsertedType->second->getNextNode()) {
320 unsigned Opc =
Next->getOpcode();
321 if (
Opc == SPIRV::OpTypeStructContinuedINTEL ||
322 Opc == SPIRV::OpConstantCompositeContinuedINTEL ||
323 Opc == SPIRV::OpSpecConstantCompositeContinuedINTEL ||
324 Opc == SPIRV::OpCompositeConstructContinuedINTEL)
325 LastInsertedType->second =
Next;
335SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
SPIRVTypeInst ElemType,
338 assert(NumElems >= 2 &&
"SPIR-V OpTypeVector requires at least 2 components");
340 if (EleOpc == SPIRV::OpTypePointer) {
343 SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
347 "Vector of pointers requires SPV_INTEL_masked_gather_scatter "
352 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
353 EleOpc == SPIRV::OpTypeBool) &&
354 "Invalid vector element type");
357 return createConstOrTypeAtFunctionEntry(
358 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
359 return MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
371 auto *
const CF = ConstantFP::get(Ctx, Val);
373 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
374 MI->getOpcode() == SPIRV::OpConstantF))
375 return MI->getOperand(0).getReg();
386 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
387 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
393 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
398 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
402 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
409 constrainSelectedInstRegOperands(MIB);
421 SpvType,
TII, ZeroAsNull);
429 auto *
const CI = ConstantInt::get(
432 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
433 MI->getOpcode() == SPIRV::OpConstantI))
434 return MI->getOperand(0).getReg();
445 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
446 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
452 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
458 : SPIRV::OpConstantTrue)
461 }
else if (!CI->
isZero() || !ZeroAsNull) {
462 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
467 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
471 constrainSelectedInstRegOperands(MIB);
481 bool EmitIR,
bool ZeroAsNull) {
483 auto &MF = MIRBuilder.
getMF();
487 auto *
const CI = ConstantInt::get(
const_cast<IntegerType *
>(Ty), Val,
501 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
507 if (Val || !ZeroAsNull) {
508 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
513 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
517 constrainSelectedInstRegOperands(MIB);
527 auto &MF = MIRBuilder.
getMF();
531 SPIRV::AccessQualifier::ReadWrite,
true);
532 auto *
const CF = ConstantFP::get(Ctx, Val);
538 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
539 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
542 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
545 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
548 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
555Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
559 if (SpvType->
getOpcode() == SPIRV::OpTypeVector ||
560 SpvType->
getOpcode() == SPIRV::OpTypeArray) {
564 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
569 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
575Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
578 unsigned ElemCnt,
bool ZeroAsNull) {
586 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
589 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
593 MachineInstr *DepMI =
594 const_cast<MachineInstr *
>(
static_cast<const MachineInstr *
>(SpvType));
596 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
597 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
598 MachineInstrBuilder MIB;
600 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
603 for (
unsigned i = 0; i < ElemCnt; ++i)
606 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
610 constrainSelectedInstRegOperands(MIB);
623 I, SpvType,
TII, ZeroAsNull);
633 "Expected vector type for constant vector creation");
637 "Expected integer element type for APInt constant vector");
642 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
657 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
661 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
673 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
688 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(I64Ty, Num)});
689 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
693Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
710 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
716 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
719 for (
unsigned i = 0; i < ElemCnt; ++i)
724 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
739 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
743 return getOrCreateIntCompositeOrNull(
744 Val, MIRBuilder, SpvType, EmitIR, ConstVec, BW,
762 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
763 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
766 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
768 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
778 unsigned Param,
unsigned FilerMode,
791 MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
802 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
804 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
813 GVar = M->getGlobalVariable(Name);
814 if (GVar ==
nullptr) {
838 if (&GVBuilder.
getMBB() != &EntryBB)
841 auto MIB = GVBuilder.
buildInstr(SPIRV::OpVariable)
849 if (IsInstSelector) {
850 constrainSelectedInstRegOperands(MIB);
858 auto MRI = MIRBuilder.
getMRI();
859 if (Reg != ResVReg) {
862 MRI->setType(Reg, RegLLTy);
881 if (IsConst && !ST.isShader())
886 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
891 {
static_cast<uint32_t>(*LinkageType)}, Name);
893 SPIRV::BuiltIn::BuiltIn BuiltInId;
896 {
static_cast<uint32_t>(BuiltInId)});
902 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
919 std::nullopt, MIRBuilder,
false);
921 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
922 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
931 bool ExplicitLayoutRequired,
934 "Invalid array element type");
942 ArrayType = createConstOrTypeAtFunctionEntry(
944 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
955 ArrayType = createConstOrTypeAtFunctionEntry(
956 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
957 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
963 if (!
ST.isShader()) {
965 "Runtime arrays are not allowed in non-shader "
969 ArrayType = createConstOrTypeAtFunctionEntry(
970 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
971 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
979 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
987SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
992 return createConstOrTypeAtFunctionEntry(
993 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1003 SPIRV::AccessQualifier::AccessQualifier AccQual,
1005 Type *OriginalElementType =
nullptr;
1006 uint64_t TotalSize = 0;
1008 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
1009 OriginalElementType, MIRBuilder, AccQual,
1010 Decorator !=
nullptr, EmitIR);
1011 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
1012 Decorator !=
nullptr,
1016 const SPIRVSubtarget &
ST =
1019 constexpr unsigned MaxWordCount = UINT16_MAX;
1022 size_t MaxNumElements = MaxWordCount - 2;
1023 size_t SPIRVStructNumElements = NumElements;
1024 if (NumElements > MaxNumElements) {
1026 SPIRVStructNumElements = MaxNumElements;
1027 MaxNumElements = MaxWordCount - 1;
1030 for (
const auto &Elem : Ty->
elements()) {
1031 SPIRVTypeInst ElemTy = findSPIRVType(
1033 Decorator !=
nullptr, EmitIR);
1035 "Invalid struct element type");
1044 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1045 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1048 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1049 MIBStruct.
addUse(FieldTypes[
I]);
1050 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1051 I += MaxNumElements) {
1053 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1054 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1055 MIBCont.
addUse(FieldTypes[J]);
1061 Decorator(SPVType->defs().begin()->getReg());
1068 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1074 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1079 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1081 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1083 .
addImm(
static_cast<uint32_t
>(SC))
1090 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1092 return MIRBuilder.
buildInstr(SPIRV::OpTypeForwardPointer)
1094 .
addImm(
static_cast<uint32_t
>(SC));
1102 const SPIRVSubtarget *
ST =
1103 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1104 if (Ty->isVarArg() &&
ST->isShader()) {
1106 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1107 Fn,
"SPIR-V shaders do not support variadic functions",
1110 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1112 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1115 for (
auto &ArgType : ArgTypes)
1129 add(Ty,
false, NewMI);
1130 return finishCreatingSPIRVType(Ty, NewMI);
1135 SPIRV::AccessQualifier::AccessQualifier AccQual,
1136 bool ExplicitLayoutRequired,
bool EmitIR) {
1139 FVT && FVT->getNumElements() == 1)
1140 return findSPIRVType(FVT->getElementType(), MIRBuilder, AccQual,
1141 ExplicitLayoutRequired, EmitIR);
1142 Ty = adjustIntTypeByWidth(Ty);
1145 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1147 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1149 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1154 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1155 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1156 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1157 return SpirvType->
uses().
begin()->getReg();
1158 return SpirvType->
defs().
begin()->getReg();
1169const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1171 unsigned SrcBitWidth = IType->getBitWidth();
1172 if (SrcBitWidth > 1) {
1173 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1184 SPIRV::AccessQualifier::AccessQualifier AccQual,
1185 bool ExplicitLayoutRequired,
bool EmitIR) {
1187 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1189 if (
const MachineInstr *
MI =
1190 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1194 const unsigned Width = IType->getBitWidth();
1195 return Width == 1 ? getOpTypeBool(MIRBuilder)
1196 : getOpTypeInt(Width, MIRBuilder,
false);
1203 SPIRV::FPEncoding::BFloat16KHR);
1209 return getOpTypeVoid(MIRBuilder);
1213 AccQual, ExplicitLayoutRequired, EmitIR);
1219 AccQual, ExplicitLayoutRequired, EmitIR);
1221 ExplicitLayoutRequired, EmitIR);
1224 if (SType->isOpaque())
1225 return getOpTypeOpaque(SType, MIRBuilder);
1228 if (ExplicitLayoutRequired) {
1229 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1230 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1234 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1238 SPIRVTypeInst RetTy =
1239 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1240 ExplicitLayoutRequired, EmitIR);
1242 for (
const auto &ParamTy : FType->params())
1243 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1244 ExplicitLayoutRequired, EmitIR));
1245 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1251 const SPIRVSubtarget *
ST =
1252 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1255 SPIRVTypeInst SpvElementType =
nullptr;
1258 !
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
1271 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1274 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1282 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1283 bool ExplicitLayoutRequired,
bool EmitIR) {
1288 TypesInProcessing.insert(Ty);
1289 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1290 ExplicitLayoutRequired, EmitIR);
1291 TypesInProcessing.erase(Ty);
1298 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1304 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1306 add(Ty, ExplicitLayoutRequired, SpirvType);
1319 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1320 if (t != VRegToTypeMap.end()) {
1321 auto tt = t->second.find(VReg);
1322 if (tt != t->second.end())
1338 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1339 bool ExplicitLayoutRequired,
bool EmitIR) {
1342 FVT && FVT->getNumElements() == 1)
1344 ExplicitLayoutRequired, EmitIR);
1349 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1351 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1361 TypesInProcessing.clear();
1362 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1363 ExplicitLayoutRequired, EmitIR);
1365 for (
auto &
CU : ForwardPointerTypes) {
1368 bool PtrNeedsLayout =
false;
1369 const Type *Ty2 =
CU.first;
1371 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1374 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1379 ForwardPointerTypes.clear();
1384 unsigned TypeOpcode)
const {
1386 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1387 return Type->getOpcode() == TypeOpcode;
1391 unsigned TypeOpcode)
const {
1393 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1394 if (
Type->getOpcode() == TypeOpcode)
1396 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1397 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1399 return ScalarType->
getOpcode() == TypeOpcode;
1405 switch (
Type->getOpcode()) {
1406 case SPIRV::OpTypeImage:
1407 case SPIRV::OpTypeSampler:
1408 case SPIRV::OpTypeSampledImage:
1410 case SPIRV::OpTypeStruct:
1411 return hasBlockDecoration(
Type);
1426 return Type->getOpcode() == SPIRV::OpTypeVector
1427 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1435 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1436 ?
Type->getOperand(1).getReg()
1437 :
Type->getOperand(0).getReg();
1448 if (ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1449 ScalarType->
getOpcode() == SPIRV::OpTypeFloat)
1451 if (ScalarType->
getOpcode() == SPIRV::OpTypeBool)
1453 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1461 return ScalarType->
getOpcode() == SPIRV::OpTypeInt ||
1462 ScalarType->
getOpcode() == SPIRV::OpTypeFloat
1470 return ScalarType && ScalarType->
getOpcode() == SPIRV::OpTypeInt ? ScalarType
1480 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1487 return ElemType ? ElemType->
getOpcode() : 0;
1492 if (!Type1 || !Type2)
1498 if (Op1 == SPIRV::OpTypePointer &&
1501 if (Op2 == SPIRV::OpTypePointer &&
1506 return Bits1 > 0 && Bits1 == Bits2;
1509SPIRV::StorageClass::StorageClass
1513 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1517SPIRV::StorageClass::StorageClass
1519 return static_cast<SPIRV::StorageClass::StorageClass
>(
1525 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1536 ExplicitLayoutRequired, EmitIr);
1539 SPIRV::Decoration::Block, {});
1543 SPIRV::Decoration::NonWritable, 0, {});
1547 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1559 finishCreatingSPIRVType(
T, R);
1566 const auto SC = SPIRV::StorageClass::PushConstant;
1575 T, MIRBuilder, SPIRV::AccessQualifier::None,
1579 SPIRV::Decoration::Block, {});
1593 assert(ST->getNumElements() == Offsets.size());
1606 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1607 std::move(Decorator), EmitIr);
1608 add(
Key, SPIRVStructType);
1609 return SPIRVStructType;
1614 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1617 "SPIR-V image builtin type must have sampled type parameter!");
1620 SPIRV::AccessQualifier::ReadWrite,
true);
1623 "Invalid number of parameters for SPIR-V image builtin!");
1625 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1626 SPIRV::AccessQualifier::None;
1628 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1629 ? SPIRV::AccessQualifier::WriteOnly
1630 : SPIRV::AccessQualifier::AccessQualifier(
1636 MIRBuilder, SampledType,
1642 SPIRVToLLVMType[R] = ExtensionType;
1650 SPIRV::ImageFormat::ImageFormat ImageFormat,
1651 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1653 Depth, Arrayed, Multisampled, Sampled,
1654 ImageFormat, AccessQual);
1657 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1669 if (AccessQual != SPIRV::AccessQualifier::None)
1683 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1685 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1694 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1698 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1700 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1713 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1715 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1730 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1732 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1745 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1747 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1754 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1756 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1758 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1766 add(ExtensionType,
false, NewMI);
1774 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1778 add(Ty,
false, NewMI);
1788 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1794 if (Operand.isReg()) {
1795 MIB.
addUse(Operand.getReg());
1796 }
else if (Operand.isImm()) {
1797 MIB.
addImm(Operand.getImm());
1802 add(Ty,
false, NewMI);
1809 SPIRV::StorageClass::StorageClass SC,
1810 SPIRV::AccessQualifier::AccessQualifier AQ) {
1811 unsigned VecElts = 0;
1818 MIRBuilder, AQ,
false,
true);
1839 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1856 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1860SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1871 unsigned SPIRVOPcode,
Type *Ty) {
1876 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1879 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1883 if (!Ty->isFloatTy()) {
1884 return NewTypeMI.addImm(0);
1889 add(Ty,
false, NewMI);
1890 return finishCreatingSPIRVType(Ty, NewMI);
1930 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1941 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1944 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1947 add(Ty,
false, NewMI);
1948 return finishCreatingSPIRVType(Ty, NewMI);
1957 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1965 assert(NumElements >= 2 &&
"SPIR-V vectors must have at least 2 components");
1973 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1976 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
1981 add(Ty,
false, NewMI);
1982 return finishCreatingSPIRVType(Ty, NewMI);
1987 SPIRV::StorageClass::StorageClass SC) {
1994 SPIRV::StorageClass::StorageClass SC) {
1997 .canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1999 F.getContext().diagnose(
2001 "Function used as a data pointer requires "
2002 "SPV_INTEL_function_pointers extension",
2007 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
2010 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
2014 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
2016 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
2023 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
2028 SPIRV::StorageClass::StorageClass SC) {
2034 "The base type was not correctly laid out for the given storage class.");
2038SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
2040 SPIRV::StorageClass::StorageClass SC) {
2047 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2051 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2057 return finishCreatingSPIRVType(Ty, NewMI);
2070 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2071 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2077 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2080 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2083 constrainSelectedInstRegOperands(MIB);
2094 case SPIRV::OpTypeFloat:
2095 return &SPIRV::fIDRegClass;
2096 case SPIRV::OpTypePointer:
2097 return &SPIRV::pIDRegClass;
2098 case SPIRV::OpTypeVector: {
2100 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2101 if (ElemOpcode == SPIRV::OpTypeFloat)
2102 return &SPIRV::vfIDRegClass;
2103 if (ElemOpcode == SPIRV::OpTypePointer)
2104 return &SPIRV::vpIDRegClass;
2105 return &SPIRV::viIDRegClass;
2108 return &SPIRV::iIDRegClass;
2113 static_cast<SPIRV::StorageClass::StorageClass
>(
2118 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2120 case SPIRV::OpTypeInt:
2121 case SPIRV::OpTypeFloat:
2122 case SPIRV::OpTypeBool:
2124 case SPIRV::OpTypePointer:
2126 case SPIRV::OpTypeVector: {
2129 switch (ElemType ? ElemType->
getOpcode() : 0) {
2130 case SPIRV::OpTypePointer:
2133 case SPIRV::OpTypeInt:
2134 case SPIRV::OpTypeFloat:
2135 case SPIRV::OpTypeBool:
2157 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2164 if (ScopeMD->getNumOperands() < 2)
2170 auto D = AliasInstMDMap.find(DomainMD);
2171 if (
D != AliasInstMDMap.end())
2178 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2180 auto S = AliasInstMDMap.find(ScopeMD);
2181 if (S != AliasInstMDMap.end())
2184 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2189 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2197 for (
auto *Scope : ScopeList)
2198 MIB.
addUse(Scope->getOperand(0).getReg());
2200 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2206 const MDNode *AliasingListMD) {
2233 B.CreateIntrinsic(Intrinsic::spv_value_md,
2235 AssignCI =
B.CreateIntrinsicWithoutFolding(Intrinsic::fake_use, {Arg});
2238 OfType, Arg, {},
B);
2248 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2249 if (AssignPtrTyCI ==
nullptr ||
2250 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2252 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2266 Intrinsic::spv_assign_ptr_type)
2275void SPIRVGlobalRegistry::addStructOffsetDecorations(
2278 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2284void SPIRVGlobalRegistry::addArrayStrideDecorations(
2286 uint32_t SizeInBytes = DL.getTypeAllocSize(ElementType);
2293 for (
const MachineInstr &Use :
2294 Type->getMF()->getRegInfo().use_instructions(Def)) {
2295 if (
Use.getOpcode() != SPIRV::OpDecorate)
2298 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.
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
SPIRVTypeInst getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
bool isScalarOrVectorSigned(SPIRVTypeInst Type) const
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
SPIRVTypeInst getOrCreateOpTypeSampledImage(SPIRVTypeInst ImageType, MachineIRBuilder &MIRBuilder)
unsigned getNumScalarOrVectorTotalBitWidth(SPIRVTypeInst Type) const
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)
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.