23#include "llvm/IR/IntrinsicsSPIRV.h"
25#define DEBUG_TYPE "spirv-prelegalizer"
39void SPIRVPreLegalizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
58 cast<Constant>(cast<ConstantAsMetadata>(
59 MI.getOperand(3).getMetadata()->getOperand(0))
61 if (
auto *GV = dyn_cast<GlobalValue>(Const)) {
64 GR->
add(GV,
MRI.getVRegDef(SrcReg));
67 RegsAlreadyAddedToDT[&
MI] = Reg;
71 if (
auto *ConstVec = dyn_cast<ConstantDataVector>(Const)) {
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) {
79 Constant *ElemConst = ConstVec->getElementAsConstant(i);
83 MRI.getVRegDef(BuildVec->getOperand(1 + i).getReg()));
85 BuildVec->getOperand(1 + i).setReg(ElemReg);
88 if (Const->getType()->isTargetExtTy()) {
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,
102 assert(SrcMI &&
"Expected source instruction to be valid");
109 RegsAlreadyAddedToDT[&
MI] = Reg;
112 assert(
MI.getOperand(2).isReg() &&
"Reg operand is expected");
114 if (SrcMI &&
isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
122 auto It = RegsAlreadyAddedToDT.
find(
MI);
123 if (It != RegsAlreadyAddedToDT.
end())
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();
134 MI->eraseFromParent();
146 const MDNode *MD =
MI.getOperand(2).getMetadata();
156 MI->eraseFromParent();
165 IE =
MRI->use_instr_end();
180 assert(ResType && OpType &&
"Operand types are expected");
184 if (!
MRI->getRegClassOrNull(ResVReg))
186 if (ResType == OpType)
218 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
222 MI.getOperand(1).getReg());
228 MI->eraseFromParent();
264 MRI->replaceRegWith(Def, Source);
274 MI->eraseFromParent();
296 assert(
MI &&
"Machine instr is expected");
297 if (
MI->getOperand(0).isReg()) {
301 switch (
MI->getOpcode()) {
302 case TargetOpcode::G_FCONSTANT:
303 case TargetOpcode::G_CONSTANT: {
305 Type *Ty =
MI->getOperand(1).getCImm()->getType();
307 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
310 case TargetOpcode::G_GLOBAL_VALUE: {
315 Global->getType()->getAddressSpace());
317 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
320 case TargetOpcode::G_ANYEXT:
321 case TargetOpcode::G_SEXT:
322 case TargetOpcode::G_ZEXT: {
323 if (
MI->getOperand(1).isReg()) {
325 MRI.getVRegDef(
MI->getOperand(1).getReg())) {
328 unsigned ExpectedBW =
329 std::max(
MRI.getType(Reg).getScalarSizeInBits(), CurrentBW);
340 case TargetOpcode::G_PTRTOINT:
342 MRI.getType(Reg).getScalarSizeInBits(), MIB);
344 case TargetOpcode::G_TRUNC:
345 case TargetOpcode::G_ADDRSPACE_CAST:
346 case TargetOpcode::G_PTR_ADD:
347 case TargetOpcode::COPY: {
359 LLT RegType =
MRI.getType(Reg);
360 if (SpvType->
getOpcode() == SPIRV::OpTypePointer &&
371 if (!
MRI.getRegClassOrNull(Reg))
373 : &SPIRV::iIDRegClass);
389 LLT RegType =
MRI.getType(Reg);
394 if (NewWidth != CurrentWidth)
402 if (NewWidth != CurrentWidth) {
412 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.
end();
414 while (DefIt !=
MBB.
end() &&
415 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
416 DefIt = std::next(DefIt);
424 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
429 SPIRV::AccessQualifier::ReadWrite,
true);
433 if (!
MRI.getRegClassOrNull(Reg))
435 if (!
MRI.getType(Reg).isValid())
443 Register NewReg =
MRI.createGenericVirtualRegister(
MRI.getType(Reg));
445 MRI.setRegClass(NewReg, RegClass);
446 MRI.setRegClass(Reg, RegClass);
454 const uint32_t Flags = Def->getFlags();
460 for (
unsigned I = 0, E = Def->getNumDefs();
I != E; ++
I) {
473 for (
auto &
Op :
MI.operands()) {
474 if (!
Op.isReg() ||
Op.isDef())
478 if (!SpvType && KnownResType) {
479 SpvType = KnownResType;
483 if (!
MRI.getRegClassOrNull(OpReg))
485 if (!
MRI.getType(OpReg).isValid())
503 bool IsExtendedInts =
505 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
506 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions) ||
507 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_int4);
513 bool ReachedBegin =
false;
517 unsigned MIOp =
MI.getOpcode();
519 if (!IsExtendedInts) {
521 for (
auto &MOP :
MI.operands()) {
524 else if (MOP.isCImm())
537 assert(Def &&
"Expecting an instruction that defines the register");
539 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
540 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
548 assert(Def &&
"Expecting an instruction that defines the register");
550 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
551 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
554 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
559 for (
unsigned I = 1, E =
MI.getNumOperands();
I != E && Def; ++
I)
565 cast<MDString>(MD->
getOperand(1))->getString();
573 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
574 MIOp == TargetOpcode::G_FCONSTANT ||
575 MIOp == TargetOpcode::G_BUILD_VECTOR) {
582 bool NeedAssignType =
true;
583 if (
MRI.hasOneUse(Reg)) {
588 if (
UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
589 NeedAssignType =
false;
592 if (MIOp == TargetOpcode::G_CONSTANT) {
593 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
594 Ty = TargetExtIt == TargetExtConstTypes.
end()
595 ?
MI.getOperand(1).getCImm()->getType()
596 : TargetExtIt->second;
609 }
else if (PrimaryReg != Reg &&
610 MRI.getType(Reg) ==
MRI.getType(PrimaryReg)) {
611 auto *RCReg =
MRI.getRegClassOrNull(Reg);
612 auto *RCPrimary =
MRI.getRegClassOrNull(PrimaryReg);
613 if (!RCReg || RCPrimary == RCReg) {
614 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
616 NeedAssignType =
false;
619 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
620 Ty =
MI.getOperand(1).getFPImm()->getType();
622 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
623 Type *ElemTy =
nullptr;
627 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
629 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
638 if (!NextMI || NextMI->
getOpcode() != SPIRV::ASSIGN_TYPE ||
644 Ty = VectorType::get(
645 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
648 NeedAssignType =
false;
652 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
663 auto It = RegsAlreadyAddedToDT.
find(
MI);
664 if (It != RegsAlreadyAddedToDT.
end())
665 MRI.replaceRegWith(
MI->getOperand(0).getReg(), It->second);
667 MI->eraseFromParent();
674 switch (
MI.getOpcode()) {
675 case TargetOpcode::G_TRUNC:
676 case TargetOpcode::G_ANYEXT:
677 case TargetOpcode::G_SEXT:
678 case TargetOpcode::G_ZEXT:
679 case TargetOpcode::G_PTRTOINT:
680 case TargetOpcode::COPY:
681 case TargetOpcode::G_ADDRSPACE_CAST:
705 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands();
Idx != MISz;
710 if (
Idx == AsmDescOp && MO.
isImm()) {
713 AsmDescOp += 1 +
F.getNumOperandRegisters();
734 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
735 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
742 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
746 GR->
add(AsmTargetMIB.getInstr(), AsmTargetMIB);
750 const MDNode *IAMD = I1->getOperand(1).getMetadata();
753 for (
const auto &ArgTy : FTy->params())
755 ArgTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
true));
758 SPIRV::AccessQualifier::ReadWrite,
true);
760 FTy, RetType, ArgTypes, MIRBuilder);
764 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);
765 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
774 addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
777 GR->
add(AsmMIB.getInstr(), AsmMIB);
784 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
789 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);
792 SPIRV::AccessQualifier::ReadWrite,
true);
796 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
800 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
801 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
805 MI->eraseFromParent();
816 MI.getOpcode() == TargetOpcode::INLINEASM)
820 if (ToProcess.
size() == 0)
823 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
825 "following SPIR-V extension: SPV_INTEL_inline_assembly",
837 return FPMaxError.Spir;
852 MI.getOperand(2).getMetadata());
854 Intrinsic::spv_assign_fpmaxerror_decoration)) {
855 ConstantFP *OpV = mdconst::dyn_extract<ConstantFP>(
856 MI.getOperand(2).getMetadata()->getOperand(0));
861 SPIRV::Decoration::FPMaxErrorDecorationINTEL,
865 MI.getOperand(2).getImm(),
866 MI.getOperand(3).getMetadata());
874 MI->eraseFromParent();
894 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
904 while (
MI.getNumOperands() > 0)
906 for (
auto &MO : NewOperands)
920 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
927 MI->eraseFromParent();
960 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
962 if (!
MI->getOperand(i).isReg()) {
970 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
975 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
980 auto It = BB2MBB.
find(BB);
981 if (It == BB2MBB.
end())
983 "in a switch statement");
987 ClearAddressTaken.
insert(ReferencedBlock);
988 ToEraseMI.
insert(BuildMBB);
993 while (
MI->getNumOperands() > 0)
994 MI->removeOperand(0);
995 for (
auto &MO : NewOps)
1001 Next =
MI->getNextNode();
1003 if (Next && Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
1012 Succ->setAddressTakenIRBlock(
nullptr);
1023 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
1025 BlockAddrI->getOperand(1).getBlockAddress());
1031 BlockAddrI->eraseFromParent();
1073 GR->setCurrentFunc(MF);
1099char SPIRVPreLegalizer::
ID = 0;
1102 return new SPIRVPreLegalizer();
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...
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.
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 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 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 SPIRVType * propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, 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 void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)
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.
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
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<GISelValueTrackingInfoAnal...
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.
LLVM_ABI bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
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.
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 <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.
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.
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)
LLVM_ABI 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
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)
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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.
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 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.
#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.
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.
void 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,...
bool isTypeFoldingSupported(unsigned Opcode)
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)
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)
@ Global
Append to llvm.global_dtors.
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
constexpr unsigned BitWidth
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)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)