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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

28

29using namespace llvm;

30

34

38 Register SwiftErrorVReg) const {

39

40 if (MIRBuilder.getMF()

44 return true;

45

46

47 if (IndirectCalls.size() > 0) {

48 produceIndirectPtrTypes(MIRBuilder);

49 IndirectCalls.clear();

50 }

51

52

53

54 if (VRegs.size() > 1)

55 return false;

56 if (Val) {

58 return MIRBuilder.buildInstr(SPIRV::OpReturnValue)

61 *STI.getRegBankInfo());

62 }

63 MIRBuilder.buildInstr(SPIRV::OpReturn);

64 return true;

65}

66

67

71

72 uint32_t FuncControl = static_cast<uint32_t>(SPIRV::FunctionControl::None);

73

74 if (F.hasFnAttribute(Attribute::AttrKind::NoInline))

75 FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::DontInline);

76 else if (F.hasFnAttribute(Attribute::AttrKind::AlwaysInline))

77 FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::Inline);

78

80 FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::Pure);

82 FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::Const);

83

84 if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_optnone) ||

85 ST->canUseExtension(SPIRV::Extension::SPV_EXT_optnone))

86 if (F.hasFnAttribute(Attribute::OptimizeNone))

87 FuncControl |= static_cast<uint32_t>(SPIRV::FunctionControl::OptNoneEXT);

88

89 return FuncControl;

90}

91

95 if (CMeta)

97 }

98 return nullptr;

99}

100

101

102

103

104

105

110 bool hasArgPtrs = false;

111 for (auto &Arg : F.args()) {

112

113 if (Arg.getType()->isPointerTy()) {

114 hasArgPtrs = true;

115 break;

116 }

117 }

118 if (!hasArgPtrs) {

119 Type *RetTy = FTy->getReturnType();

120

122 return FTy;

123 }

124

125

126

129 for (auto SArgTy : SArgTys)

132}

133

134static SPIRV::AccessQualifier::AccessQualifier

137 return SPIRV::AccessQualifier::ReadWrite;

138

140 if (!ArgAttribute)

141 return SPIRV::AccessQualifier::ReadWrite;

142

143 if (ArgAttribute->getString() == "read_only")

144 return SPIRV::AccessQualifier::ReadOnly;

145 if (ArgAttribute->getString() == "write_only")

146 return SPIRV::AccessQualifier::WriteOnly;

147 return SPIRV::AccessQualifier::ReadWrite;

148}

149

150static std::vectorSPIRV::Decoration::Decoration

153 if (ArgAttribute && ArgAttribute->getString() == "volatile")

154 return {SPIRV::Decoration::Volatile};

155 return {};

156}

157

162

163 SPIRV::AccessQualifier::AccessQualifier ArgAccessQual =

165

166 Type *OriginalArgType =

168

169

170

173 true);

174

175 Argument *Arg = F.getArg(ArgIdx);

181 }

182

183

184

185

186

187

188

189

190

195 }

196

199

200 if (II && II->getIntrinsicID() == Intrinsic::spv_assign_type) {

202 Type *BuiltinType =

204 assert(BuiltinType->isTargetExtTy() && "Expected TargetExtType");

206 true);

207 }

208

209

210 if (II || II->getIntrinsicID() != Intrinsic::spv_assign_ptr_type)

211 continue;

212

214 Type *ElementTy =

217 ElementTy, MIRBuilder,

220 }

221

222

223

225 ArgAccessQual, true);

226}

227

228static SPIRV::ExecutionModel::ExecutionModel

231 return SPIRV::ExecutionModel::Kernel;

232

234 auto attribute = F.getFnAttribute("hlsl.shader");

235 if (!attribute.isValid()) {

237 "This entry point lacks mandatory hlsl.shader attribute.");

238 }

239

240 const auto value = attribute.getValueAsString();

241 if (value == "compute")

242 return SPIRV::ExecutionModel::GLCompute;

243 if (value == "vertex")

244 return SPIRV::ExecutionModel::Vertex;

245 if (value == "pixel")

246 return SPIRV::ExecutionModel::Fragment;

247

249 "This HLSL entry point is not supported by this backend.");

250 }

251

253

254

255

256

257

259 auto attribute = F.getFnAttribute("hlsl.shader");

260 if (!attribute.isValid()) {

262 return SPIRV::ExecutionModel::Kernel;

263 }

265

266 const auto value = attribute.getValueAsString();

267 if (value == "compute")

268 return SPIRV::ExecutionModel::GLCompute;

269 if (value == "vertex")

270 return SPIRV::ExecutionModel::Vertex;

271 if (value == "pixel")

