LLVM: lib/Target/SPIRV/SPIRVPreLegalizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

25#include "llvm/IR/IntrinsicsSPIRV.h"

27

28#define DEBUG_TYPE "spirv-prelegalizer"

29

30using namespace llvm;

31

32namespace {

34public:

35 static char ID;

38 }

41};

42}

43

44void SPIRVPreLegalizer::getAnalysisUsage(AnalysisUsage &AU) const {

47}

48

49static void

60 continue;

62 Register SrcReg = MI.getOperand(2).getReg();

63 auto *Const =

64 cast(cast(

65 MI.getOperand(3).getMetadata()->getOperand(0))

66 ->getValue());

67 if (auto *GV = dyn_cast(Const)) {

69 if (!Reg.isValid()) {

70 GR->add(GV, &MF, SrcReg);

72 } else

73 RegsAlreadyAddedToDT[&MI] = Reg;

74 } else {

76 if (!Reg.isValid()) {

77 if (auto *ConstVec = dyn_cast(Const)) {

78 auto *BuildVec = MRI.getVRegDef(SrcReg);

80 BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);

81 for (unsigned i = 0; i < ConstVec->getNumElements(); ++i) {

82

83

84 Constant *ElemConst = ConstVec->getElementAsConstant(i);

87 GR->add(ElemConst, &MF, BuildVec->getOperand(1 + i).getReg());

88 else

89 BuildVec->getOperand(1 + i).setReg(ElemReg);

90 }

91 }

92 GR->add(Const, &MF, SrcReg);

93 TrackedConstRegs.insert(SrcReg);

94 if (Const->getType()->isTargetExtTy()) {

95

97 if (SrcMI && (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT ||

98 SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))

99 TargetExtConstTypes[SrcMI] = Const->getType();

100 if (Const->isNullValue()) {

107 }

108 }

109 } else {

110 RegsAlreadyAddedToDT[&MI] = Reg;

111

112

113 assert(MI.getOperand(2).isReg() && "Reg operand is expected");

115 if (SrcMI && isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))

116 ToEraseComposites.push_back(SrcMI);

117 }

118 }

119 }

120 }

122 Register Reg = MI->getOperand(2).getReg();

123 if (RegsAlreadyAddedToDT.contains(MI))

124 Reg = RegsAlreadyAddedToDT[MI];

125 auto *RC = MRI.getRegClassOrNull(MI->getOperand(0).getReg());

126 if (MRI.getRegClassOrNull(Reg) && RC)

127 MRI.setRegClass(Reg, RC);

128 MRI.replaceRegWith(MI->getOperand(0).getReg(), Reg);

129 MI->eraseFromParent();

130 }

132 MI->eraseFromParent();

133}

134

135static void

140 const unsigned AssignNameOperandShift = 2;

144 continue;

145 unsigned NumOp = MI.getNumExplicitDefs() + AssignNameOperandShift;

146 while (MI.getOperand(NumOp).isReg()) {

149 assert(ConstMI->getOpcode() == TargetOpcode::G_CONSTANT);

150 MI.removeOperand(NumOp);

154 if (MRI.use_empty(DefReg) && !TrackedConstRegs.contains(DefReg))

156 }

157 }

158 }

160 MI->eraseFromParent();

161}

162

166 IE = MRI->use_instr_end();

167 I != IE; ++I) {

173 }

174 return nullptr;

175}

176

181 assert(ResType && OpType && "Operand types are expected");

183 report_fatal_error("incompatible result and operand types in a bitcast");

185 if (MRI->getRegClassOrNull(ResVReg))

187 if (ResType == OpType)

189 else

194}

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

219 if (MI.getOpcode() != TargetOpcode::G_BITCAST)

220 continue;

223 MI.getOperand(1).getReg());

225 }

226 }

228 MI->eraseFromParent();

229}

230

233

241 continue;

242 assert(MI.getOperand(2).isReg());

246 MIB.buildBitcast(MI.getOperand(0).getReg(), MI.getOperand(2).getReg());

247 continue;

248 }

249 Register Def = MI.getOperand(0).getReg();

250 Register Source = MI.getOperand(2).getReg();

256

257

258

261

264 MRI->replaceRegWith(Def, Source);

265 } else {

268 }

