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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

24

25#define DEBUG_TYPE "spirv-prelegalizer"

26

27using namespace llvm;

28

29namespace {

31public:

32 static char ID;

35 void getAnalysisUsage(AnalysisUsage &AU) const override;

36};

37}

38

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

40 AU.addPreserved();

42}

43

44static void

54 continue;

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

57 auto *Const =

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

60 ->getValue());

63 if (Reg.isValid()) {

64 GR->add(GV, MRI.getVRegDef(SrcReg));

66 } else

67 RegsAlreadyAddedToDT[&MI] = Reg;

68 } else {

70 if (Reg.isValid()) {

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

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

75 GR->add(Const, BuildVec);

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

77

78

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

82 GR->add(ElemConst,

83 MRI.getVRegDef(BuildVec->getOperand(1 + i).getReg()));

84 else

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

86 }

87 }

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

89

91 if (SrcMI)

92 GR->add(Const, SrcMI);

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

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

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

96 if (Const->isNullValue()) {

100 Const->getType(), MIB, SPIRV::AccessQualifier::ReadWrite,

101 true);

102 assert(SrcMI && "Expected source instruction to be valid");

106 }

107 }

108 } else {

109 RegsAlreadyAddedToDT[&MI] = Reg;

110

111

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

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

115 ToEraseComposites.push_back(SrcMI);

116 }

117 }

118 }

119 }

122 auto It = RegsAlreadyAddedToDT.find(MI);

123 if (It != RegsAlreadyAddedToDT.end())

124 Reg = It->second;

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);

130 MI->eraseFromParent();

131 }

134 MI->eraseFromParent();

135 }

136}

137

145 continue;

146 const MDNode *MD = MI.getOperand(2).getMetadata();

151 }

153 }

156 MI->eraseFromParent();

157 }

158 ToErase.clear();

159 }

160}

161

165 IE = MRI->use_instr_end();

166 I != IE; ++I) {

170 UseMI->getOperand(1).getReg() == Reg)

172 }

173 return nullptr;

174}

175

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

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

184 if (MRI->getRegClassOrNull(ResVReg))

186 if (ResType == OpType)

188 else

193}

194

195

196

197

198

199

200

201

202

203

204

205

212 Register DstReg = MI.getOperand(0).getReg();

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

216 DstType &&

217 "Expected destination SPIR-V type to have been assigned already.");

220 "Expected source SPIR-V type to have been assigned already.");

221 if (DstType == SrcType) {

225 continue;

226 }

227 }

228

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

230 continue;

231

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

236 }

237 }

240 MI->eraseFromParent();

241 }

242}

243

246

253 continue;

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

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

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

260 auto SC =

262 ? SPIRV::StorageClass::CodeSectionINTEL

266

267

268

271

274 MRI->replaceRegWith(Def, Source);

275 } else {

279 }

280 }

281 }

284 MI->eraseFromParent();

285 }

286}

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

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

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

310 if (!SpvType) {

311 switch (MI->getOpcode()) {

312 case TargetOpcode::G_FCONSTANT:

313 case TargetOpcode::G_CONSTANT: {

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

317 Ty, MIB, SPIRV::AccessQualifier::ReadWrite, true);

318 break;

319 }

320 case TargetOpcode::G_GLOBAL_VALUE: {

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

327 Ty, MIB, SPIRV::AccessQualifier::ReadWrite, true);

328 break;

329 }

330 case TargetOpcode::G_ANYEXT:

331 case TargetOpcode::G_SEXT:

332 case TargetOpcode::G_ZEXT: {

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

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

338 unsigned ExpectedBW =

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

342 if (NumElements > 1)

344 MIB, true);

345 }

346 }

347 }

348 break;

349 }

350 case TargetOpcode::G_PTRTOINT:

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

353 break;

354 case TargetOpcode::G_TRUNC:

355 case TargetOpcode::G_ADDRSPACE_CAST:

356 case TargetOpcode::G_PTR_ADD:

357 case TargetOpcode::COPY: {

360 if (Def)

362 break;

363 }

364 default:

365 break;

366 }

367 if (SpvType) {

368

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

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

378 }

380 }

381 if (MRI.getRegClassOrNull(Reg))

