LLVM: lib/Target/SPIRV/SPIRVGlobalRegistry.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
27#include
28#include
29
30using namespace llvm;
31
33 if (auto PType = dyn_cast(Ty))
34 return PType->getAddressSpace();
35 if (auto PType = dyn_cast(Ty))
36 return PType->getAddressSpace();
37 if (auto *ExtTy = dyn_cast(Ty);
39 return ExtTy->getIntParameter(0);
41}
42
44 : PointerSize(PointerSize), Bound(0) {}
45
52 return SpirvType;
53}
54
61 return SpirvType;
62}
63
70 return SpirvType;
71}
72
75 SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
79 return SpirvType;
80}
81
85 VRegToTypeMap[&MF][VReg] = SpirvType;
86}
87
89 auto Res = MRI.createGenericVirtualRegister(LLT::scalar(64));
90 MRI.setRegClass(Res, &SPIRV::TYPERegClass);
91 return Res;
92}
93
96}
97
99 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
100 return MIRBuilder.buildInstr(SPIRV::OpTypeBool)
102 });
103}
104
105unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(unsigned Width) const {
106 if (Width > 64)
109 if (ST.canUseExtension(
110 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers))
111 return Width;
112 if (Width <= 8)
113 Width = 8;
114 else if (Width <= 16)
115 Width = 16;
116 else if (Width <= 32)
117 Width = 32;
118 else
119 Width = 64;
120 return Width;
121}
122
123SPIRVType *SPIRVGlobalRegistry::getOpTypeInt(unsigned Width,
125 bool IsSigned) {
126 Width = adjustOpTypeIntWidth(Width);
129 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
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);
136 }
137 return MIRBuilder.buildInstr(SPIRV::OpTypeInt)
139 .addImm(Width)
140 .addImm(IsSigned ? 1 : 0);
141 });
142}
143
146 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
147 return MIRBuilder.buildInstr(SPIRV::OpTypeFloat)
149 .addImm(Width);
150 });
151}
152
154 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
155 return MIRBuilder.buildInstr(SPIRV::OpTypeVoid)
157 });
158}
159
161
162
163
164
166 auto It = LastInsertedTypeMap.find(MF);
167 if (It == LastInsertedTypeMap.end())
168 return;
169 if (It->second == MI)
170 LastInsertedTypeMap.erase(MF);
171}
172
173SPIRVType *SPIRVGlobalRegistry::createOpType(
176 auto oldInsertPoint = MIRBuilder.getInsertPt();
179
180 auto LastInsertedType = LastInsertedTypeMap.find(CurMF);
181 if (LastInsertedType != LastInsertedTypeMap.end()) {
182 auto It = LastInsertedType->second->getIterator();
183
184
186 if (It->getParent() != NewMBB)
187 InsertAt = oldInsertPoint->getParent() == NewMBB
188 ? oldInsertPoint
190 else if (It->getNextNode())
191 InsertAt = It->getNextNode()->getIterator();
192 else
194 MIRBuilder.setInsertPt(*NewMBB, InsertAt);
195 } else {
197 auto Result = LastInsertedTypeMap.try_emplace(CurMF, nullptr);
198 assert(Result.second);
199 LastInsertedType = Result.first;
200 }
201
203
204
206 LastInsertedType->second = Type;
207
208 MIRBuilder.setInsertPt(*OldMBB, oldInsertPoint);
210}
211
212SPIRVType *SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
215 auto EleOpc = ElemType->getOpcode();
216 (void)EleOpc;
217 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
218 EleOpc == SPIRV::OpTypeBool) &&
219 "Invalid vector element type");
220
221 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
222 return MIRBuilder.buildInstr(SPIRV::OpTypeVector)
225 .addImm(NumElems);
226 });
227}
228
229std::tuple<Register, ConstantInt *, bool, unsigned>
230SPIRVGlobalRegistry::getOrCreateConstIntReg(uint64_t Val, SPIRVType *SpvType,
238 bool NewInstr = false;
239
243 Res =
246 if (MIRBuilder)
248 else
251 NewInstr = true;
252 }
253 return std::make_tuple(Res, CI, NewInstr, BitWidth);
254}
255
256std::tuple<Register, ConstantFP *, bool, unsigned>
257SPIRVGlobalRegistry::getOrCreateConstFloatReg(APFloat Val, SPIRVType *SpvType,
265 bool NewInstr = false;
266
267 auto *const CI = ConstantFP::get(Ctx, Val);
270 Res =
273 if (MIRBuilder)
275 else
278 NewInstr = true;
279 }
280 return std::make_tuple(Res, CI, NewInstr, BitWidth);
281}
282
286 bool ZeroAsNull) {
290 bool New;
292 std::tie(Res, CI, New, BitWidth) =
293 getOrCreateConstFloatReg(Val, SpvType, nullptr, &I, &TII);
294
295
296 if (!New && (.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
297 return Res;
301
302 if (Val.isPosZero() && ZeroAsNull) {
303 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
304 .addDef(Res)
305 .addUse(getSPIRVTypeID(SpvType));
306 } else {
307 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
308 .addDef(Res)
309 .addUse(getSPIRVTypeID(SpvType));
310 addNumImm(
311 APInt(BitWidth, CI->getValueAPF().bitcastToAPInt().getZExtValue()),
312 MIB);
313 }
316 *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
317 return MIB;
318 });
319 return Res;
320}
321
325 bool ZeroAsNull) {
329 bool New;
331 std::tie(Res, CI, New, BitWidth) =
332 getOrCreateConstIntReg(Val, SpvType, nullptr, &I, &TII);
333
334
335 if (!New && (.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
336 return Res;
337
341 if (Val || !ZeroAsNull) {
342 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
343 .addDef(Res)
346 } else {
347 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
350 }
353 *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
354 return MIB;
355 });
356 return Res;
357}
358
362 bool ZeroAsNull) {
364 auto &MF = MIRBuilder.getMF();
367
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);
379 if (EmitIR) {
381 } else {
385 if (Val || !ZeroAsNull) {
386 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
387 .addDef(Res)
388 .addUse(SpvTypeReg);
390 } else {
391 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
394 }
397 *Subtarget.getRegisterInfo(),
398 *Subtarget.getRegBankInfo());
399 return MIB;
400 });
401 }
402 }
403 return Res;
404}
405
409 auto &MF = MIRBuilder.getMF();
410 auto &Ctx = MF.getFunction().getContext();
411 if (!SpvType) {
414 }
415
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)
427 .addDef(Res)
429 addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB);
430 return MIB;
431 });
432 }
433
434 return Res;
435}
436
437Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
441 if (SpvType->getOpcode() == SPIRV::OpTypeVector ||
442 SpvType->getOpcode() == SPIRV::OpTypeArray) {
445 }
446 if (Type->getOpcode() == SPIRV::OpTypeFloat) {
449 SpvBaseType, TII, ZeroAsNull);
450 }
451 assert(Type->getOpcode() == SPIRV::OpTypeInt);
454 SpvBaseType, TII, ZeroAsNull);
455}
456
457Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
460 unsigned ElemCnt, bool ZeroAsNull) {
461
463
464 bool IsNull = Val->isNullValue() && ZeroAsNull;
466
467
468
470 if (!IsNull)
471 SpvScalConst =
472 getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
473
479 DT.add(CA, CurMF, SpvVecConst);
483 if (!IsNull) {
484 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
485 .addDef(SpvVecConst)
487 for (unsigned i = 0; i < ElemCnt; ++i)
488 MIB.addUse(SpvScalConst);
489 } else {
490 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
491 .addDef(SpvVecConst)
493 }
496 *Subtarget.getRegisterInfo(),
497 *Subtarget.getRegBankInfo());
498 return MIB;
499 });
500 return SpvVecConst;
501 }
502 return Res;
503}
504
509 bool ZeroAsNull) {
512 const FixedVectorType *LLVMVecTy = cast(LLVMTy);
515 auto *ConstVal = ConstantInt::get(LLVMBaseTy, Val);
516 auto *ConstVec =
519 return getOrCreateCompositeOrNull(ConstVal, I, SpvType, TII, ConstVec, BW,
521 ZeroAsNull);
522}
523
528 bool ZeroAsNull) {
531 const FixedVectorType *LLVMVecTy = cast(LLVMTy);
534 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
535 auto *ConstVec =
538 return getOrCreateCompositeOrNull(ConstVal, I, SpvType, TII, ConstVec, BW,
540 ZeroAsNull);
541}
542
548 const ArrayType *LLVMArrTy = cast(LLVMTy);
550 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
553
554
555
556
557
558
559
560
563 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(LLVMBaseTy, Num)});
564 return getOrCreateCompositeOrNull(CI, I, SpvType, TII, UniqueKey, BW,
566}
567
568Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
574 if (Val || EmitIR) {
577 SpvScalConst = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
578 }
584 DT.add(CA, CurMF, SpvVecConst);
585 if (EmitIR) {
587 } else {
589 if (Val) {
590 auto MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
591 .addDef(SpvVecConst)
593 for (unsigned i = 0; i < ElemCnt; ++i)
594 MIB.addUse(SpvScalConst);
595 return MIB;
596 } else {
597 return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
598 .addDef(SpvVecConst)
600 }
601 });
602 }
603 return SpvVecConst;
604 }
605 return Res;
606}
607
611 SPIRVType *SpvType, bool EmitIR) {
614 const FixedVectorType *LLVMVecTy = cast(LLVMTy);
616 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
617 auto ConstVec =
620 return getOrCreateIntCompositeOrNull(Val, MIRBuilder, SpvType, EmitIR,
621 ConstVec, BW,
623}
624
630
640 return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
641 .addDef(Res)
643 });
645 }
646 return Res;
647}
648
650 Register ResReg, unsigned AddrMode, unsigned Param, unsigned FilerMode,
653 if (SpvType)
656 MIRBuilder)) == nullptr)
657 report_fatal_error("Unable to recognize SPIRV type name: opencl.sampler_t");
658
659 auto Sampler =
661 ? ResReg
663 auto Res = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
664 return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
665 .addDef(Sampler)
668 .addImm(Param)
669 .addImm(FilerMode);
670 });
671 assert(Res->getOperand(0).isReg());
672 return Res->getOperand(0).getReg();
673}
674
677 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
679 SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder,
680 bool IsInstSelector) {
682 if (GV)
683 GVar = cast(GV);
684 else {
685
686
688 GVar = M->getGlobalVariable(Name);
689 if (GVar == nullptr) {
691
695 }
696 GV = GVar;
697 }
699 if (Reg.isValid()) {
700 if (Reg != ResVReg)
701 MIRBuilder.buildCopy(ResVReg, Reg);
702 return ResVReg;
703 }
704
705 auto MIB = MIRBuilder.buildInstr(SPIRV::OpVariable)
709
710 if (Init != 0) {
711 MIB.addUse(Init->getOperand(0).getReg());
712 }
713
714
715
716 if (IsInstSelector) {
719 *Subtarget.getRegisterInfo(),
720 *Subtarget.getRegBankInfo());
721 }
723 DT.add(GVar, &MIRBuilder.getMF(), Reg);
725
726
728 if (Reg != ResVReg) {
729 LLT RegLLTy =
731 MRI->setType(Reg, RegLLTy);
733 } else {
734
735
736
738 if (!DefType || DefType != BaseType)
740 }
741
742
743 if (GVar && GVar->hasName())
745
746
747
750 if (IsConst && ST.isOpenCLEnv())
751 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Constant, {});
752
755 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
756 }
757
758 if (HasLinkageTy)
759 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::LinkageAttributes,
761
762 SPIRV::BuiltIn::BuiltIn BuiltInId;
764 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::BuiltIn,
765 {static_cast<uint32_t>(BuiltInId)});
766
767
768
769
770 MDNode *GVarMD = nullptr;
771 if (GVar && (GVarMD = GVar->getMetadata("spirv.Decorations")) != nullptr)
773
774 return Reg;
775}
776
779 const std::string &Prefix);
780
783 switch (Type->getOpcode()) {
784 case SPIRV::OpTypeSampledImage: {
786 }
787 case SPIRV::OpTypeImage: {
789 }
790 case SPIRV::OpTypeArray: {
792 Register ElementTypeReg = Type->getOperand(1).getReg();
793 auto *ElementType = MRI->getUniqueVRegDef(ElementTypeReg);
794 const SPIRVType *TypeInst = MRI->getVRegDef(Type->getOperand(2).getReg());
797 assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
801 .str();
802 }
803 case SPIRV::OpTypeFloat:
804 return ("f" + Twine(Type->getOperand(1).getImm())).str();
805 case SPIRV::OpTypeSampler:
806 return ("sampler");
807 case SPIRV::OpTypeInt:
808 if (Type->getOperand(2).getImm())
809 return ("i" + Twine(Type->getOperand(1).getImm())).str();
810 return ("u" + Twine(Type->getOperand(1).getImm())).str();
811 default:
812 llvm_unreachable("Trying to the the name of an unknown type.");
813 }
814}
815
818 const std::string &Prefix) {
819 Register SampledTypeReg = Type->getOperand(1).getReg();
821 std::string TypeName = Prefix + buildSpirvTypeName(SampledType, MIRBuilder);
823 TypeName = (TypeName + '_' + Twine(Type->getOperand(I).getImm())).str();
824 }
825 return TypeName;
826}
827
832 VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
835
836
837
838
840 "_" + Twine(Set) + "_" + Twine(Binding))
841 .str();
843 SPIRV::StorageClass::UniformConstant, nullptr, false,
844 false, SPIRV::LinkageType::Import, MIRBuilder, false);
845
846 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
847 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
848 return VarReg;
849}
850
854 bool EmitIR) {
856 "Invalid array element type");
859 buildConstantInt(NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
860 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
861 return MIRBuilder.buildInstr(SPIRV::OpTypeArray)
864 .addUse(NumElementsVReg);
865 });
866}
867
873 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
874 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeOpaque).addDef(ResVReg);
877 return MIB;
878 });
879}
880
883 bool EmitIR) {
885 for (const auto &Elem : Ty->elements()) {
887 assert(ElemTy && ElemTy->getOpcode() != SPIRV::OpTypeVoid &&
888 "Invalid struct element type");
890 }
892 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
893 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
894 for (const auto &Ty : FieldTypes)
899 buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
900 return MIB;
901 });
902}
903
904SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
906 SPIRV::AccessQualifier::AccessQualifier AccQual) {
909}
910
911SPIRVType *SPIRVGlobalRegistry::getOpTypePointer(
912 SPIRV::StorageClass::StorageClass SC, SPIRVType *ElemType,
914 if (.isValid())
916
917 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
918 return MIRBuilder.buildInstr(SPIRV::OpTypePointer)
919 .addDef(Reg)
920 .addImm(static_cast<uint32_t>(SC))
922 });
923}
924
925SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
926 SPIRV::StorageClass::StorageClass SC, MachineIRBuilder &MIRBuilder) {
927 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
928 return MIRBuilder.buildInstr(SPIRV::OpTypeForwardPointer)
930 .addImm(static_cast<uint32_t>(SC));
931 });
932}
933
934SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
937 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
940 for (const SPIRVType *ArgType : ArgTypes)
942 return MIB;
943}
944
950 if (Reg.isValid())
952 SPIRVType *SpirvType = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
954 return finishCreatingSPIRVType(Ty, SpirvType);
955}
956
957SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
959 SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
960 Ty = adjustIntTypeByWidth(Ty);
962 if (Reg.isValid())
964 if (ForwardPointerTypes.contains(Ty))
965 return ForwardPointerTypes[Ty];
966 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, EmitIR);
967}
968
970 assert(SpirvType && "Attempting to get type id for nullptr type.");
971 if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer)
972 return SpirvType->uses().begin()->getReg();
973 return SpirvType->defs().begin()->getReg();
974}
975
976
977
978
979
980
981
982
983
984const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(const Type *Ty) const {
985 if (auto IType = dyn_cast(Ty)) {
986 unsigned SrcBitWidth = IType->getBitWidth();
987 if (SrcBitWidth > 1) {
988 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
989
992 }
993 }
994 return Ty;
995}
996
997SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
999 SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
1001 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1002 auto &TypeToSPIRVTypeMap = DT.getTypes()->getAllUses();
1003 auto t = TypeToSPIRVTypeMap.find(Ty);
1004 if (t != TypeToSPIRVTypeMap.end()) {
1005 auto tt = t->second.find(&MIRBuilder.getMF());
1006 if (tt != t->second.end())
1008 }
1009
1010 if (auto IType = dyn_cast(Ty)) {
1011 const unsigned Width = IType->getBitWidth();
1012 return Width == 1 ? getOpTypeBool(MIRBuilder)
1013 : getOpTypeInt(Width, MIRBuilder, false);
1014 }
1018 return getOpTypeVoid(MIRBuilder);
1021 findSPIRVType(cast(Ty)->getElementType(), MIRBuilder);
1022 return getOpTypeVector(cast(Ty)->getNumElements(), El,
1023 MIRBuilder);
1024 }
1027 return getOpTypeArray(Ty->getArrayNumElements(), El, MIRBuilder, EmitIR);
1028 }
1029 if (auto SType = dyn_cast(Ty)) {
1030 if (SType->isOpaque())
1031 return getOpTypeOpaque(SType, MIRBuilder);
1032 return getOpTypeStruct(SType, MIRBuilder, EmitIR);
1033 }
1034 if (auto FType = dyn_cast(Ty)) {
1035 SPIRVType *RetTy = findSPIRVType(FType->getReturnType(), MIRBuilder);
1037 for (const auto &t : FType->params()) {
1038 ParamTypes.push_back(findSPIRVType(t, MIRBuilder));
1039 }
1040 return getOpTypeFunction(RetTy, ParamTypes, MIRBuilder);
1041 }
1042
1044 SPIRVType *SpvElementType = nullptr;
1047 else
1049
1050
1054
1055
1056 if (SpvElementType == nullptr) {
1057 if (!ForwardPointerTypes.contains(Ty))
1058 ForwardPointerTypes[Ty] = getOpTypeForwardPointer(SC, MIRBuilder);
1059 return ForwardPointerTypes[Ty];
1060 }
1061
1062
1063 if (ForwardPointerTypes.contains(Ty)) {
1065 return getOpTypePointer(SC, SpvElementType, MIRBuilder, Reg);
1066 }
1067
1069}
1070
1071SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
1073 SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
1075 return nullptr;
1076 TypesInProcessing.insert(Ty);
1077 SPIRVType *SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
1078 TypesInProcessing.erase(Ty);
1079 VRegToTypeMap[&MIRBuilder.getMF()][getSPIRVTypeID(SpirvType)] = SpirvType;
1080 SPIRVToLLVMType[SpirvType] = unifyPtrType(Ty);
1082
1083
1084 if (SpirvType->getOpcode() != SPIRV::OpTypeForwardPointer && .isValid() &&
1086 if (auto *ExtTy = dyn_cast(Ty);
1088 DT.add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
1093 DT.add(cast(Ty)->getElementType(),
1096 else
1100 }
1101
1102 return SpirvType;
1103}
1104
1108 auto t = VRegToTypeMap.find(MF ? MF : CurMF);
1109 if (t != VRegToTypeMap.end()) {
1110 auto tt = t->second.find(VReg);
1111 if (tt != t->second.end())
1112 return tt->second;
1113 }
1114 return nullptr;
1115}
1116
1119 if (!MF)
1123}
1124
1127 SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
1129 if (auto *ExtTy = dyn_cast(Ty);
1131 Reg = DT.find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
1132 &MIRBuilder.getMF());
1134 Ty = adjustIntTypeByWidth(Ty);
1135 Reg = DT.find(Ty, &MIRBuilder.getMF());
1137 Reg = DT.find(cast(Ty)->getElementType(),
1139 } else {
1140 Reg =
1143 }
1144
1147 TypesInProcessing.clear();
1148 SPIRVType *STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
1149
1150 for (auto &CU : ForwardPointerTypes) {
1151 const Type *Ty2 = CU.first;
1153 if ((Reg = DT.find(Ty2, &MIRBuilder.getMF())).isValid())
1155 else
1156 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, EmitIR);
1157 if (Ty == Ty2)
1158 STy = STy2;
1159 }
1160 ForwardPointerTypes.clear();
1161 return STy;
1162}
1163
1165 unsigned TypeOpcode) const {
1167 assert(Type && "isScalarOfType VReg has no type assigned");
1168 return Type->getOpcode() == TypeOpcode;
1169}
1170
1172 unsigned TypeOpcode) const {
1174 assert(Type && "isScalarOrVectorOfType VReg has no type assigned");
1175 if (Type->getOpcode() == TypeOpcode)
1176 return true;
1177 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1178 Register ScalarTypeVReg = Type->getOperand(1).getReg();
1180 return ScalarType->getOpcode() == TypeOpcode;
1181 }
1182 return false;
1183}
1184
1185unsigned
1188}
1189
1190unsigned
1193 return 0;
1194 return Type->getOpcode() == SPIRV::OpTypeVector
1195 ? static_cast<unsigned>(Type->getOperand(2).getImm())
1196 : 1;
1197}
1198
1202}
1203
1207 return nullptr;
1208 Register ScalarReg = Type->getOpcode() == SPIRV::OpTypeVector
1209 ? Type->getOperand(1).getReg()
1210 : Type->getOperand(0).getReg();
1214 return ScalarType;
1215}
1216
1217unsigned
1219 assert(Type && "Invalid Type pointer");
1220 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1221 auto EleTypeReg = Type->getOperand(1).getReg();
1223 }
1224 if (Type->getOpcode() == SPIRV::OpTypeInt ||
1225 Type->getOpcode() == SPIRV::OpTypeFloat)
1226 return Type->getOperand(1).getImm();
1227 if (Type->getOpcode() == SPIRV::OpTypeBool)
1228 return 1;
1229 llvm_unreachable("Attempting to get bit width of non-integer/float type.");
1230}
1231
1234 assert(Type && "Invalid Type pointer");
1235 unsigned NumElements = 1;
1236 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1237 NumElements = static_cast<unsigned>(Type->getOperand(2).getImm());
1239 }
1240 return Type->getOpcode() == SPIRV::OpTypeInt ||
1241 Type->getOpcode() == SPIRV::OpTypeFloat
1242 ? NumElements * Type->getOperand(1).getImm()
1243 : 0;
1244}
1245
1248 if (Type && Type->getOpcode() == SPIRV::OpTypeVector)
1250 return Type && Type->getOpcode() == SPIRV::OpTypeInt ? Type : nullptr;
1251}
1252
1256}
1257
1259 return PtrType && PtrType->getOpcode() == SPIRV::OpTypePointer
1261 : nullptr;
1262}
1263
1266 return ElemType ? ElemType->getOpcode() : 0;
1267}
1268
1271 if (!Type1 || )
1272 return false;
1273 auto Op1 = Type1->getOpcode(), Op2 = Type2->getOpcode();
1274
1275
1276
1277 if (Op1 == SPIRV::OpTypePointer &&
1279 return true;
1280 if (Op2 == SPIRV::OpTypePointer &&
1282 return true;
1285 return Bits1 > 0 && Bits1 == Bits2;
1286}
1287
1288SPIRV::StorageClass::StorageClass
1291 assert(Type && Type->getOpcode() == SPIRV::OpTypePointer &&
1292 Type->getOperand(1).isImm() && "Pointer type is expected");
1294}
1295
1296SPIRV::StorageClass::StorageClass
1298 return static_castSPIRV::StorageClass::StorageClass\(
1299 Type->getOperand(1).getImm());
1300}
1301
1305 SPIRV::ImageFormat::ImageFormat ImageFormat,
1306 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1308 Depth, Arrayed, Multisampled, Sampled,
1309 ImageFormat, AccessQual);
1310 if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
1311 return Res;
1313 DT.add(TD, &MIRBuilder.getMF(), ResVReg);
1314 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeImage)
1319 .addImm(Arrayed)
1320 .addImm(Multisampled)
1321 .addImm(Sampled)
1322 .addImm(ImageFormat);
1323
1324 if (AccessQual != SPIRV::AccessQualifier::None)
1325 MIB.addImm(AccessQual);
1326 return MIB;
1327}
1328
1332 if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
1333 return Res;
1335 DT.add(TD, &MIRBuilder.getMF(), ResVReg);
1336 return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
1337}
1338
1341 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1343 if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
1344 return Res;
1346 DT.add(TD, &MIRBuilder.getMF(), ResVReg);
1347 return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
1349 .addImm(AccessQual);
1350}
1351
1355 if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
1356 return Res;
1358 DT.add(TD, &MIRBuilder.getMF(), ResVReg);
1359 return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent).addDef(ResVReg);
1360}
1361
1367 ImageType);
1368 if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
1369 return Res;
1371 DT.add(TD, &MIRBuilder.getMF(), ResVReg);
1372 return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
1375}
1376
1387 MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1394 DT.add(ExtensionType, &MIRBuilder.getMF(), ResVReg);
1395 return SpirvTy;
1396}
1397
1405 DT.add(Ty, &MIRBuilder.getMF(), ResVReg);
1406 return SpirvTy;
1407}
1408
1413 if (Reg.isValid())
1415 return nullptr;
1416}
1417
1418
1421 SPIRV::StorageClass::StorageClass SC,
1422 SPIRV::AccessQualifier::AccessQualifier AQ) {
1423 unsigned VecElts = 0;
1425
1426
1430 MIRBuilder, AQ);
1431
1432
1433
1435
1437 if (!Ty)
1438
1439 return nullptr;
1440
1442
1443
1446 TypeStr = TypeStr.substr(strlen("*"));
1447 }
1448
1449
1450 bool IsPtrToVec = TypeStr.consume_back("*");
1451
1453 TypeStr = TypeStr.substr(0, TypeStr.find(']'));
1454 }
1456 if (VecElts > 0)
1458
1459 if (IsPtrToVec)
1461
1462 return SpirvTy;
1463}
1464
1470 MIRBuilder);
1471}
1472
1473SPIRVType *SPIRVGlobalRegistry::finishCreatingSPIRVType(const Type *LLVMTy,
1477 SPIRVToLLVMType[SpirvType] = unifyPtrType(LLVMTy);
1478 return SpirvType;
1479}
1480
1484 unsigned SPIRVOPcode,
1485 Type *LLVMTy) {
1487 if (Reg.isValid())
1490 auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRVOPcode))
1495 return finishCreatingSPIRVType(LLVMTy, MIB);
1496}
1497
1500
1501
1502
1503
1507}
1508
1512 Type *LLVMTy;
1514 case 16:
1516 break;
1517 case 32:
1519 break;
1520 case 64:
1522 break;
1523 default:
1525 }
1527}
1528
1533 MIRBuilder);
1534}
1535
1541 if (Reg.isValid())
1544 auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeBool))
1547 return finishCreatingSPIRVType(LLVMTy, MIB);
1548}
1549
1554 NumElements),
1555 MIRBuilder);
1556}
1557
1564 if (Reg.isValid())
1567 auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeVector))
1570 .addImm(NumElements);
1572 return finishCreatingSPIRVType(LLVMTy, MIB);
1573}
1574
1581 if (Reg.isValid())
1586 auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeArray))
1591 return finishCreatingSPIRVType(LLVMTy, MIB);
1592}
1593
1596 SPIRV::StorageClass::StorageClass SC) {
1601
1603 if (Reg.isValid())
1605
1606 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1609 MIRBuilder.getTII().get(SPIRV::OpTypePointer))
1614 finishCreatingSPIRVType(LLVMTy, MIB);
1615 return MIB;
1616 });
1617}
1618
1621 SPIRV::StorageClass::StorageClass SC) {
1624}
1625
1632
1636 return Res;
1642
1644 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
1649 *ST.getRegisterInfo(), *ST.getRegBankInfo());
1650 return Res;
1651}
1652
1655 unsigned Opcode = SpvType->getOpcode();
1656 switch (Opcode) {
1657 case SPIRV::OpTypeFloat:
1658 return &SPIRV::fIDRegClass;
1659 case SPIRV::OpTypePointer:
1660 return &SPIRV::pIDRegClass;
1661 case SPIRV::OpTypeVector: {
1663 unsigned ElemOpcode = ElemType ? ElemType->getOpcode() : 0;
1664 if (ElemOpcode == SPIRV::OpTypeFloat)
1665 return &SPIRV::vfIDRegClass;
1666 if (ElemOpcode == SPIRV::OpTypePointer)
1667 return &SPIRV::vpIDRegClass;
1668 return &SPIRV::vIDRegClass;
1669 }
1670 }
1671 return &SPIRV::iIDRegClass;
1672}
1673
1676 static_castSPIRV::StorageClass::StorageClass\(
1678}
1679
1681 unsigned Opcode = SpvType ? SpvType->getOpcode() : 0;
1682 switch (Opcode) {
1683 case SPIRV::OpTypeInt:
1684 case SPIRV::OpTypeFloat:
1685 case SPIRV::OpTypeBool:
1687 case SPIRV::OpTypePointer:
1689 case SPIRV::OpTypeVector: {
1692 switch (ElemType ? ElemType->getOpcode() : 0) {
1693 case SPIRV::OpTypePointer:
1695 break;
1696 case SPIRV::OpTypeInt:
1697 case SPIRV::OpTypeFloat:
1698 case SPIRV::OpTypeBool:
1700 break;
1701 default:
1703 }
1705 static_cast<unsigned>(SpvType->getOperand(2).getImm()), ET);
1706 }
1707 }
1709}
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 = Opcode .
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)
SPIRVType * getResultType(Register VReg, MachineFunction *MF=nullptr)
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)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
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 * 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.