269 }

270 }

272 MI->eraseFromParent();

273}

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

293 assert(MI && "Machine instr is expected");

294 if (MI->getOperand(0).isReg()) {

295 Register Reg = MI->getOperand(0).getReg();

297 if (!SpvType) {

298 switch (MI->getOpcode()) {

299 case TargetOpcode::G_FCONSTANT:

300 case TargetOpcode::G_CONSTANT: {

302 Type *Ty = MI->getOperand(1).getCImm()->getType();

304 break;

305 }

306 case TargetOpcode::G_GLOBAL_VALUE: {

311 Global->getType()->getAddressSpace());

313 break;

314 }

315 case TargetOpcode::G_ANYEXT:

316 case TargetOpcode::G_SEXT:

317 case TargetOpcode::G_ZEXT: {

318 if (MI->getOperand(1).isReg()) {

320 MRI.getVRegDef(MI->getOperand(1).getReg())) {

323 unsigned ExpectedBW =

324 std::max(MRI.getType(Reg).getScalarSizeInBits(), CurrentBW);

327 if (NumElements > 1)

328 SpvType =

330 }

331 }

332 }

333 break;

334 }

335 case TargetOpcode::G_PTRTOINT:

337 MRI.getType(Reg).getScalarSizeInBits(), MIB);

338 break;

339 case TargetOpcode::G_TRUNC:

340 case TargetOpcode::G_ADDRSPACE_CAST:

341 case TargetOpcode::G_PTR_ADD:

342 case TargetOpcode::COPY: {

345 if (Def)

347 break;

348 }

349 default:

350 break;

351 }

352 if (SpvType) {

353

354 LLT RegType = MRI.getType(Reg);

355 if (SpvType->getOpcode() == SPIRV::OpTypePointer &&

360 MI->getParent()->getParent()->getSubtarget<SPIRVSubtarget>();

364 }

366 }

367 if (MRI.getRegClassOrNull(Reg))

368 MRI.setRegClass(Reg, SpvType ? GR->getRegClass(SpvType)

369 : &SPIRV::iIDRegClass);

370 }

371 }

372 return SpvType;

373}

374

375

376

377

379 LLT RegType = MRI.getType(Reg);

381 return;

383 if (Sz == 1)

384 return;

385 unsigned NewSz = std::min(std::max(1u << Log2_32_Ceil(Sz), 8u), 64u);

386 if (NewSz != Sz)

388}

389

390static std::pair<Register, unsigned>

393 if (!SpvType)

397 MRI.setRegClass(Reg, RC);

398 unsigned GetIdOp = SPIRV::GET_ID;

399 if (RC == &SPIRV::fIDRegClass)

400 GetIdOp = SPIRV::GET_fID;

401 else if (RC == &SPIRV::pIDRegClass)

402 GetIdOp = SPIRV::GET_pID;

403 else if (RC == &SPIRV::vfIDRegClass)

404 GetIdOp = SPIRV::GET_vfID;

405 else if (RC == &SPIRV::vpIDRegClass)

406 GetIdOp = SPIRV::GET_vpID;

407 else if (RC == &SPIRV::vIDRegClass)

408 GetIdOp = SPIRV::GET_vID;

409 return {Reg, GetIdOp};

410}

411

415 Def->getNextNode() ? Def->getNextNode()->getIterator() : MBB.end();

416

417 while (DefIt != MBB.end() &&

418 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))

419 DefIt = std::next(DefIt);

421}

422

423

424

425

426

427

428namespace llvm {

432 assert((Ty || SpvType) && "Either LLVM or SPIRV type is expected.");

436 Register NewReg = MRI.createGenericVirtualRegister(MRI.getType(Reg));

437 if (auto *RC = MRI.getRegClassOrNull(Reg)) {

438 MRI.setRegClass(NewReg, RC);

439 } else {

440 auto RegClass = GR->getRegClass(SpvType);

441 MRI.setRegClass(NewReg, RegClass);

442 MRI.setRegClass(Reg, RegClass);

443 }

445

446

448

449

450 const uint32_t Flags = Def->getFlags();

456 for (unsigned I = 0, E = Def->getNumDefs(); I != E; ++I) {

458 if (MO.getReg() == Reg) {

460 break;

461 }

462 }

463 return NewReg;

464}