272 return SPIRV::ExecutionModel::Fragment;

273

274 report_fatal_error("This HLSL entry point is not supported by this backend.");

275}

276

281

283 return true;

284

285 assert(GR && "Must initialize the SPIRV type registry before lowering args.");

286 GR->setCurrentFunc(MIRBuilder.getMF());

287

288

291

292

294 if (VRegs.size() > 0) {

295 unsigned i = 0;

296 for (const auto &Arg : F.args()) {

297

298

299 if (VRegs[i].size() > 1)

300 return false;

302 GR->assignSPIRVTypeToVReg(SpirvTy, VRegs[i][0], MIRBuilder.getMF());

304

305 if (Arg.hasName())

306 buildOpName(VRegs[i][0], Arg.getName(), MIRBuilder);

308 auto DerefBytes = static_cast<unsigned>(Arg.getDereferenceableBytes());

309 if (DerefBytes != 0)

311 SPIRV::Decoration::MaxByteOffset, {DerefBytes});

312 }

313 if (Arg.hasAttribute(Attribute::Alignment) && !ST->isShader()) {

314 auto Alignment = static_cast<unsigned>(

315 Arg.getAttribute(Attribute::Alignment).getValueAsInt());

316 buildOpDecorate(VRegs[i][0], MIRBuilder, SPIRV::Decoration::Alignment,

317 {Alignment});

318 }

319 if (Arg.hasAttribute(Attribute::ReadOnly)) {

320 auto Attr =

321 static_cast<unsigned>(SPIRV::FunctionParameterAttribute::NoWrite);

323 SPIRV::Decoration::FuncParamAttr, {Attr});

324 }

325 if (Arg.hasAttribute(Attribute::ZExt)) {

326 auto Attr =

327 static_cast<unsigned>(SPIRV::FunctionParameterAttribute::Zext);

329 SPIRV::Decoration::FuncParamAttr, {Attr});

330 }

331 if (Arg.hasAttribute(Attribute::NoAlias)) {

332 auto Attr =

333 static_cast<unsigned>(SPIRV::FunctionParameterAttribute::NoAlias);

335 SPIRV::Decoration::FuncParamAttr, {Attr});

336 }

337

338

339

340

341

342 if (Arg.hasAttribute(Attribute::ByVal) ||

343 (Arg.hasAttribute(Attribute::ByRef) &&

344 F.getParent()->getTargetTriple().getVendor() ==

346 auto Attr =

347 static_cast<unsigned>(SPIRV::FunctionParameterAttribute::ByVal);

349 SPIRV::Decoration::FuncParamAttr, {Attr});

350 }

351 if (Arg.hasAttribute(Attribute::StructRet)) {

352 auto Attr =

353 static_cast<unsigned>(SPIRV::FunctionParameterAttribute::Sret);

355 SPIRV::Decoration::FuncParamAttr, {Attr});

356 }

357

359 std::vectorSPIRV::Decoration::Decoration ArgTypeQualDecs =

361 for (SPIRV::Decoration::Decoration Decoration : ArgTypeQualDecs)

362 buildOpDecorate(VRegs[i][0], MIRBuilder, Decoration, {});

363 }

364

365 MDNode *Node = F.getMetadata("spirv.ParameterDecorations");

366 if (Node && i < Node->getNumOperands() &&

371 assert(MD2 && "Metadata operand is expected");

373 assert(Const && "MDOperand should be ConstantInt");

374 auto Dec =

375 static_castSPIRV::Decoration::Decoration\(Const->getZExtValue());

376 std::vector<uint32_t> DecVec;

377 for (unsigned j = 1; j < MD2->getNumOperands(); j++) {

379 assert(Const && "MDOperand should be ConstantInt");

380 DecVec.push_back(static_cast<uint32_t>(Const->getZExtValue()));

381 }

383 }

384 }

385 ++i;

386 }

387 }

388

391 MRI->setRegClass(FuncVReg, &SPIRV::iIDRegClass);

395 if (Type *FRetElemTy = GR->findDeducedElementType(&F)) {

398 GR->addReturnType(&F, DerivedTy);

399 FRetTy = DerivedTy;

400 }

401 }

402 SPIRVType *RetTy = GR->getOrCreateSPIRVType(

403 FRetTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);

405 SPIRVType *FuncTy = GR->getOrCreateOpTypeFunctionWithArgs(

406 FTy, RetTy, ArgTypeVRegs, MIRBuilder);

408

409

412 .addUse(GR->getSPIRVTypeID(RetTy))

414 .addUse(GR->getSPIRVTypeID(FuncTy));

416 GR->addGlobalObject(&F, &MIRBuilder.getMF(), FuncVReg);

