33 if (
auto PType = dyn_cast<TypedPointerType>(Ty))
34 return PType->getAddressSpace();
35 if (
auto PType = dyn_cast<PointerType>(Ty))
36 return PType->getAddressSpace();
37 if (
auto *ExtTy = dyn_cast<TargetExtType>(Ty);
39 return ExtTy->getIntParameter(0);
44 : PointerSize(PointerSize), Bound(0) {}
75 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
85 VRegToTypeMap[&MF][VReg] = SpirvType;
90 MRI.setRegClass(Res, &SPIRV::TYPERegClass);
100 return MIRBuilder.
buildInstr(SPIRV::OpTypeBool)
105unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(
unsigned Width)
const {
109 if (
ST.canUseExtension(
110 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers))
114 else if (Width <= 16)
116 else if (Width <= 32)
123SPIRVType *SPIRVGlobalRegistry::getOpTypeInt(
unsigned Width,
126 Width = adjustOpTypeIntWidth(Width);
130 if (
ST.canUseExtension(
131 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers)) {
132 MIRBuilder.buildInstr(SPIRV::OpExtension)
133 .addImm(SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers);
134 MIRBuilder.buildInstr(SPIRV::OpCapability)
135 .addImm(SPIRV::Capability::ArbitraryPrecisionIntegersINTEL);
137 return MIRBuilder.
buildInstr(SPIRV::OpTypeInt)
140 .addImm(IsSigned ? 1 : 0);
147 return MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
155 return MIRBuilder.
buildInstr(SPIRV::OpTypeVoid)
166 auto It = LastInsertedTypeMap.find(MF);
167 if (It == LastInsertedTypeMap.end())
169 if (It->second ==
MI)
170 LastInsertedTypeMap.erase(MF);
173SPIRVType *SPIRVGlobalRegistry::createOpType(
180 auto LastInsertedType = LastInsertedTypeMap.find(
CurMF);
181 if (LastInsertedType != LastInsertedTypeMap.end()) {
182 auto It = LastInsertedType->second->getIterator();
186 if (It->getParent() != NewMBB)
187 InsertAt = oldInsertPoint->getParent() == NewMBB
190 else if (It->getNextNode())
191 InsertAt = It->getNextNode()->getIterator();
197 auto Result = LastInsertedTypeMap.try_emplace(
CurMF,
nullptr);
199 LastInsertedType = Result.first;
206 LastInsertedType->second =
Type;
217 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
218 EleOpc == SPIRV::OpTypeBool) &&
219 "Invalid vector element type");
222 return MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
229std::tuple<Register, ConstantInt *, bool, unsigned>
238 bool NewInstr =
false;
253 return std::make_tuple(Res, CI, NewInstr,
BitWidth);
256std::tuple<Register, ConstantFP *, bool, unsigned>
257SPIRVGlobalRegistry::getOrCreateConstFloatReg(
APFloat Val,
SPIRVType *SpvType,
265 bool NewInstr =
false;
267 auto *
const CI = ConstantFP::get(Ctx, Val);
280 return std::make_tuple(Res, CI, NewInstr,
BitWidth);
293 getOrCreateConstFloatReg(Val, SpvType,
nullptr, &
I, &
TII);
296 if (!New && (!
I.getOperand(0).isReg() || Res !=
I.getOperand(0).getReg()))
303 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
305 .addUse(getSPIRVTypeID(SpvType));
307 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
309 .addUse(getSPIRVTypeID(SpvType));
311 APInt(BitWidth, CI->getValueAPF().bitcastToAPInt().getZExtValue()),
316 *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
332 getOrCreateConstIntReg(Val, SpvType,
nullptr, &
I, &
TII);
335 if (!New && (!
I.getOperand(0).isReg() || Res !=
I.getOperand(0).getReg()))
341 if (Val || !ZeroAsNull) {
342 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
347 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
353 *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
364 auto &MF = MIRBuilder.
getMF();
368 const auto ConstInt =
369 ConstantInt::get(
const_cast<IntegerType *
>(LLVMIntTy), Val);
374 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
375 MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
377 SPIRV::AccessQualifier::ReadWrite, EmitIR);
378 DT.
add(ConstInt, &MIRBuilder.
getMF(), Res);
385 if (Val || !ZeroAsNull) {
386 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantI)
391 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
397 *Subtarget.getRegisterInfo(),
398 *Subtarget.getRegBankInfo());
409 auto &MF = MIRBuilder.
getMF();
410 auto &Ctx = MF.getFunction().getContext();
416 const auto ConstFP = ConstantFP::get(Ctx, Val);
419 Res = MF.getRegInfo().createGenericVirtualRegister(
421 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
423 DT.
add(ConstFP, &MF, Res);
426 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantF)
429 addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB);
437Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
441 if (SpvType->
getOpcode() == SPIRV::OpTypeVector ||
442 SpvType->
getOpcode() == SPIRV::OpTypeArray) {
446 if (
Type->getOpcode() == SPIRV::OpTypeFloat) {
449 SpvBaseType,
TII, ZeroAsNull);
451 assert(
Type->getOpcode() == SPIRV::OpTypeInt);
454 SpvBaseType,
TII, ZeroAsNull);
457Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
460 unsigned ElemCnt,
bool ZeroAsNull) {
472 getOrCreateBaseRegister(Val,
I, SpvType,
TII,
BitWidth, ZeroAsNull);
484 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
487 for (
unsigned i = 0; i < ElemCnt; ++i)
490 MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
496 *Subtarget.getRegisterInfo(),
497 *Subtarget.getRegBankInfo());
515 auto *ConstVal = ConstantInt::get(LLVMBaseTy, Val);
519 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
534 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
538 return getOrCreateCompositeOrNull(ConstVal,
I, SpvType,
TII, ConstVec, BW,
548 const ArrayType *LLVMArrTy = cast<ArrayType>(LLVMTy);
550 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
563 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(LLVMBaseTy, Num)});
564 return getOrCreateCompositeOrNull(CI,
I, SpvType,
TII, UniqueKey, BW,
568Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
590 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpConstantComposite)
593 for (
unsigned i = 0; i < ElemCnt; ++i)
597 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
616 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
620 return getOrCreateIntCompositeOrNull(Val, MIRBuilder, SpvType, EmitIR,
640 return MIRBuilder.
buildInstr(SPIRV::OpConstantNull)
656 MIRBuilder)) ==
nullptr)
664 return MIRBuilder.
buildInstr(SPIRV::OpConstantSampler)
671 assert(Res->getOperand(0).isReg());
672 return Res->getOperand(0).getReg();
677 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
680 bool IsInstSelector) {
683 GVar = cast<const GlobalVariable>(GV);
688 GVar = M->getGlobalVariable(
Name);
689 if (GVar ==
nullptr) {
705 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpVariable)
716 if (IsInstSelector) {
719 *Subtarget.getRegisterInfo(),
720 *Subtarget.getRegBankInfo());
723 DT.
add(GVar, &MIRBuilder.
getMF(), Reg);
727 if (Reg != ResVReg) {
730 MRI->setType(Reg, RegLLTy);
737 if (!DefType || DefType !=
BaseType)
749 if (IsConst && ST.isOpenCLEnv())
754 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
761 SPIRV::BuiltIn::BuiltIn BuiltInId;
764 {
static_cast<uint32_t>(BuiltInId)});
770 if (GVar && (GVarMD = GVar->
getMetadata(
"spirv.Decorations")) !=
nullptr)
778 const std::string &Prefix);
782 switch (
Type->getOpcode()) {
783 case SPIRV::OpTypeSampledImage: {
786 case SPIRV::OpTypeImage: {
789 case SPIRV::OpTypeArray: {
792 auto *ElementType =
MRI->getUniqueVRegDef(ElementTypeReg);
802 case SPIRV::OpTypeFloat:
803 return (
"f" +
Twine(
Type->getOperand(1).getImm())).str();
804 case SPIRV::OpTypeSampler:
806 case SPIRV::OpTypeInt:
807 if (
Type->getOperand(2).getImm())
808 return (
"i" +
Twine(
Type->getOperand(1).getImm())).str();
809 return (
"u" +
Twine(
Type->getOperand(1).getImm())).str();
817 const std::string &Prefix) {
822 TypeName = (TypeName +
'_' +
Twine(
Type->getOperand(
I).getImm())).str();
831 VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
842 SPIRV::StorageClass::UniformConstant,
nullptr,
false,
843 false, SPIRV::LinkageType::Import, MIRBuilder,
false);
845 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
846 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
855 "Invalid array element type");
860 return MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
863 .addUse(NumElementsVReg);
873 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeOpaque).addDef(ResVReg);
884 for (
const auto &Elem : Ty->
elements()) {
887 "Invalid struct element type");
892 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
893 for (
const auto &Ty : FieldTypes)
903SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
905 SPIRV::AccessQualifier::AccessQualifier AccQual) {
910SPIRVType *SPIRVGlobalRegistry::getOpTypePointer(
911 SPIRV::StorageClass::StorageClass SC,
SPIRVType *ElemType,
917 return MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
924SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
927 return MIRBuilder.
buildInstr(SPIRV::OpTypeForwardPointer)
933SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
936 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
939 for (
const SPIRVType *ArgType : ArgTypes)
951 SPIRVType *SpirvType = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
953 return finishCreatingSPIRVType(Ty, SpirvType);
956SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
958 SPIRV::AccessQualifier::AccessQualifier AccQual,
bool EmitIR) {
959 Ty = adjustIntTypeByWidth(Ty);
963 if (ForwardPointerTypes.contains(Ty))
964 return ForwardPointerTypes[Ty];
965 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, EmitIR);
969 assert(SpirvType &&
"Attempting to get type id for nullptr type.");
970 if (SpirvType->
getOpcode() == SPIRV::OpTypeForwardPointer)
971 return SpirvType->
uses().begin()->getReg();
972 return SpirvType->
defs().begin()->getReg();
983const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(
const Type *Ty)
const {
984 if (
auto IType = dyn_cast<IntegerType>(Ty)) {
985 unsigned SrcBitWidth = IType->getBitWidth();
986 if (SrcBitWidth > 1) {
987 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
996SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
998 SPIRV::AccessQualifier::AccessQualifier AccQual,
bool EmitIR) {
1000 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1001 auto &TypeToSPIRVTypeMap = DT.
getTypes()->getAllUses();
1002 auto t = TypeToSPIRVTypeMap.find(Ty);
1003 if (t != TypeToSPIRVTypeMap.end()) {
1004 auto tt = t->second.find(&MIRBuilder.
getMF());
1005 if (tt != t->second.end())
1009 if (
auto IType = dyn_cast<IntegerType>(Ty)) {
1010 const unsigned Width = IType->getBitWidth();
1011 return Width == 1 ? getOpTypeBool(MIRBuilder)
1012 : getOpTypeInt(Width, MIRBuilder,
false);
1017 return getOpTypeVoid(MIRBuilder);
1020 findSPIRVType(cast<FixedVectorType>(Ty)->getElementType(), MIRBuilder);
1021 return getOpTypeVector(cast<FixedVectorType>(Ty)->
getNumElements(), El,
1028 if (
auto SType = dyn_cast<StructType>(Ty)) {
1029 if (SType->isOpaque())
1030 return getOpTypeOpaque(SType, MIRBuilder);
1031 return getOpTypeStruct(SType, MIRBuilder, EmitIR);
1033 if (
auto FType = dyn_cast<FunctionType>(Ty)) {
1034 SPIRVType *
RetTy = findSPIRVType(FType->getReturnType(), MIRBuilder);
1036 for (
const auto &t : FType->params()) {
1037 ParamTypes.
push_back(findSPIRVType(t, MIRBuilder));
1039 return getOpTypeFunction(
RetTy, ParamTypes, MIRBuilder);
1055 if (SpvElementType ==
nullptr) {
1056 if (!ForwardPointerTypes.contains(Ty))
1057 ForwardPointerTypes[Ty] = getOpTypeForwardPointer(SC, MIRBuilder);
1058 return ForwardPointerTypes[Ty];
1062 if (ForwardPointerTypes.contains(Ty)) {
1064 return getOpTypePointer(SC, SpvElementType, MIRBuilder, Reg);
1070SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
1072 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
1075 TypesInProcessing.insert(Ty);
1076 SPIRVType *SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
1077 TypesInProcessing.erase(Ty);
1083 if (SpirvType->
getOpcode() != SPIRV::OpTypeForwardPointer && !
Reg.isValid() &&
1085 if (
auto *ExtTy = dyn_cast<TargetExtType>(Ty);
1087 DT.
add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
1092 DT.
add(cast<TypedPointerType>(Ty)->getElementType(),
1107 auto t = VRegToTypeMap.find(MF ? MF :
CurMF);
1108 if (t != VRegToTypeMap.end()) {
1109 auto tt = t->second.find(VReg);
1110 if (tt != t->second.end())
1123 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
1125 if (
auto *ExtTy = dyn_cast<TargetExtType>(Ty);
1127 Reg = DT.
find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
1128 &MIRBuilder.
getMF());
1130 Ty = adjustIntTypeByWidth(Ty);
1133 Reg = DT.
find(cast<TypedPointerType>(Ty)->getElementType(),
1143 TypesInProcessing.clear();
1144 SPIRVType *STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
1146 for (
auto &
CU : ForwardPointerTypes) {
1147 const Type *Ty2 =
CU.first;
1149 if ((Reg = DT.
find(Ty2, &MIRBuilder.
getMF())).isValid())
1152 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, EmitIR);
1156 ForwardPointerTypes.clear();
1161 unsigned TypeOpcode)
const {
1163 assert(
Type &&
"isScalarOfType VReg has no type assigned");
1164 return Type->getOpcode() == TypeOpcode;
1168 unsigned TypeOpcode)
const {
1170 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
1171 if (
Type->getOpcode() == TypeOpcode)
1173 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1174 Register ScalarTypeVReg =
Type->getOperand(1).getReg();
1176 return ScalarType->
getOpcode() == TypeOpcode;
1190 return Type->getOpcode() == SPIRV::OpTypeVector
1191 ?
static_cast<unsigned>(
Type->getOperand(2).getImm())
1204 Register ScalarReg =
Type->getOpcode() == SPIRV::OpTypeVector
1205 ?
Type->getOperand(1).getReg()
1206 :
Type->getOperand(0).getReg();
1216 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1217 auto EleTypeReg =
Type->getOperand(1).getReg();
1220 if (
Type->getOpcode() == SPIRV::OpTypeInt ||
1221 Type->getOpcode() == SPIRV::OpTypeFloat)
1222 return Type->getOperand(1).getImm();
1223 if (
Type->getOpcode() == SPIRV::OpTypeBool)
1225 llvm_unreachable(
"Attempting to get bit width of non-integer/float type.");
1231 unsigned NumElements = 1;
1232 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
1233 NumElements =
static_cast<unsigned>(
Type->getOperand(2).getImm());
1236 return Type->getOpcode() == SPIRV::OpTypeInt ||
1237 Type->getOpcode() == SPIRV::OpTypeFloat
1238 ? NumElements *
Type->getOperand(1).getImm()
1244 if (
Type &&
Type->getOpcode() == SPIRV::OpTypeVector)
1246 return Type &&
Type->getOpcode() == SPIRV::OpTypeInt ?
Type :
nullptr;
1255 return PtrType && PtrType->
getOpcode() == SPIRV::OpTypePointer
1262 return ElemType ? ElemType->
getOpcode() : 0;
1267 if (!Type1 || !
Type2)
1273 if (Op1 == SPIRV::OpTypePointer &&
1276 if (Op2 == SPIRV::OpTypePointer &&
1281 return Bits1 > 0 && Bits1 == Bits2;
1284SPIRV::StorageClass::StorageClass
1288 Type->getOperand(1).isImm() &&
"Pointer type is expected");
1292SPIRV::StorageClass::StorageClass
1294 return static_cast<SPIRV::StorageClass::StorageClass
>(
1295 Type->getOperand(1).getImm());
1301 SPIRV::ImageFormat::ImageFormat ImageFormat,
1302 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1304 Depth, Arrayed, Multisampled, Sampled,
1305 ImageFormat, AccessQual);
1306 if (
auto *Res = checkSpecialInstr(TD, MIRBuilder))
1309 DT.
add(TD, &MIRBuilder.
getMF(), ResVReg);
1310 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeImage)
1320 if (AccessQual != SPIRV::AccessQualifier::None)
1328 if (
auto *Res = checkSpecialInstr(TD, MIRBuilder))
1331 DT.
add(TD, &MIRBuilder.
getMF(), ResVReg);
1337 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1339 if (
auto *Res = checkSpecialInstr(TD, MIRBuilder))
1342 DT.
add(TD, &MIRBuilder.
getMF(), ResVReg);
1343 return MIRBuilder.
buildInstr(SPIRV::OpTypePipe)
1351 if (
auto *Res = checkSpecialInstr(TD, MIRBuilder))
1354 DT.
add(TD, &MIRBuilder.
getMF(), ResVReg);
1364 if (
auto *Res = checkSpecialInstr(TD, MIRBuilder))
1367 DT.
add(TD, &MIRBuilder.
getMF(), ResVReg);
1368 return MIRBuilder.
buildInstr(SPIRV::OpTypeSampledImage)
1383 MIRBuilder.
buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1390 DT.
add(ExtensionType, &MIRBuilder.
getMF(), ResVReg);
1401 DT.
add(Ty, &MIRBuilder.
getMF(), ResVReg);
1417 SPIRV::StorageClass::StorageClass SC,
1418 SPIRV::AccessQualifier::AccessQualifier AQ) {
1419 unsigned VecElts = 0;
1442 TypeStr = TypeStr.
substr(strlen(
"*"));
1449 TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
1469SPIRVType *SPIRVGlobalRegistry::finishCreatingSPIRVType(
const Type *LLVMTy,
1480 unsigned SPIRVOPcode,
1486 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRVOPcode))
1491 return finishCreatingSPIRVType(LLVMTy, MIB);
1540 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypeBool))
1543 return finishCreatingSPIRVType(LLVMTy, MIB);
1563 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypeVector))
1568 return finishCreatingSPIRVType(LLVMTy, MIB);
1582 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypeArray))
1587 return finishCreatingSPIRVType(LLVMTy, MIB);
1592 SPIRV::StorageClass::StorageClass SC) {
1605 MIRBuilder.
getTII().
get(SPIRV::OpTypePointer))
1610 finishCreatingSPIRVType(LLVMTy, MIB);
1617 SPIRV::StorageClass::StorageClass SC) {
1640 MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUndef))
1645 *ST.getRegisterInfo(), *ST.getRegBankInfo());
1653 case SPIRV::OpTypeFloat:
1654 return &SPIRV::fIDRegClass;
1655 case SPIRV::OpTypePointer:
1656 return &SPIRV::pIDRegClass;
1657 case SPIRV::OpTypeVector: {
1659 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
1660 if (ElemOpcode == SPIRV::OpTypeFloat)
1661 return &SPIRV::vfIDRegClass;
1662 if (ElemOpcode == SPIRV::OpTypePointer)
1663 return &SPIRV::vpIDRegClass;
1664 return &SPIRV::vIDRegClass;
1667 return &SPIRV::iIDRegClass;
1672 static_cast<SPIRV::StorageClass::StorageClass
>(
1677 unsigned Opcode = SpvType ? SpvType->
getOpcode() : 0;
1679 case SPIRV::OpTypeInt:
1680 case SPIRV::OpTypeFloat:
1681 case SPIRV::OpTypeBool:
1683 case SPIRV::OpTypePointer:
1685 case SPIRV::OpTypeVector: {
1688 switch (ElemType ? ElemType->
getOpcode() : 0) {
1689 case SPIRV::OpTypePointer:
1692 case SPIRV::OpTypeInt:
1693 case SPIRV::OpTypeFloat:
1694 case SPIRV::OpTypeBool:
unsigned const MachineRegisterInfo * MRI
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static unsigned getNumElements(Type *Ty)
static Register createTypeVReg(MachineRegisterInfo &MRI)
unsigned getAS(SPIRVType *SpvType)
static std::string GetSpirvImageTypeName(const SPIRVType *Type, MachineIRBuilder &MIRBuilder, const std::string &Prefix)
static std::string buildSpirvTypeName(const SPIRVType *Type, MachineIRBuilder &MIRBuilder)
unsigned typeToAddressSpace(const Type *Ty)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Class to represent array types.
uint64_t getNumElements() const
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Type * getElementType() const
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
Class to represent fixed width SIMD vectors.
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
MaybeAlign getAlign() const
Returns the alignment of the given variable or 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.
Class to represent integer types.
static 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.
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>.
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands which may be register uses.
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
const ConstantInt * getCImm() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A Module instance is used to store all the information related to an LLVM module.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static 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
void add(const Type *Ty, const MachineFunction *MF, Register R)
Register find(const Type *Ty, const MachineFunction *MF)
const SPIRVDuplicatesTracker< Type > * getTypes()
SPIRVType * getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AccQual)
unsigned getNumScalarOrVectorTotalBitWidth(const SPIRVType *Type) const
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
Register getOrCreateGlobalVariableWithBinding(const SPIRVType *VarType, uint32_t Set, uint32_t Binding, MachineIRBuilder &MIRBuilder)
SPIRVType * assignFloatTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * assignVectTypeToVReg(SPIRVType *BaseType, unsigned NumElements, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
SPIRVType * getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder)
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR=true)
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType)
bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const
unsigned getScalarOrVectorComponentCount(Register VReg) const
SPIRVType * getOrCreateSPIRVFloatType(unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII)
SPIRVType * getOrCreateOpTypeImage(MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, SPIRV::Dim::Dim Dim, uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled, SPIRV::ImageFormat::ImageFormat ImageFormat, SPIRV::AccessQualifier::AccessQualifier AccQual)
bool isScalarOrVectorSigned(const SPIRVType *Type) const
SPIRVGlobalRegistry(unsigned PointerSize)
unsigned getPointerSize() const
SPIRVType * getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr)
SPIRVType * getPointeeType(SPIRVType *PtrType)
void invalidateMachineInstr(MachineInstr *MI)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init, bool IsConst, bool HasLinkageTy, SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
SPIRVType * assignIntTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
unsigned getPointeeTypeOp(Register PtrReg)
SPIRVType * getOrCreateOpTypeSampledImage(SPIRVType *ImageType, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
SPIRVType * getScalarOrVectorComponentType(Register VReg) const
SPIRVType * assignTypeToVReg(const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
SPIRVType * getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVType *RetType, const SmallVectorImpl< SPIRVType * > &ArgTypes, MachineIRBuilder &MIRBuilder)
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
Register getOrCreateConstVector(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
SPIRVType * getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVPointerType(SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SClass=SPIRV::StorageClass::Function)
SPIRVType * getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType, const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns, uint32_t Use)
SPIRVType * getResultType(Register VReg)
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
LLT getRegType(SPIRVType *SpvType) const
SPIRVType * getOrCreateSPIRVArrayType(SPIRVType *BaseType, unsigned NumElements, MachineInstr &I, const SPIRVInstrInfo &TII)
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
SPIRVType * getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, SPIRVType *SpvType)
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR=true, bool ZeroAsNull=true)
const SPIRVType * retrieveScalarOrVectorIntType(const SPIRVType *Type) const
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).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Class to represent struct types.
ArrayRef< Type * > elements() const
bool hasName() const
Return true if this is a named struct that has a non-empty name.
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...
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 Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
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
uint64_t getArrayNumElements() const
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVoidTy() const
Return true if this is 'void'.
static 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 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.
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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
SpecialTypeDescriptor make_descr_pipe(uint8_t AQ)
SpecialTypeDescriptor make_descr_sampler()
std::tuple< const Type *, unsigned, unsigned > SpecialTypeDescriptor
SpecialTypeDescriptor make_descr_event()
SpecialTypeDescriptor make_descr_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
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...
SPIRVType * lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
SpecialTypeDescriptor make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
Reg
All possible values of the reg field in the ModR/M byte.
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)
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
bool 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...
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
bool isTypedPointerTy(const Type *T)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Type * toTypedPointer(Type *Ty)
bool isSpecialOpaqueType(const Type *Ty)
bool isPointerTy(const Type *T)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
const Type * unifyPtrType(const Type *Ty)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
constexpr unsigned BitWidth
bool hasBuiltinTypePrefix(StringRef Name)
bool isPointerTyOrWrapper(const Type *Ty)
void addStringImm(const StringRef &Str, MCInst &Inst)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)
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.