465

469 for (auto &Op : MI.operands()) {

470 if (Op.isReg() || Op.isDef())

471 continue;

477 if (RC != MRI.getRegClassOrNull(OpReg))

478 MRI.setRegClass(OpReg, RC);

479 Op.setReg(IdOpInfo.first);

480 }

481}

482}

483

484static void

488

491

495

496 bool IsExtendedInts =

497 ST->canUseExtension(

498 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||

499 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);

500

503 continue;

504

505 bool ReachedBegin = false;

506 for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();

507 !ReachedBegin;) {

509 unsigned MIOp = MI.getOpcode();

510

511 if (!IsExtendedInts) {

512

513 for (const auto &MOP : MI.operands())

514 if (MOP.isReg())

516 }

517

519 Register Reg = MI.getOperand(1).getReg();

527 assert(Def && "Expecting an instruction that defines the register");

528

529 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&

530 Def->getOpcode() != SPIRV::ASSIGN_TYPE)

535 Register Reg = MI.getOperand(1).getReg();

538 assert(Def && "Expecting an instruction that defines the register");

539

540 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&

541 Def->getOpcode() != SPIRV::ASSIGN_TYPE)

544 } else if (MIOp == TargetOpcode::FAKE_USE && MI.getNumOperands() > 0) {

546 if (MdMI && isSpvIntrinsic(*MdMI, Intrinsic::spv_value_md)) {

547

549 for (unsigned I = 1, E = MI.getNumOperands(); I != E && Def; ++I)

551 Def = nullptr;

552 if (Def) {

555 cast(MD->getOperand(1))->getString();

559 }

561 }

563 } else if (MIOp == TargetOpcode::G_CONSTANT ||

564 MIOp == TargetOpcode::G_FCONSTANT ||

565 MIOp == TargetOpcode::G_BUILD_VECTOR) {

566

567

568

569

570

571 Register Reg = MI.getOperand(0).getReg();

572 bool NeedAssignType = true;

573 if (MRI.hasOneUse(Reg)) {

577 continue;

578 if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)

579 NeedAssignType = false;

580 }

581 Type *Ty = nullptr;

582 if (MIOp == TargetOpcode::G_CONSTANT) {

583 auto TargetExtIt = TargetExtConstTypes.find(&MI);

584 Ty = TargetExtIt == TargetExtConstTypes.end()

585 ? MI.getOperand(1).getCImm()->getType()

586 : TargetExtIt->second;

587 const ConstantInt *OpCI = MI.getOperand(1).getCImm();

588

589

590

591

592

593

594

595

597 if (!PrimaryReg.isValid()) {

598 GR->add(OpCI, &MF, Reg);

599 } else if (PrimaryReg != Reg &&

600 MRI.getType(Reg) == MRI.getType(PrimaryReg)) {

601 auto *RCReg = MRI.getRegClassOrNull(Reg);

602 auto *RCPrimary = MRI.getRegClassOrNull(PrimaryReg);

603 if (!RCReg || RCPrimary == RCReg) {

604 RegsAlreadyAddedToDT[&MI] = PrimaryReg;

606 NeedAssignType = false;

607 }

608 }

609 } else if (MIOp == TargetOpcode::G_FCONSTANT) {

610 Ty = MI.getOperand(1).getFPImm()->getType();

611 } else {

612 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);

613 Type *ElemTy = nullptr;

614 MachineInstr *ElemMI = MRI.getVRegDef(MI.getOperand(1).getReg());

616

617 if (ElemMI->getOpcode() == TargetOpcode::G_CONSTANT) {

619 } else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT) {

621 } else {

622

624 if (!NextMI || NextMI->getOpcode() != SPIRV::ASSIGN_TYPE ||

627 }

628 if (ElemTy)

629 Ty = VectorType::get(

630 ElemTy, MI.getNumExplicitOperands() - MI.getNumExplicitDefs(),

631 false);

632 else

633 NeedAssignType = false;

634 }

635 if (NeedAssignType)

637 } else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {

639 }

640

641 if (MII == Begin)

642 ReachedBegin = true;

643 else

644 --MII;

645 }

646 }

648 auto It = RegsAlreadyAddedToDT.find(MI);