417 if (F.isDeclaration())

418 GR->add(&F, MB);

419

420

421 int i = 0;

422 for (const auto &Arg : F.args()) {

423 assert(VRegs[i].size() == 1 && "Formal arg has multiple vregs");

424 Register ArgReg = VRegs[i][0];

425 MRI->setRegClass(ArgReg, GR->getRegClass(ArgTypeVRegs[i]));

426 MRI->setType(ArgReg, GR->getRegType(ArgTypeVRegs[i]));

427 auto MIB = MIRBuilder.buildInstr(SPIRV::OpFunctionParameter)

429 .addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));

430 if (F.isDeclaration())

431 GR->add(&Arg, MIB);

432 GR->addGlobalObject(&Arg, &MIRBuilder.getMF(), ArgReg);

433 i++;

434 }

435

436 if (F.hasName())

437 buildOpName(FuncVReg, F.getName(), MIRBuilder);

438

439

441

442

443

446 auto MIB = MIRBuilder.buildInstr(SPIRV::OpEntryPoint)

451 buildOpDecorate(FuncVReg, MIRBuilder, SPIRV::Decoration::LinkageAttributes,

452 {static_cast<uint32_t>(*LnkTy)}, F.getName());

453 }

454

455

456 bool hasFunctionPointers =

457 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers);

458 if (hasFunctionPointers) {

459 if (F.hasFnAttribute("referenced-indirectly")) {

461 "Unexpected 'referenced-indirectly' attribute of the kernel "

462 "function");

464 SPIRV::Decoration::ReferencedIndirectlyINTEL, {});

465 }

466 }

467

468 return true;

469}

470

471

472

473

474

475

476

477

478

479

480

481void SPIRVCallLowering::produceIndirectPtrTypes(

483

486 for (auto const &IC : IndirectCalls) {

488 IC.RetTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);

490 for (size_t i = 0; i < IC.ArgTys.size(); ++i) {

492 IC.ArgTys[i], MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);

493 SpirvArgTypes.push_back(SPIRVTy);

496 }

497

501 FTy, SpirvRetTy, SpirvArgTypes, MIRBuilder);

502

503 auto SC = ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)

504 ? SPIRV::StorageClass::CodeSectionINTEL

505 : SPIRV::StorageClass::Function;

508

510 }

511}

512

515

516

517 if (Info.OrigRet.Regs.size() > 1)

518 return false;

520 GR->setCurrentFunc(MF);

521 const Function *CF = nullptr;

522 std::string DemangledName;

523 const Type *OrigRetTy = Info.OrigRet.Ty;

524

525

526

527

528 if (Info.Callee.isGlobal()) {

529 std::string FuncName = Info.Callee.getGlobal()->getName().str();

532

533 if (CF == nullptr)

534 return false;

535

539 if (auto *DerivedRetTy = GR->findReturnType(CF))

540 OrigRetTy = DerivedRetTy;

541 }

542 }

543

546 Info.OrigRet.Regs.empty() ? Register(0) : Info.OrigRet.Regs[0];

548

550 if (isFunctionDecl && !DemangledName.empty()) {

552 if (!GR->getSPIRVTypeForVReg(ResVReg)) {

553 const Type *RetTy = OrigRetTy;

555 const Value *OrigValue = Info.OrigRet.OrigValue;

556 if (!OrigValue)

557 OrigValue = Info.CB;

558 if (OrigValue)

559 if (Type *ElemTy = GR->findDeducedElementType(OrigValue))

560 RetTy =

562 }

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

565 }

566 } else {

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

569 }

571 for (auto Arg : Info.OrigArgs) {

572 assert(Arg.Regs.size() == 1 && "Call arg has multiple VRegs");

573 Register ArgReg = Arg.Regs[0];

575 SPIRVType *SpvType = GR->getSPIRVTypeForVReg(ArgReg);

576 if (!SpvType) {

577 Type *ArgTy = nullptr;

579

580

581

582

583

584 if (Arg.OrigValue)

585 if (Type *ElemTy = GR->findDeducedElementType(Arg.OrigValue))

586 ArgTy =

588 } else {

589 ArgTy = Arg.Ty;

590 }

591 if (ArgTy) {

592 SpvType = GR->getOrCreateSPIRVType(

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

594 GR->assignSPIRVTypeToVReg(SpvType, ArgReg, MF);

595 }

596 }

597 if (MRI->getRegClassOrNull(ArgReg)) {

598

599

600

601 MRI->setRegClass(ArgReg, SpvType ? GR->getRegClass(SpvType)

602 : &SPIRV::pIDRegClass);

603 MRI->setType(

604 ArgReg,

605 SpvType ? GR->getRegType(SpvType)

607 GR->getPointerSize()));

608 }