383 : &SPIRV::iIDRegClass);

384 }

385 }

386 return SpvType;

387}

388

389

390

391

397

401 return;

404 if (NewWidth != CurrentWidth)

406}

407

410 unsigned CurrentWidth = CImmVal->getBitWidth();

412 if (NewWidth != CurrentWidth) {

413

416 }

417}

418

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

423

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

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

426 DefIt = std::next(DefIt);

428}

429

430namespace llvm {

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

437 if (!SpvType)

439 SPIRV::AccessQualifier::ReadWrite, true);

440 if (MRI.getRegClassOrNull(Reg))

442 if (MRI.getType(Reg).isValid())

445}

446

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

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

453 continue;

456 if (!SpvType && KnownResType) {

457 SpvType = KnownResType;

459 }

461 if (MRI.getRegClassOrNull(OpReg))

463 if (MRI.getType(OpReg).isValid())

465 }

466}

467}

468

469static void

473

476

480

481 bool IsExtendedInts =

482 ST->canUseExtension(

483 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||

484 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions) ||

485 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_int4);

486

488 if (MBB->empty())

489 continue;

490

491 bool ReachedBegin = false;

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

493 !ReachedBegin;) {

495 unsigned MIOp = MI.getOpcode();

496

497 if (!IsExtendedInts) {

498

499 for (auto &MOP : MI.operands()) {

500 if (MOP.isReg())

502 else if (MOP.isCImm())

504 }

505 }

506

512 ElementTy, MI,

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

516

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

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

526

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

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

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

533

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

537 Def = nullptr;

538 if (Def) {

545 }

547 }

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

550 MIOp == TargetOpcode::G_FCONSTANT ||

551 MIOp == TargetOpcode::G_BUILD_VECTOR) {

552

553

556 Type *Ty = nullptr;

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

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

559 Ty = TargetExtIt == TargetExtConstTypes.end()

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

561 : TargetExtIt->second;

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

563

564

565

566

567

568

569

570

572 if (!PrimaryReg.isValid()) {

573 GR->add(OpCI, &MI);

574 } else if (PrimaryReg != Reg &&

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

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

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

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

579 RegsAlreadyAddedToDT[&MI] = PrimaryReg;

581 NeedAssignType = false;

582 }

583 }

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

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

586 } else {

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

588 Type *ElemTy = nullptr;

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

591

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

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

596 } else {

597 if (const SPIRVType *ElemSpvType =

600 }

601 if (ElemTy)

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

604 false);

605 else

606 NeedAssignType = false;

607 }

608 if (NeedAssignType)

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

612 }

613

614 if (MII == Begin)

615 ReachedBegin = true;

616 else

617 --MII;

618 }

619 }

621 auto It = RegsAlreadyAddedToDT.find(MI);

622 if (It != RegsAlreadyAddedToDT.end())

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

625 MI->eraseFromParent();

626 }

627

628

629

632 switch (MI.getOpcode()) {

633 case TargetOpcode::G_TRUNC:

634 case TargetOpcode::G_ANYEXT:

635 case TargetOpcode::G_SEXT:

636 case TargetOpcode::G_ZEXT:

637 case TargetOpcode::G_PTRTOINT:

638 case TargetOpcode::COPY:

639 case TargetOpcode::G_ADDRSPACE_CAST:

641 break;

642 }

643 }

644 }

645}

646

656

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

664 ++Idx) {

667 continue;

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

669

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

672 continue;

673 }

675 if (Ops)

677 else

678 DefReg = MO.getReg();

679 } else if (Ops) {

680 Ops->push_back(Idx);

681 }

682 }

683 return DefReg;

684}

685

686static void

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

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

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

696

697 if (!AsmTargetReg.isValid()) {

698

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

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

701 auto AsmTargetMIB =

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

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

704 GR->add(AsmTargetMIB.getInstr(), AsmTargetMIB);

705 }

706

707

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

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

713 ArgTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true));

716 SPIRV::AccessQualifier::ReadWrite, true);

718 FTy, RetType, ArgTypes, MIRBuilder);

719

720

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

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

727 .addUse(AsmTargetReg);

728

730 AsmMIB);

731

733 ->getString(),

734 AsmMIB);