649 if (RegsAlreadyAddedToDT.contains(MI))

650 MRI.replaceRegWith(MI->getOperand(0).getReg(), It->second);

651 MI->eraseFromParent();

652 }

653

654

655

658 switch (MI.getOpcode()) {

659 case TargetOpcode::G_TRUNC:

660 case TargetOpcode::G_ANYEXT:

661 case TargetOpcode::G_SEXT:

662 case TargetOpcode::G_ZEXT:

663 case TargetOpcode::G_PTRTOINT:

664 case TargetOpcode::COPY:

665 case TargetOpcode::G_ADDRSPACE_CAST:

667 break;

668 }

669 }

670 }

671}

672

673

675

684}

685

692 for (unsigned Idx = StartOp, MISz = MI->getNumOperands(); Idx != MISz;

696 continue;

697 if (Idx == AsmDescOp && MO.isImm()) {

698

700 AsmDescOp += 1 + F.getNumOperandRegisters();

701 continue;

702 }

704 if (!Ops)

706 else

707 DefReg = MO.getReg();

708 } else if (Ops) {

709 Ops->push_back(Idx);

710 }

711 }

712 return DefReg;

713}

714

715static void

721 for (unsigned i = 0, Sz = ToProcess.size(); i + 1 < Sz; i += 2) {

722 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];

724 MIRBuilder.setInsertPt(*I2->getParent(), *I2);

725

726 if (!AsmTargetReg.isValid()) {

727

728 AsmTargetReg = MRI.createGenericVirtualRegister(LLT::scalar(32));

729 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);

730 auto AsmTargetMIB =

731 MIRBuilder.buildInstr(SPIRV::OpAsmTargetINTEL).addDef(AsmTargetReg);

732 addStringImm(ST.getTargetTripleAsStr(), AsmTargetMIB);

733 GR->add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);

734 }

735

736

737 const MDNode *IAMD = I1->getOperand(1).getMetadata();

740 for (const auto &ArgTy : FTy->params())

745 FTy, RetType, ArgTypes, MIRBuilder);

746

747

749 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);

750 auto AsmMIB = MIRBuilder.buildInstr(SPIRV::OpAsmINTEL)

754 .addUse(AsmTargetReg);

755

757 AsmMIB);

758

759 addStringImm(cast(I1->getOperand(2).getMetadata()->getOperand(0))

760 ->getString(),

761 AsmMIB);

762 GR->add(AsmMIB.getInstr(), &MF, AsmReg);

763

764

767 MIRBuilder.buildInstr(SPIRV::OpDecorate)

769 .addImm(static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));

770

773 DefReg = MRI.createGenericVirtualRegister(LLT::scalar(32));

774 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);

778 }

779

780 auto AsmCall = MIRBuilder.buildInstr(SPIRV::OpAsmCallINTEL)

784 for (unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)

785 AsmCall.addUse(I1->getOperand(IntrIdx).getReg());

786 }

788 MI->eraseFromParent();

789}

790

798 MI.getOpcode() == TargetOpcode::INLINEASM)

800 }

801 }

802 if (ToProcess.size() == 0)

803 return;

804

805 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))

807 "following SPIR-V extension: SPV_INTEL_inline_assembly",

808 false);

809

811}

812

818 continue;

821 MI.getOperand(2).getMetadata());

823 }

824 }

826 MI->eraseFromParent();

827}

828

829

830

831

839 continue;

840

842 NewOperands.push_back(MI.getOperand(0));

843 NewOperands.push_back(MI.getOperand(1));

844 NewOperands.push_back(MI.getOperand(2));

845 for (unsigned i = 3; i < MI.getNumOperands(); i += 2) {

846 Register Reg = MI.getOperand(i).getReg();

850

851 NewOperands.push_back(MI.getOperand(i + 1));

852 }

853

854 assert(MI.getNumOperands() == NewOperands.size());

855 while (MI.getNumOperands() > 0)

856 MI.removeOperand(0);

857 for (auto &MO : NewOperands)

858 MI.addOperand(MO);

859 }

860 }

861}

862

863

864

870 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)

872 }

873 }

874

876 MI->eraseFromParent();

877}

878

879

880

883

887

888

889

897 }

898 }

899

900

901