609 }

611 DemangledName, ST->getPreferredInstructionSet(), MIRBuilder,

612 ResVReg, OrigRetTy, ArgVRegs, GR, *Info.CB))

613 return *Res;

614 }

615

616 if (isFunctionDecl && !GR->find(CF, &MF).isValid()) {

617

618

620 FirstBlockBuilder.setMF(MF);

622

627 continue;

629 MRI->setRegClass(Reg, &SPIRV::iIDRegClass);

632 }

633

636 }

637

638

639 if (MIRBuilder.getMF()

643

645 return true;

646 }

647

648 unsigned CallOp;

649 if (Info.CB->isIndirectCall()) {

650 if (!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))

651 report_fatal_error("An indirect call is encountered but SPIR-V without "

652 "extensions does not support it",

653 false);

654

655 CallOp = SPIRV::OpFunctionPointerCallINTEL;

656

657

658 Register CalleeReg = Info.Callee.getReg();

659 if (CalleeReg.isValid()) {

660 SPIRVCallLowering::SPIRVIndirectCall IndirectCall;

665 "Function types mismatch");

666 for (unsigned I = 0; I != Info.OrigArgs.size(); ++I) {

667 assert(Info.OrigArgs[I].Regs.size() == 1 &&

668 "Call arg has multiple VRegs");

670 IndirectCall.ArgRegs.push_back(Info.OrigArgs[I].Regs[0]);

671 }

673 }

674 } else {

675

676 CallOp = SPIRV::OpFunctionCall;

677 }

678

679

682 SPIRVType *RetType = GR->assignTypeToVReg(

683 OrigRetTy, ResVReg, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);

684

685

686 auto MIB = MIRBuilder.buildInstr(CallOp)

688 .addUse(GR->getSPIRVTypeID(RetType))

689 .add(Info.Callee);

690

691 for (const auto &Arg : Info.OrigArgs) {

692

693 if (Arg.Regs.size() > 1)

694 return false;

695 MIB.addUse(Arg.Regs[0]);

696 }

697

698 if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing)) {

699

700 const CallBase *CI = Info.CB;

703 GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,

704 SPIRV::Decoration::AliasScopeINTEL, MD);

706 GR->buildMemAliasingOpDecorate(ResVReg, MIRBuilder,

707 SPIRV::Decoration::NoAliasINTEL, MD);

708 }

709 }

710

712 *ST->getRegBankInfo());

713}

unsigned const MachineRegisterInfo * MRI

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

Promote Memory to Register

uint64_t IntrinsicInst * II

static ConstantInt * getConstInt(MDNode *MD, unsigned NumOp)

Definition SPIRVCallLowering.cpp:92

static SPIRV::ExecutionModel::ExecutionModel getExecutionModel(const SPIRVSubtarget &STI, const Function &F)

Definition SPIRVCallLowering.cpp:229

static uint32_t getFunctionControl(const Function &F, const SPIRVSubtarget *ST)

Definition SPIRVCallLowering.cpp:68

static SPIRV::AccessQualifier::AccessQualifier getArgAccessQual(const Function &F, unsigned ArgIdx)

Definition SPIRVCallLowering.cpp:135

static SPIRVType * getArgSPIRVType(const Function &F, unsigned ArgIdx, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIRBuilder, const SPIRVSubtarget &ST)

Definition SPIRVCallLowering.cpp:158

static FunctionType * fixFunctionTypeIfPtrArgs(SPIRVGlobalRegistry *GR, const Function &F, FunctionType *FTy, const SPIRVType *SRetTy, const SmallVector< SPIRVType *, 4 > &SArgTys)

Definition SPIRVCallLowering.cpp:107

static std::vector< SPIRV::Decoration::Decoration > getKernelArgTypeQual(const Function &F, unsigned ArgIdx)

Definition SPIRVCallLowering.cpp:151

#define SPIRV_BACKEND_SERVICE_FUN_NAME

This class represents an incoming formal argument to a Function.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool isValid() const

Return true if the attribute is any kind of attribute.

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

CallLowering(const TargetLowering *TLI)

This is the shared class of boolean and integer constants.

TypeSize getTypeStoreSize(Type *Ty) const

Returns the maximum number of bytes that may be overwritten by storing the specified type.

FunctionLoweringInfo - This contains information that is global to a function that is used when lower...

Class to represent function types.

unsigned getNumParams() const

Return the number of fixed parameters this function type requires.

Type * getParamType(unsigned i) const

Parameter type accessors.

