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 : PointerSize(PointerSize), Bound(0),
CurMF(nullptr) {}
123 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
133 VRegToTypeMap[&MF][VReg] = SpirvType;
138 MRI.setRegClass(Res, &SPIRV::TYPERegClass);
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;
316SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
SPIRVTypeInst ElemType,
320 assert(NumElems >= 2 &&
"SPIR-V OpTypeVector requires at least 2 components");
321 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
322 EleOpc == SPIRV::OpTypeBool) &&
323 "Invalid vector element type");
325 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
327 return MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
339 auto *
const CF = ConstantFP::get(Ctx, Val);
341 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
342 MI->getOpcode() == SPIRV::OpConstantF))
343 return MI->getOperand(0).getReg();
354 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
355 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
361 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
366 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
370 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
377 const auto &ST =
CurMF->getSubtarget();
379 *ST.getRegisterInfo(),
380 *ST.getRegBankInfo());
392 SpvType,
TII, ZeroAsNull);
400 auto *
const CI = ConstantInt::get(
403 if (
MI && (
MI->getOpcode() == SPIRV::OpConstantNull ||
404 MI->getOpcode() == SPIRV::OpConstantI))
405 return MI->getOperand(0).getReg();
416 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
417 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
423 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
429 : SPIRV::OpConstantTrue)
432 }
else if (!CI->
isZero() || !ZeroAsNull) {
433 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
438 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
442 const auto &ST =
CurMF->getSubtarget();
444 *ST.getRegisterInfo(),
445 *ST.getRegBankInfo());
455 bool EmitIR,
bool ZeroAsNull) {
457 auto &MF = MIRBuilder.
getMF();
461 auto *
const CI = ConstantInt::get(
const_cast<IntegerType *
>(Ty), Val,
470 Res =
MRI.createGenericVirtualRegister(LLTy);
471 MRI.setRegClass(Res, &SPIRV::iIDRegClass);
475 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
481 if (Val || !ZeroAsNull) {
482 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
487 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
491 const auto &Subtarget =
CurMF->getSubtarget();
493 *Subtarget.getRegisterInfo(),
494 *Subtarget.getRegBankInfo());
504 auto &MF = MIRBuilder.
getMF();
508 SPIRV::AccessQualifier::ReadWrite,
true);
509 auto *
const CF = ConstantFP::get(Ctx, Val);
515 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
516 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
519 const MachineInstr *Const = createConstOrTypeAtFunctionEntry(
522 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
525 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
532Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
536 if (SpvType->
getOpcode() == SPIRV::OpTypeVector ||
537 SpvType->
getOpcode() == SPIRV::OpTypeArray) {
541 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
546 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
552Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
555 unsigned ElemCnt,
bool ZeroAsNull) {
563 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
566 Register Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
570 MachineInstr *DepMI =
571 const_cast<MachineInstr *
>(
static_cast<const MachineInstr *
>(SpvType));
573 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
574 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
575 MachineInstrBuilder MIB;
577 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
580 for (
unsigned i = 0; i < ElemCnt; ++i)
583 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
587 const auto &Subtarget =
CurMF->getSubtarget();
589 *Subtarget.getRegisterInfo(),
590 *Subtarget.getRegBankInfo());
603 I, SpvType,
TII, ZeroAsNull);
613 "Expected vector type for constant vector creation");
617 "Expected integer element type for APInt constant vector");
622 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
637 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
641 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
653 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
668 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(I64Ty, Num)});
669 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
673Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
690 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
696 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
699 for (
unsigned i = 0; i < ElemCnt; ++i)
704 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
719 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
723 return getOrCreateIntCompositeOrNull(Val, MIRBuilder, SpvType, EmitIR,
742 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
743 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
746 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
748 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
758 unsigned Param,
unsigned FilerMode,
771 MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
782 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
784 const std::optional<SPIRV::LinkageType::LinkageType> &LinkageType,
793 GVar = M->getGlobalVariable(Name);
794 if (GVar ==
nullptr) {
812 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpVariable)
820 if (IsInstSelector) {
821 const auto &Subtarget =
CurMF->getSubtarget();
823 *Subtarget.getRegisterInfo(),
824 *Subtarget.getRegBankInfo());
833 if (Reg != ResVReg) {
836 MRI->setType(Reg, RegLLTy);
855 if (IsConst && !ST.isShader())
860 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
865 {
static_cast<uint32_t>(*LinkageType)}, Name);
867 SPIRV::BuiltIn::BuiltIn BuiltInId;
870 {
static_cast<uint32_t>(BuiltInId)});
876 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
893 std::nullopt, MIRBuilder,
false);
895 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
896 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
905 bool ExplicitLayoutRequired,
908 "Invalid array element type");
916 ArrayType = createConstOrTypeAtFunctionEntry(
918 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
929 ArrayType = createConstOrTypeAtFunctionEntry(
930 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
931 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
937 if (!
ST.isShader()) {
939 "Runtime arrays are not allowed in non-shader "
943 ArrayType = createConstOrTypeAtFunctionEntry(
944 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
945 return MIRBuilder.
buildInstr(SPIRV::OpTypeRuntimeArray)
953 addArrayStrideDecorations(
ArrayType->defs().begin()->getReg(), ET,
961SPIRVGlobalRegistry::getOpTypeOpaque(
const StructType *Ty,
966 return createConstOrTypeAtFunctionEntry(
967 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
977 SPIRV::AccessQualifier::AccessQualifier AccQual,
979 Type *OriginalElementType =
nullptr;
980 uint64_t TotalSize = 0;
982 SPIRVTypeInst ElementSPIRVType = findSPIRVType(
983 OriginalElementType, MIRBuilder, AccQual,
984 Decorator !=
nullptr, EmitIR);
985 return getOpTypeArray(TotalSize, ElementSPIRVType, MIRBuilder,
986 Decorator !=
nullptr,
990 const SPIRVSubtarget &
ST =
993 constexpr unsigned MaxWordCount = UINT16_MAX;
996 size_t MaxNumElements = MaxWordCount - 2;
997 size_t SPIRVStructNumElements = NumElements;
998 if (NumElements > MaxNumElements) {
1000 SPIRVStructNumElements = MaxNumElements;
1001 MaxNumElements = MaxWordCount - 1;
1004 for (
const auto &Elem : Ty->
elements()) {
1005 SPIRVTypeInst ElemTy = findSPIRVType(
1007 Decorator !=
nullptr, EmitIR);
1009 "Invalid struct element type");
1018 SPIRVTypeInst SPVType = createConstOrTypeAtFunctionEntry(
1019 MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1022 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1023 MIBStruct.
addUse(FieldTypes[
I]);
1024 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1025 I += MaxNumElements) {
1027 MIRBuilder.
buildInstr(SPIRV::OpTypeStructContinuedINTEL);
1028 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1029 MIBCont.
addUse(FieldTypes[
I]);
1035 Decorator(SPVType->defs().begin()->getReg());
1042 SPIRV::AccessQualifier::AccessQualifier AccQual) {
1048 SPIRV::StorageClass::StorageClass SC,
SPIRVTypeInst ElemType,
1053 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1055 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
1057 .
addImm(
static_cast<uint32_t
>(SC))
1064 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1066 return MIRBuilder.
buildInstr(SPIRV::OpTypeForwardPointer)
1068 .
addImm(
static_cast<uint32_t
>(SC));
1076 const SPIRVSubtarget *
ST =
1077 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1078 if (Ty->isVarArg() &&
ST->isShader()) {
1080 Ty->getContext().diagnose(DiagnosticInfoUnsupported(
1081 Fn,
"SPIR-V shaders do not support variadic functions",
1084 return createConstOrTypeAtFunctionEntry(MIRBuilder, [&](MachineIRBuilder
1086 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
1089 for (
auto &ArgType : ArgTypes)
1103 add(Ty,
false, NewMI);
1104 return finishCreatingSPIRVType(Ty, NewMI);
1109 SPIRV::AccessQualifier::AccessQualifier AccQual,
1110 bool ExplicitLayoutRequired,
bool EmitIR) {
1111 Ty = adjustIntTypeByWidth(Ty);
1114 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1116 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
1118 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
1123 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
1124 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1125 SpirvType->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1126 return SpirvType->
uses().
begin()->getReg();
1127 return SpirvType->
defs().
begin()->getReg();
1138const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
1140 unsigned SrcBitWidth = IType->getBitWidth();
1141 if (SrcBitWidth > 1) {
1142 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1153 SPIRV::AccessQualifier::AccessQualifier AccQual,
1154 bool ExplicitLayoutRequired,
bool EmitIR) {
1156 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1158 if (
const MachineInstr *
MI =
1159 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.
getMF()))
1163 const unsigned Width = IType->getBitWidth();
1164 return Width == 1 ? getOpTypeBool(MIRBuilder)
1165 : getOpTypeInt(Width, MIRBuilder,
false);
1170 SPIRV::FPEncoding::BFloat16KHR);
1176 return getOpTypeVoid(MIRBuilder);
1180 AccQual, ExplicitLayoutRequired, EmitIR);
1186 AccQual, ExplicitLayoutRequired, EmitIR);
1188 ExplicitLayoutRequired, EmitIR);
1191 if (SType->isOpaque())
1192 return getOpTypeOpaque(SType, MIRBuilder);
1195 if (ExplicitLayoutRequired) {
1196 Decorator = [&MIRBuilder, SType,
this](
Register Reg) {
1197 addStructOffsetDecorations(
Reg,
const_cast<StructType *
>(SType),
1201 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1205 SPIRVTypeInst RetTy =
1206 findSPIRVType(FType->getReturnType(), MIRBuilder, AccQual,
1207 ExplicitLayoutRequired, EmitIR);
1209 for (
const auto &ParamTy : FType->params())
1210 ParamTypes.
push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1211 ExplicitLayoutRequired, EmitIR));
1212 return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
1216 SPIRVTypeInst SpvElementType =
nullptr;
1223 const SPIRVSubtarget *
ST =
1224 static_cast<const SPIRVSubtarget *
>(&MIRBuilder.
getMF().getSubtarget());
1234 if (
auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1237 return getOpTypePointer(SC, SpvElementType, MIRBuilder,
Reg);
1245 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1246 bool ExplicitLayoutRequired,
bool EmitIR) {
1251 TypesInProcessing.insert(Ty);
1252 SPIRVTypeInst SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1253 ExplicitLayoutRequired, EmitIR);
1254 TypesInProcessing.erase(Ty);
1261 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer ||
1267 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1269 add(Ty, ExplicitLayoutRequired, SpirvType);
1282 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1283 if (t != VRegToTypeMap.end()) {
1284 auto tt = t->second.find(VReg);
1285 if (tt != t->second.end())
1301 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1302 bool ExplicitLayoutRequired,
bool EmitIR) {
1305 FVT && FVT->getNumElements() == 1)
1307 ExplicitLayoutRequired, EmitIR);
1312 Reg =
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1314 Reg =
find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1324 TypesInProcessing.clear();
1325 SPIRVTypeInst STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1326 ExplicitLayoutRequired, EmitIR);
1328 for (
auto &
CU : ForwardPointerTypes) {
1331 bool PtrNeedsLayout =
false;
1332 const Type *Ty2 =
CU.first;
1334 if ((Reg =
find(Ty2, PtrNeedsLayout, MF)).
isValid())
1337 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1342 ForwardPointerTypes.clear();
1347 unsigned TypeOpcode)
const {
1349 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1350 return Type->getOpcode() == TypeOpcode;
1354 unsigned TypeOpcode)
const {
1356 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1357 if (
Type->getOpcode() == TypeOpcode)
1359 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1360 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1362 return ScalarType->
getOpcode() == TypeOpcode;
1368 switch (
Type->getOpcode()) {
1369 case SPIRV::OpTypeImage:
1370 case SPIRV::OpTypeSampler:
1371 case SPIRV::OpTypeSampledImage:
1373 case SPIRV::OpTypeStruct:
1374 return hasBlockDecoration(
Type);
1389 return Type->getOpcode() == SPIRV::OpTypeVector
1390 ?
static_cast<unsigned>(
Type->getOperand(2).
getImm())
1398 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1399 ?
Type->getOperand(1).getReg()
1400 :
Type->getOperand(0).getReg();
1410 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1411 auto EleTypeReg =
Type->getOperand(1).getReg();
1414 if (
Type->getOpcode() == SPIRV::OpTypeInt ||
1415 Type->getOpcode() == SPIRV::OpTypeFloat)
1416 return Type->getOperand(1).getImm();
1417 if (
Type->getOpcode() == SPIRV::OpTypeBool)
1419 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1425 unsigned NumElements = 1;
1426 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1427 NumElements =
static_cast<unsigned>(
Type->getOperand(2).
getImm());
1430 return Type->getOpcode() == SPIRV::OpTypeInt ||
1431 Type->getOpcode() == SPIRV::OpTypeFloat
1432 ? NumElements *
Type->getOperand(1).getImm()
1438 if (
Type &&
Type->getOpcode() == SPIRV::OpTypeVector)
1440 return Type &&
Type->getOpcode() == SPIRV::OpTypeInt ?
Type :
nullptr;
1449 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1456 return ElemType ? ElemType->
getOpcode() : 0;
1461 if (!Type1 || !Type2)
1467 if (Op1 == SPIRV::OpTypePointer &&
1470 if (Op2 == SPIRV::OpTypePointer &&
1475 return Bits1 > 0 && Bits1 == Bits2;
1478SPIRV::StorageClass::StorageClass
1482 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1486SPIRV::StorageClass::StorageClass
1488 return static_cast<SPIRV::StorageClass::StorageClass
>(
1494 SPIRV::StorageClass::StorageClass SC,
bool IsWritable,
bool EmitIr) {
1505 ExplicitLayoutRequired, EmitIr);
1508 SPIRV::Decoration::Block, {});
1512 SPIRV::Decoration::NonWritable, 0, {});
1516 getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1528 finishCreatingSPIRVType(
T, R);
1535 const auto SC = SPIRV::StorageClass::PushConstant;
1544 T, MIRBuilder, SPIRV::AccessQualifier::None,
1548 SPIRV::Decoration::Block, {});
1562 assert(ST->getNumElements() == Offsets.size());
1575 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1576 std::move(Decorator), EmitIr);
1577 add(
Key, SPIRVStructType);
1578 return SPIRVStructType;
1583 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1586 "SPIR-V image builtin type must have sampled type parameter!");
1589 SPIRV::AccessQualifier::ReadWrite,
true);
1592 "Invalid number of parameters for SPIR-V image builtin!");
1594 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1595 SPIRV::AccessQualifier::None;
1597 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1598 ? SPIRV::AccessQualifier::WriteOnly
1599 : SPIRV::AccessQualifier::AccessQualifier(
1605 MIRBuilder, SampledType,
1611 SPIRVToLLVMType[R] = ExtensionType;
1619 SPIRV::ImageFormat::ImageFormat ImageFormat,
1620 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1622 Depth, Arrayed, Multisampled, Sampled,
1623 ImageFormat, AccessQual);
1626 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1638 if (AccessQual != SPIRV::AccessQualifier::None)
1652 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1654 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampler)
1663 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1667 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1669 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1682 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1684 return MIRBuilder.
buildInstr(SPIRV::OpTypeDeviceEvent)
1699 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1701 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1714 findMI(ExtensionType,
false, &MIRBuilder.
getMF()))
1716 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1723 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1725 .
addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1727 return MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1735 add(ExtensionType,
false, NewMI);
1743 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1747 add(Ty,
false, NewMI);
1757 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1763 if (Operand.isReg()) {
1764 MIB.
addUse(Operand.getReg());
1765 }
else if (Operand.isImm()) {
1766 MIB.
addImm(Operand.getImm());
1771 add(Ty,
false, NewMI);
1778 SPIRV::StorageClass::StorageClass SC,
1779 SPIRV::AccessQualifier::AccessQualifier AQ) {
1780 unsigned VecElts = 0;
1787 MIRBuilder, AQ,
false,
true);
1808 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1825 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false,
true);
1829SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1840 unsigned SPIRVOPcode,
Type *Ty) {
1845 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1848 MIRBuilder.
getDL(),
TII.get(SPIRVOPcode))
1852 if (!Ty->isFloatTy()) {
1853 return NewTypeMI.addImm(0);
1858 add(Ty,
false, NewMI);
1859 return finishCreatingSPIRVType(Ty, NewMI);
1899 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1910 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1913 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeBool))
1916 add(Ty,
false, NewMI);
1917 return finishCreatingSPIRVType(Ty, NewMI);
1926 MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false, EmitIR);
1939 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
1942 MIRBuilder.
getDL(),
TII.get(SPIRV::OpTypeVector))
1947 add(Ty,
false, NewMI);
1948 return finishCreatingSPIRVType(Ty, NewMI);
1953 SPIRV::StorageClass::StorageClass SC) {
1960 SPIRV::StorageClass::StorageClass SC) {
1963 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
1966 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
1970 SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC,
1972 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
1979 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
1984 SPIRV::StorageClass::StorageClass SC) {
1990 "The base type was not correctly laid out for the given storage class.");
1994SPIRVTypeInst SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
1996 SPIRV::StorageClass::StorageClass SC) {
2003 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2007 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
2013 return finishCreatingSPIRVType(Ty, NewMI);
2026 Res =
CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
2027 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
2033 const MachineInstr *NewMI = createConstOrTypeAtFunctionEntry(
2036 MIRBuilder.
getDL(),
TII.get(SPIRV::OpUndef))
2039 const auto &ST =
CurMF->getSubtarget();
2041 *ST.getRegisterInfo(),
2042 *ST.getRegBankInfo());
2053 case SPIRV::OpTypeFloat:
2054 return &SPIRV::fIDRegClass;
2055 case SPIRV::OpTypePointer:
2056 return &SPIRV::pIDRegClass;
2057 case SPIRV::OpTypeVector: {
2060 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
2061 if (ElemOpcode == SPIRV::OpTypeFloat)
2062 return &SPIRV::vfIDRegClass;
2063 if (ElemOpcode == SPIRV::OpTypePointer)
2064 return &SPIRV::vpIDRegClass;
2065 return &SPIRV::vIDRegClass;
2068 return &SPIRV::iIDRegClass;
2073 static_cast<SPIRV::StorageClass::StorageClass
>(
2078 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
2080 case SPIRV::OpTypeInt:
2081 case SPIRV::OpTypeFloat:
2082 case SPIRV::OpTypeBool:
2084 case SPIRV::OpTypePointer:
2086 case SPIRV::OpTypeVector: {
2090 switch (ElemType ? ElemType->
getOpcode() : 0) {
2091 case SPIRV::OpTypePointer:
2094 case SPIRV::OpTypeInt:
2095 case SPIRV::OpTypeFloat:
2096 case SPIRV::OpTypeBool:
2119 if (
auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
2126 if (ScopeMD->getNumOperands() < 2)
2132 auto D = AliasInstMDMap.find(DomainMD);
2133 if (
D != AliasInstMDMap.end())
2135 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2140 AliasInstMDMap.insert(std::make_pair(DomainMD,
Domain));
2142 auto S = AliasInstMDMap.find(ScopeMD);
2143 if (S != AliasInstMDMap.end())
2145 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2146 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpAliasScopeDeclINTEL)
2151 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
2156 const Register Ret =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
2159 for (
auto *Scope : ScopeList)
2160 MIB.
addUse(Scope->getOperand(0).getReg());
2162 AliasInstMDMap.
insert(std::make_pair(AliasingListMD,
List));
2168 const MDNode *AliasingListMD) {
2195 B.CreateIntrinsic(Intrinsic::spv_value_md,
2197 AssignCI =
B.CreateIntrinsic(Intrinsic::fake_use, {Arg});
2200 OfType, Arg, {},
B);
2210 B.GetInsertBlock() ?
B.GetInsertBlock()->getParent() :
nullptr;
2211 if (AssignPtrTyCI ==
nullptr ||
2212 AssignPtrTyCI->
getParent()->getParent() != CurrF) {
2214 Intrinsic::spv_assign_ptr_type, {Arg->
getType()}, OfType, Arg,
2228 Intrinsic::spv_assign_ptr_type)
2237void SPIRVGlobalRegistry::addStructOffsetDecorations(
2241 for (
uint32_t I = 0;
I < Ty->getNumElements(); ++
I) {
2247void SPIRVGlobalRegistry::addArrayStrideDecorations(
2249 uint32_t SizeInBytes = DataLayout().getTypeSizeInBits(ElementType) / 8;
2256 for (
const MachineInstr &Use :
2257 Type->getMF()->getRegInfo().use_instructions(Def)) {
2258 if (
Use.getOpcode() != SPIRV::OpDecorate)
2261 if (
Use.getOperand(1).getImm() == SPIRV::Decoration::Block)
unsigned const MachineRegisterInfo * MRI
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
Promote Memory to Register
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static unsigned getNumElements(Type *Ty)
static bool storageClassRequiresExplictLayout(SPIRV::StorageClass::StorageClass SC)
static Register createTypeVReg(MachineRegisterInfo &MRI)
static bool allowEmitFakeUse(const Value *Arg)
static unsigned typeToAddressSpace(const Type *Ty)
unsigned getAS(SPIRVTypeInst SpvType)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
ArrayRef - 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.
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,...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
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.
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 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.
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.
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...
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
SPIRVTypeInst getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
bool isScalarOrVectorSigned(SPIRVTypeInst Type) const
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
SPIRVTypeInst getOrCreateOpTypeSampledImage(SPIRVTypeInst ImageType, MachineIRBuilder &MIRBuilder)
unsigned getNumScalarOrVectorTotalBitWidth(SPIRVTypeInst Type) const
SPIRVTypeInst assignVectTypeToVReg(SPIRVTypeInst BaseType, unsigned NumElements, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
void assignSPIRVTypeToVReg(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
SPIRVTypeInst getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVTypeInst RetType, const SmallVectorImpl< SPIRVTypeInst > &ArgTypes, MachineIRBuilder &MIRBuilder)
void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg)
const TargetRegisterClass * getRegClass(SPIRVTypeInst SpvType) const
MachineInstr * getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD)
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVVectorType(SPIRVTypeInst BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
SPIRVTypeInst getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
Register buildGlobalVariable(Register Reg, SPIRVTypeInst BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init, bool IsConst, const std::optional< SPIRV::LinkageType::LinkageType > &LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
SPIRVTypeInst assignIntTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
SPIRVTypeInst getResultType(Register VReg, MachineFunction *MF=nullptr)
void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld=true)
SPIRVTypeInst getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
unsigned getScalarOrVectorComponentCount(Register VReg) const
SPIRVTypeInst assignFloatTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const
void addDeducedElementType(Value *Val, Type *Ty)
SPIRVGlobalRegistry(unsigned PointerSize)
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
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.
StringRef - 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
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Class to represent struct types.
ArrayRef< Type * > elements() const
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
unsigned getNumElements() const
Random access to the elements.
bool hasName() const
Return true if this is a named struct that has a non-empty name.
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
unsigned getNumIntParameters() const
Type * getTypeParameter(unsigned i) const
unsigned getNumTypeParameters() const
unsigned getIntParameter(unsigned i) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
Type * getArrayElementType() const
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
LLVM_ABI uint64_t getArrayNumElements() const
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isAggregateType() const
Return true if the type is an aggregate type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI TypedPointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
'undef' values are things that do not have specified contents.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
IRHandle handle(const Type *Ty)
IRHandle irhandle_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
IRHandle irhandle_padding()
IRHandle irhandle_vkbuffer(const Type *ElementType, StorageClass::StorageClass SC, bool IsWriteable)
IRHandle irhandle_sampler()
TargetExtType * parseBuiltinTypeNameToTargetExtType(std::string TypeName, LLVMContext &Context)
Translates a string representing a SPIR-V or OpenCL builtin type to a TargetExtType that can be furth...
IRHandle irhandle_event()
SPIRVTypeInst lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
IRHandle irhandle_pipe(uint8_t AQ)
IRHandle irhandle_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getPointerAddressSpace(const Type *T)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
bool matchPeeledArrayPattern(const StructType *Ty, Type *&OriginalElementType, uint64_t &TotalSize)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
MetadataAsValue * buildMD(Value *Arg)
bool isTypedPointerTy(const Type *T)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * getTypedPointerWrapper(Type *ElemTy, unsigned AS)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Type * toTypedPointer(Type *Ty)
bool isSpecialOpaqueType(const Type *Ty)
bool isPointerTy(const Type *T)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
const Type * unifyPtrType(const Type *Ty)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
std::function< void(Register)> StructOffsetDecorator
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool hasBuiltinTypePrefix(StringRef Name)
bool isPointerTyOrWrapper(const Type *Ty)
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
PoisonValue * getNormalizedPoisonValue(Type *Ty)
void addStringImm(const StringRef &Str, MCInst &Inst)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.