902

908 for (unsigned i = 0; i < MI->getNumOperands(); ++i) {

909

910 if (MI->getOperand(i).isReg()) {

912 continue;

913 }

914

915 Register Reg = MI->getOperand(i).getReg();

917

918 if (!BuildMBB || BuildMBB->getOpcode() != TargetOpcode::G_BLOCK_ADDR) {

920 continue;

921 }

922

923 assert(BuildMBB && BuildMBB->getOpcode() == TargetOpcode::G_BLOCK_ADDR &&

928 auto It = BB2MBB.find(BB);

929 if (It == BB2MBB.end())

930 report_fatal_error("cannot find a machine basic block by a basic block "

931 "in a switch statement");

934

935 ClearAddressTaken.insert(ReferencedBlock);

936 ToEraseMI.insert(BuildMBB);

937 }

938

939

940 assert(MI->getNumOperands() == NewOps.size());

941 while (MI->getNumOperands() > 0)

942 MI->removeOperand(0);

943 for (auto &MO : NewOps)

944 MI->addOperand(MO);

945

947 if (isSpvIntrinsic(*Next, Intrinsic::spv_track_constant)) {

948 ToEraseMI.insert(Next);

949 Next = MI->getNextNode();

950 }

951 if (Next && Next->getOpcode() == TargetOpcode::G_BRINDIRECT)

952 ToEraseMI.insert(Next);

953 }

954 }

955

956

957

958

960 Succ->setAddressTakenIRBlock(nullptr);

961

962

963

964

965

966

967

971 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {

973 BlockAddrI->getOperand(1).getBlockAddress());

977 }

978 BlockAddrI->eraseFromParent();

979 }

980}

981

984 return true;

985

986

987

989 return false;

990

991

992

994 It != E; ++It) {

996 return false;

997 }

998 return true;

999}

1000

1003

1004

1007 continue;

1008

1010 1);

1013 }

1014}

1015

1016bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {

1017

1020 GR->setCurrentFunc(MF);

1022

1024

1030

1034

1040

1041 return true;

1042}

1043

1045 false)

1046

1047char SPIRVPreLegalizer::ID = 0;

1048

1050 return new SPIRVPreLegalizer();

1051}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder & UseMI

This file contains the simple types necessary to represent the attributes associated with functions a...

Provides analysis for continuously CSEing during GISel passes.

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

Provides analysis for querying information about KnownBits during GISel passes.

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static Register collectInlineAsmInstrOperands(MachineInstr *MI, SmallVector< unsigned, 4 > *Ops=nullptr)

static void cleanupHelperInstructions(MachineFunction &MF)

static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder)

static void selectOpBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)

static void insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder, const SmallVector< MachineInstr * > &ToProcess)

static void removeImplicitFallthroughs(MachineFunction &MF, MachineIRBuilder MIB)

static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def)

static bool isImplicitFallthrough(MachineBasicBlock &MBB)

bool isTypeFoldingSupported(unsigned Opcode)

static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)

static void processInstrsWithTypeFolding(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)

static void widenScalarLLTNextPow2(Register Reg, MachineRegisterInfo &MRI)

static void processSwitchesConstants(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)

static SPIRVType * propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, MachineIRBuilder &MIB)

static MachineInstr * findAssignTypeInstr(Register Reg, MachineRegisterInfo *MRI)

static void buildOpBitcast(SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, Register ResVReg, Register OpReg)

static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)

static void addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &STI, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes, SmallSet< Register, 4 > &TrackedConstRegs)

static void foldConstantsIntoIntrinsics(MachineFunction &MF, const SmallSet< Register, 4 > &TrackedConstRegs)

static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB)

static std::pair< Register, unsigned > createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI, const SPIRVGlobalRegistry &GR)

static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)

Represent the analysis usage information of a pass.

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

LLVM Basic Block Representation.

The address of a basic block.

BasicBlock * getBasicBlock() const

static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)

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...

This is an important base class in LLVM.

void destroyConstant()

Called if some element of this constant is no longer valid.

This class represents an Operation in the Expression.

iterator find(const_arg_type_t< KeyT > Val)

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

FunctionPass class - This class is used to implement most global optimizations.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...

constexpr unsigned getScalarSizeInBits() const