735 GR->add(AsmMIB.getInstr(), AsmMIB);

736

737

740 MIRBuilder.buildInstr(SPIRV::OpDecorate)

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

743

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

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

750 SPIRV::AccessQualifier::ReadWrite, true);

752 }

753

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

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

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

760 }

763 MI->eraseFromParent();

764 }

765}

766

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

776 }

777 }

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

779 return;

780

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

783 "following SPIR-V extension: SPV_INTEL_inline_assembly",

784 false);

785

787}

788

790 union {

791 float F;

793 } FPMaxError;

794 FPMaxError.F = F;

795 return FPMaxError.Spir;

796}

797

805 isSpvIntrinsic(MI, Intrinsic::spv_assign_aliasing_decoration) &&

806 isSpvIntrinsic(MI, Intrinsic::spv_assign_fpmaxerror_decoration))

807 continue;

811 MI.getOperand(2).getMetadata(), ST);

813 Intrinsic::spv_assign_fpmaxerror_decoration)) {

815 MI.getOperand(2).getMetadata()->getOperand(0));

818

820 SPIRV::Decoration::FPMaxErrorDecorationINTEL,

821 {OpValue});

822 } else {

824 MI.getOperand(2).getImm(),

825 MI.getOperand(3).getMetadata());

826 }

827

829 }

830 }

833 MI->eraseFromParent();

834 }

835}

836

837

838

839

847 continue;

848

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

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

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

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

858

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

860 }

861

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

863 while (MI.getNumOperands() > 0)

864 MI.removeOperand(0);

865 for (auto &MO : NewOperands)

866 MI.addOperand(MO);

867 }

868 }

869}

870

871

872

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

881 }

882 }

883

886 MI->eraseFromParent();

887 }

888}

889

890

891

894

897 BB2MBB[MBB.getBasicBlock()] = &MBB;

898

899

900

908 }

909 }

910

911

912

913

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

920

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

923 continue;

924 }

925

928

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

931 continue;

932 }

933

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

939 auto It = BB2MBB.find(BB);

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

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

942 "in a switch statement");

945

946 ClearAddressTaken.insert(ReferencedBlock);

947 ToEraseMI.insert(BuildMBB);

948 }

949

950

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

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

953 MI->removeOperand(0);

954 for (auto &MO : NewOps)

955 MI->addOperand(MO);

956

960 Next = MI->getNextNode();

961 }

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

964 }

965 }

966

967

968

969

971 Succ->setAddressTakenIRBlock(nullptr);

972

973

974

975

976

977

978

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

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

988 }

990 BlockAddrI->eraseFromParent();

991 }

992}

993

995 if (MBB.empty())

996 return true;

997

998

999

1000 if (MBB.canFallThrough())

1001 return false;

1002

1003

1004

1006 It != E; ++It) {

1008 return false;

1009 }

1010 return true;

1011}

1012

1015

1016

1019 continue;

1020

1023 MIB.buildBr(**MBB.successors().begin());

1024 }

1025}

1026

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

1028

1029 const SPIRVSubtarget &ST = MF.getSubtarget();

1030 SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();

1031 GR->setCurrentFunc(MF);

1032 MachineIRBuilder MIB(MF);

1033

1034 DenseMap<MachineInstr *, Type *> TargetExtConstTypes;

1035

1040

1044

1050

1051 return true;

1052}

1053

1055 false)

1056

1057char SPIRVPreLegalizer::ID = 0;

1058

1060 return new SPIRVPreLegalizer();

1061}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder & UseMI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Provides analysis for continuously CSEing during GISel passes.

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

Provides analysis for querying information about KnownBits during GISel passes.

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

Promote Memory to Register

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

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

Definition SPIRVPreLegalizer.cpp:658

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

Definition SPIRVPreLegalizer.cpp:767

static void cleanupHelperInstructions(MachineFunction &MF, SPIRVGlobalRegistry *GR)

Definition SPIRVPreLegalizer.cpp:873

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

Definition SPIRVPreLegalizer.cpp:687

static void removeImplicitFallthroughs(MachineFunction &MF, MachineIRBuilder MIB)

Definition SPIRVPreLegalizer.cpp:1013

static unsigned widenBitWidthToNextPow2(unsigned BitWidth)

