23#include "llvm/IR/IntrinsicsSPIRV.h"
25#define DEBUG_TYPE "spirv-prelegalizer"
39void SPIRVPreLegalizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
47 MI->eraseFromParent();
65 MI.getOperand(3).getMetadata()->getOperand(0))
73 RegsAlreadyAddedToDT[&
MI] =
Reg;
80 BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
81 GR->
add(Const, BuildVec);
82 for (
unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
85 Constant *ElemConst = ConstVec->getElementAsConstant(i);
89 MRI.
getVRegDef(BuildVec->getOperand(1 + i).getReg()));
91 BuildVec->getOperand(1 + i).setReg(ElemReg);
94 if (Const->getType()->isTargetExtTy()) {
98 GR->
add(Const, SrcMI);
99 if (SrcMI && (SrcMI->
getOpcode() == TargetOpcode::G_CONSTANT ||
100 SrcMI->
getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
101 TargetExtConstTypes[SrcMI] = Const->getType();
102 if (Const->isNullValue()) {
106 Const->getType(), MIB, SPIRV::AccessQualifier::ReadWrite,
108 assert(SrcMI &&
"Expected source instruction to be valid");
115 RegsAlreadyAddedToDT[&
MI] =
Reg;
118 assert(
MI.getOperand(2).isReg() &&
"Reg operand is expected");
120 if (SrcMI &&
isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
128 auto It = RegsAlreadyAddedToDT.
find(
MI);
129 if (It != RegsAlreadyAddedToDT.
end())
149 const MDNode *MD =
MI.getOperand(2).getMetadata();
171 UseMI->getOperand(1).getReg() ==
Reg)
181 assert(ResType && OpType &&
"Operand types are expected");
187 if (ResType == OpType)
218 "Expected destination SPIR-V type to have been assigned already.");
221 "Expected source SPIR-V type to have been assigned already.");
222 if (DstType == SrcType) {
230 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
235 MI.getOperand(1).getReg());
261 ? SPIRV::StorageClass::CodeSectionINTEL
304 assert(
MI &&
"Machine instr is expected");
305 if (
MI->getOperand(0).isReg()) {
309 switch (
MI->getOpcode()) {
310 case TargetOpcode::G_FCONSTANT:
311 case TargetOpcode::G_CONSTANT: {
313 Type *Ty =
MI->getOperand(1).getCImm()->getType();
315 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
318 case TargetOpcode::G_GLOBAL_VALUE: {
323 Global->getType()->getAddressSpace());
325 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
328 case TargetOpcode::G_ANYEXT:
329 case TargetOpcode::G_SEXT:
330 case TargetOpcode::G_ZEXT: {
331 if (
MI->getOperand(1).isReg()) {
337 unsigned ExpectedBW =
349 case TargetOpcode::G_PTRTOINT:
353 case TargetOpcode::G_TRUNC:
354 case TargetOpcode::G_ADDRSPACE_CAST:
355 case TargetOpcode::G_PTR_ADD:
356 case TargetOpcode::COPY: {
369 if (SpvType->
getOpcode() == SPIRV::OpTypePointer &&
370 RegType.isPointer() &&
372 RegType.getAddressSpace()) {
382 : &SPIRV::iIDRegClass);
399 if (!RegType.isScalar())
403 if (NewWidth != CurrentWidth)
411 if (NewWidth != CurrentWidth) {
421 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.end();
423 while (DefIt !=
MBB.end() &&
424 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
425 DefIt = std::next(DefIt);
433 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
438 SPIRV::AccessQualifier::ReadWrite,
true);
450 for (
auto &
Op :
MI.operands()) {
451 if (!
Op.isReg() ||
Op.isDef())
455 if (!SpvType && KnownResType) {
456 SpvType = KnownResType;
480 bool IsExtendedInts =
482 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
483 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions) ||
484 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_int4);
486 if (!IsExtendedInts) {
507 unsigned MIOp =
MI.getOpcode();
508 if (MIOp != TargetOpcode::G_TRUNC)
530 if (OriginalDstWidth == NewDstWidth)
541 MIB.
buildAnd(MaskedReg, SrcReg, MaskReg);
543 if (NewSrcWidth == NewDstWidth) {
547 MI.getOperand(1).setReg(MaskedReg);
552 MI->eraseFromParent();
559 bool ReachedBegin =
false;
560 for (
auto MII = std::prev(
MBB->end()), Begin =
MBB->begin();
563 unsigned MIOp =
MI.getOpcode();
565 if (!IsExtendedInts) {
567 for (
auto &MOP :
MI.operands()) {
570 else if (MOP.isCImm())
583 assert(Def &&
"Expecting an instruction that defines the register");
585 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
593 assert(Def &&
"Expecting an instruction that defines the register");
595 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
598 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
603 for (
unsigned I = 1,
E =
MI.getNumOperands();
I !=
E && Def; ++
I)
617 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
618 MIOp == TargetOpcode::G_FCONSTANT ||
619 MIOp == TargetOpcode::G_BUILD_VECTOR) {
625 if (MIOp == TargetOpcode::G_CONSTANT) {
626 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
627 Ty = TargetExtIt == TargetExtConstTypes.
end()
628 ?
MI.getOperand(1).getCImm()->getType()
629 : TargetExtIt->second;
642 }
else if (PrimaryReg !=
Reg &&
646 if (!RCReg || RCPrimary == RCReg) {
647 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
649 NeedAssignType =
false;
652 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
653 Ty =
MI.getOperand(1).getFPImm()->getType();
655 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
656 Type *ElemTy =
nullptr;
660 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
662 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
671 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
674 NeedAssignType =
false;
678 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
689 auto It = RegsAlreadyAddedToDT.
find(
MI);
690 if (It != RegsAlreadyAddedToDT.
end())
699 switch (
MI.getOpcode()) {
700 case TargetOpcode::G_TRUNC:
701 case TargetOpcode::G_ANYEXT:
702 case TargetOpcode::G_SEXT:
703 case TargetOpcode::G_ZEXT:
704 case TargetOpcode::G_PTRTOINT:
705 case TargetOpcode::COPY:
706 case TargetOpcode::G_ADDRSPACE_CAST:
730 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands(); Idx != MISz;
735 if (Idx == AsmDescOp && MO.
isImm()) {
738 AsmDescOp += 1 +
F.getNumOperandRegisters();
758 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
759 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
766 MRI.
setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
770 GR->
add(AsmTargetMIB.getInstr(), AsmTargetMIB);
774 const MDNode *IAMD = I1->getOperand(1).getMetadata();
777 for (
const auto &ArgTy : FTy->params())
779 ArgTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
true));
782 SPIRV::AccessQualifier::ReadWrite,
true);
784 FTy, RetType, ArgTypes, MIRBuilder);
789 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
801 GR->
add(AsmMIB.getInstr(), AsmMIB);
808 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
816 SPIRV::AccessQualifier::ReadWrite,
true);
820 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
824 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
825 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
834 if (CopyMI.
getOpcode() == TargetOpcode::COPY) {
838 if (TruncMI.
getOpcode() == TargetOpcode::G_TRUNC) {
860 MI.getOpcode() == TargetOpcode::INLINEASM)
864 if (ToProcess.
size() == 0)
867 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
869 "following SPIR-V extension: SPV_INTEL_inline_assembly",
881 return FPMaxError.Spir;
897 MI.getOperand(2).getMetadata(), ST);
899 Intrinsic::spv_assign_fpmaxerror_decoration)) {
901 MI.getOperand(2).getMetadata()->getOperand(0));
906 SPIRV::Decoration::FPMaxErrorDecorationINTEL,
910 MI.getOperand(2).getImm(),
911 MI.getOperand(3).getMetadata());
937 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
947 while (
MI.getNumOperands() > 0)
949 for (
auto &MO : NewOperands)
963 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
979 BB2MBB[
MBB.getBasicBlock()] = &
MBB;
1001 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
1003 if (!
MI->getOperand(i).isReg()) {
1011 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
1016 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
1021 auto It = BB2MBB.
find(BB);
1022 if (It == BB2MBB.
end())
1024 "in a switch statement");
1028 ClearAddressTaken.
insert(ReferencedBlock);
1029 ToEraseMI.
insert(BuildMBB);
1034 while (
MI->getNumOperands() > 0)
1035 MI->removeOperand(0);
1036 for (
auto &MO : NewOps)
1042 Next =
MI->getNextNode();
1044 if (
Next &&
Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
1053 Succ->setAddressTakenIRBlock(
nullptr);
1064 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
1066 BlockAddrI->getOperand(1).getBlockAddress());
1077 return MBB.getNextNode() !=
nullptr;
1081 if (!
MBB.canFallThrough())
1108bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
1111 SPIRVGlobalRegistry *GR =
ST.getSPIRVGlobalRegistry();
1112 GR->setCurrentFunc(MF);
1113 MachineIRBuilder MIB(MF);
1115 DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
1138char SPIRVPreLegalizer::
ID = 0;
1141 return new SPIRVPreLegalizer();
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)
static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder)
static void cleanupHelperInstructions(MachineFunction &MF, SPIRVGlobalRegistry *GR)
static void insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder, const SmallVector< MachineInstr * > &ToProcess)
static void removeImplicitFallthroughs(MachineFunction &MF, MachineIRBuilder MIB)
static unsigned widenBitWidthToNextPow2(unsigned BitWidth)
static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def)
static bool isImplicitFallthrough(MachineBasicBlock &MBB)
static void insertSpirvDecorations(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void processInstrsWithTypeFolding(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void processSwitchesConstants(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void lowerBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static MachineInstr * findAssignTypeInstr(Register Reg, MachineRegisterInfo *MRI)
static void widenCImmType(MachineOperand &MOP)
static void buildOpBitcast(SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, Register ResVReg, Register OpReg)
static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void widenScalarType(Register Reg, MachineRegisterInfo &MRI)
static void foldConstantsIntoIntrinsics(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &STI, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)
static uint32_t convertFloatToSPIRVWord(float F)
static SPIRVTypeInst propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, MachineIRBuilder &MIB)
static void invalidateAndEraseMI(SPIRVGlobalRegistry *GR, MachineInstr *MI)
static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)
LLVM_ABI float convertToFloat() const
Converts this APFloat to host float value.
Class for arbitrary precision integers.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
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 isValid() 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 buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
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.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
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,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
static use_instr_iterator use_instr_end()
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void assignSPIRVTypeToVReg(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
SPIRVTypeInst getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVTypeInst RetType, const SmallVectorImpl< SPIRVTypeInst > &ArgTypes, MachineIRBuilder &MIRBuilder)
const TargetRegisterClass * getRegClass(SPIRVTypeInst SpvType) const
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
SPIRVTypeInst getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVVectorType(SPIRVTypeInst BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
unsigned getScalarOrVectorComponentCount(Register VReg) const
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const
LLT getRegType(SPIRVTypeInst SpvType) const
void invalidateMachineInstr(MachineInstr *MI)
SPIRVTypeInst getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
SPIRVTypeInst changePointerStorageClass(SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Type * getDeducedGlobalValueType(const GlobalValue *Global)
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
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<X> - Return the argument parameter cast to the specified type.
FunctionPass * createSPIRVPreLegalizerPass()
void updateRegType(Register Reg, Type *Ty, SPIRVTypeInst SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Helper external function for assigning a SPIRV type to a register, ensuring the register class and ty...
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
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)
auto post_order(const T &G)
Post-order traversal of a graph.
bool isa(const From &Val)
isa<X> - 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)
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR, SPIRVTypeInst KnownResType)
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - 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)