constexpr bool isScalar() const

static constexpr LLT scalar(unsigned SizeInBits)

Get a low-level scalar or aggregate "bag of bits".

constexpr bool isPointer() const

constexpr unsigned getAddressSpace() const

const MDOperand & getOperand(unsigned I) const

const BasicBlock * getBasicBlock() const

Return the LLVM basic block that this instance corresponded to originally.

bool canFallThrough()

Return true if the block can implicitly transfer control to the block after it by falling off the end...

iterator_range< succ_iterator > successors()

reverse_iterator rbegin()

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

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.

MachineInstrBuilder buildBr(MachineBasicBlock &Dest)

Build and insert G_BR Dest.

void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)

Set the insertion point before the specified position.

MachineInstrBuilder buildInstr(unsigned Opcode)

Build and insert = Opcode .

MachineFunction & getMF()

Getter for the function we currently build.

MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)

Build and insert Dst = G_BITCAST Src.

MachineRegisterInfo * getMRI()

Getter for MRI.

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 & setMIFlags(unsigned Flags) const

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.

void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

void setDesc(const MCInstrDesc &TID)

Replace the instruction descriptor (thus opcode) of the current instruction with a new one.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

const ConstantInt * getCImm() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

const MDNode * getMetadata() const

static MachineOperand CreateCImm(const ConstantInt *CI)

void setReg(Register Reg)

Change the register this operand corresponds to.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

bool isMetadata() const

isMetadata - Tests if this is a MO_Metadata operand.

const BlockAddress * getBlockAddress() const

static MachineOperand CreateImm(int64_t Val)

bool isBlockAddress() const

isBlockAddress - Tests if this is a MO_BlockAddress operand.

Register getReg() const

getReg - Returns the register number.

const ConstantFP * getFPImm() const

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)

defusechain_iterator - This class provides iterator support for machine operands in the function that...

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

Wrapper class representing virtual and physical registers.

constexpr bool isValid() const

SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const

void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)

void add(const Constant *C, MachineFunction *MF, Register R)

bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const

unsigned getScalarOrVectorComponentCount(Register VReg) const

SPIRVType * getPointeeType(SPIRVType *PtrType)

Register getSPIRVTypeID(const SPIRVType *SpirvType) const

SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)

void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)

SPIRVType * getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVType *RetType, const SmallVectorImpl< SPIRVType * > &ArgTypes, MachineIRBuilder &MIRBuilder)

const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const

Register find(const MachineInstr *MI, MachineFunction *MF)

SPIRVType * getOrCreateSPIRVPointerType(SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SClass=SPIRV::StorageClass::Function)

SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder)

SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)

Type * getDeducedGlobalValueType(const GlobalValue *Global)

LLT getRegType(SPIRVType *SpvType) const

void addValueAttrs(MachineInstr *Key, std::pair< Type *, std::string > Val)

SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const

unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const

const SPIRVInstrInfo * getInstrInfo() const override

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

bool contains(const T &V) const

Check if the SmallSet contains the given element.

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringMapEntry - This is used to represent one value that is inserted into a StringMap.

StringRef - Represent a constant reference to a string, i.e.

The instances of the Type class are immutable: once they are created, they are never changed.

static Type * getVoidTy(LLVMContext &C)

static IntegerType * getInt32Ty(LLVMContext &C)

static TypedPointerType * get(Type *ElementType, unsigned AddressSpace)

This constructs a pointer to an object of the specified type in a numbered address space.

Type * getType() const

All values are typed, get the type of this value.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

unsigned Log2_32_Ceil(uint32_t Value)

Return the ceil log base 2 of the specified value, 32 if the value is zero.

FunctionPass * createSPIRVPreLegalizerPass()

Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)

Helper external function for inserting ASSIGN_TYPE instuction between Reg and its definition,...

iterator_range< po_iterator< T > > post_order(const T &G)

constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)

Type * toTypedPointer(Type *Ty)

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

@ Global

Append to llvm.global_dtors.

SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)

void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)

MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)

Type * getMDOperandAsType(const MDNode *N, unsigned I)

void initializeSPIRVPreLegalizerPass(PassRegistry &)

bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)

void addStringImm(const StringRef &Str, MCInst &Inst)

MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)

void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)