Definition SPIRVPreLegalizer.cpp:392

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

Definition SPIRVPreLegalizer.cpp:419

static bool isImplicitFallthrough(MachineBasicBlock &MBB)

Definition SPIRVPreLegalizer.cpp:994

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

Definition SPIRVPreLegalizer.cpp:798

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

Definition SPIRVPreLegalizer.cpp:244

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

Definition SPIRVPreLegalizer.cpp:647

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

Definition SPIRVPreLegalizer.cpp:840

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

Definition SPIRVPreLegalizer.cpp:302

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

Definition SPIRVPreLegalizer.cpp:206

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

Definition SPIRVPreLegalizer.cpp:162

static void widenCImmType(MachineOperand &MOP)

Definition SPIRVPreLegalizer.cpp:408

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

Definition SPIRVPreLegalizer.cpp:176

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

Definition SPIRVPreLegalizer.cpp:892

static void widenScalarType(Register Reg, MachineRegisterInfo &MRI)

Definition SPIRVPreLegalizer.cpp:398

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

Definition SPIRVPreLegalizer.cpp:138

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

Definition SPIRVPreLegalizer.cpp:45

static uint32_t convertFloatToSPIRVWord(float F)

Definition SPIRVPreLegalizer.cpp:789

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

Definition SPIRVPreLegalizer.cpp:470

LLVM_ABI float convertToFloat() const

Converts this APFloat to host float value.

LLVM_ABI APInt zextOrTrunc(unsigned width) const

Zero extend or truncate to width.

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 LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)

ConstantFP - Floating Point Values [float, double].

const APFloat & getValueAPF() const

This is the shared class of boolean and integer constants.

unsigned getBitWidth() const

getBitWidth - Return the scalar bitwidth of this constant.

const APInt & getValue() const

Return the constant as an APInt value reference.

This is an important base class in LLVM.

LLVM_ABI void destroyConstant()

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

iterator find(const_arg_type_t< KeyT > Val)

LLVMContext & getContext() const

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

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

LLVM_ABI iterator getFirstNonPHI()

Returns a pointer to the first instruction in this block that is not a PHINode instruction.

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

MachineInstrBundleIterator< MachineInstr > iterator

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.

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.

const MachineBasicBlock & front() const

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.

MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)

Build and insert Res = COPY Op.

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.

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

Add the specified operand to the instruction.

LLVM_ABI 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)

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

void setCImm(const ConstantInt *CI)

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)

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

defusechain_instr_iterator< true, false, false, true > use_instr_iterator

use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...

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)

SPIRVType * changePointerStorageClass(SPIRVType *PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)

const Type * getTypeForSPIRVType(const SPIRVType *Ty) const

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

unsigned getScalarOrVectorComponentCount(Register VReg) const

SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)

SPIRVType * getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)

void invalidateMachineInstr(MachineInstr *MI)

Register getSPIRVTypeID(const SPIRVType *SpirvType) const

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

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

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)

void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec, const MDNode *GVarMD)

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

unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const

bool add(SPIRV::IRHandle Handle, const MachineInstr *MI)

Register find(SPIRV::IRHandle Handle, const MachineFunction *MF)

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.

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.

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

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

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

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

Type * getType() const

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

LLVM_ABI void replaceAllUsesWith(Value *V)

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

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

unsigned ID

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

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)

Extract a Value from Metadata, if any.

This is an optimization pass for GlobalISel generic memory operations.

void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)

unsigned Log2_32_Ceil(uint32_t Value)

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

StringMapEntry< Value * > ValueName

bool isTypeFoldingSupported(unsigned Opcode)

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

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

Helper external function for assigning SPIRVType to a register, ensuring the register class and type ...

Definition SPIRVPreLegalizer.cpp:431

FunctionPass * createSPIRVPreLegalizerPass()

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

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

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

Definition SPIRVPreLegalizer.cpp:447

void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)

Type * toTypedPointer(Type *Ty)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

const MachineInstr SPIRVType

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

@ Global

Append to llvm.global_dtors.

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

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

FunctionAddr VTableAddr Next

DWARFExpression::Operation Op

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

constexpr unsigned BitWidth

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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

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

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

MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)