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 && (I.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 && (I.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 (Reg.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 && Reg.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 || Type2)

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)

1318 .addImm(Depth)

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.