Type * getReturnType() const

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

iterator_range< arg_iterator > args()

Attribute getFnAttribute(Attribute::AttrKind Kind) const

Return the attribute for the given attribute kind.

LLVM_ABI bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

bool hasMetadata() const

Return true if this instruction has any metadata attached to it.

MDNode * getMetadata(unsigned KindID) const

Get the metadata of given kind attached to this Instruction.

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.

const MDOperand & getOperand(unsigned I) const

ArrayRef< MDOperand > operands() const

unsigned getNumOperands() const

Return number of MDNode operands.

Tracking metadata reference owned by Metadata.

LLVM_ABI StringRef getString() const

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineBasicBlock * getBlockNumbered(unsigned N) const

getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...

Function & getFunction()

Return the LLVM function that this machine code represents.

Helper class to build MachineInstr.

const TargetInstrInfo & getTII()

MachineInstrBuilder buildInstr(unsigned Opcode)

Build and insert = Opcode .

MachineFunction & getMF()

Getter for the function we currently build.

void setMBB(MachineBasicBlock &MBB)

Set the insertion point to the end of MBB.

MachineInstrBuilder buildTrap(bool Debug=false)

Build and insert G_TRAP or G_DEBUGTRAP.

MachineRegisterInfo * getMRI()

Getter for MRI.

const DataLayout & getDataLayout() const

void setMF(MachineFunction &MF)

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const

const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register use operand.

MachineInstr * getInstr() const

If conversion operators fail, use this method to get the MachineInstr explicitly.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

const MachineOperand & getOperand(unsigned i) const

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

LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")

createVirtualRegister - Create and return a new virtual register in the function with the specified r...

bool doesNotAccessMemory() const

Whether this function accesses no memory.

bool onlyReadsMemory() const

Whether this function only (at most) reads memory.

Wrapper class representing virtual and physical registers.

constexpr bool isValid() const

bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override

This hook must be implemented to lower the given call instruction, including argument and return valu...

Definition SPIRVCallLowering.cpp:513

bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override

This hook must be implemented to lower outgoing return values, described by Val, into the specified v...

Definition SPIRVCallLowering.cpp:35

SPIRVCallLowering(const SPIRVTargetLowering &TLI, SPIRVGlobalRegistry *GR)

Definition SPIRVCallLowering.cpp:31

bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override

This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...

Definition SPIRVCallLowering.cpp:277

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

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

const Type * getTypeForSPIRVType(const SPIRVType *Ty) 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)

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

SPIRVEnvType getEnv() const

void setEnv(SPIRVEnvType E)

void push_back(const T &Elt)

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

const TargetRegisterInfo & getRegisterInfo() const

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

bool isPointerTy() const

True if this is an instance of PointerType.

A few GPU targets, such as DXIL and SPIR-V, have typed pointers.

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.

LLVM Value Representation.

Type * getType() const

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

iterator_range< user_iterator > users()

constexpr bool isZero() const

@ SPIR_KERNEL

Used for SPIR kernel functions.

std::optional< bool > lowerBuiltin(const StringRef DemangledCall, SPIRV::InstructionSet::InstructionSet Set, MachineIRBuilder &MIRBuilder, const Register OrigRet, const Type *OrigRetTy, const SmallVectorImpl< Register > &Args, SPIRVGlobalRegistry *GR, const CallBase &CB)

FunctionType * getOriginalFunctionType(const Function &F)

This is an optimization pass for GlobalISel generic memory operations.

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

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

unsigned getPointerAddressSpace(const Type *T)

decltype(auto) dyn_cast(const From &Val)

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

MemoryEffectsBase< IRMemLocation > MemoryEffects

Summary of how a function affects memory in the program.

MDString * getOCLKernelArgAccessQual(const Function &F, unsigned ArgIdx)

std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)

bool isTypedPointerTy(const Type *T)

auto dyn_cast_or_null(const Y &Val)

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

Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)

Type * toTypedPointer(Type *Ty)

void setRegClassType(Register Reg, SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)

bool isPointerTy(const Type *T)

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

std::optional< SPIRV::LinkageType::LinkageType > getSpirvLinkageTypeFor(const SPIRVSubtarget &ST, const GlobalValue &GV)

bool isEntryPoint(const Function &F)

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

MDString * getOCLKernelArgTypeQual(const Function &F, unsigned ArgIdx)

Type * getPointeeTypeByAttr(Argument *Arg)

bool hasPointeeTypeAttr(Argument *Arg)

decltype(auto) cast(const From &Val)

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

bool isPointerTyOrWrapper(const Type *Ty)

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

bool isUntypedPointerTy(const Type *T)