23#include "llvm/IR/IntrinsicsSPIRV.h"
25#define DEBUG_TYPE "spirv-prelegalizer"
39void SPIRVPreLegalizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
59 MI.getOperand(3).getMetadata()->getOperand(0))
64 GR->
add(GV,
MRI.getVRegDef(SrcReg));
67 RegsAlreadyAddedToDT[&
MI] =
Reg;
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)
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();
170 UseMI->getOperand(1).getReg() ==
Reg)
180 assert(ResType && OpType &&
"Operand types are expected");
184 if (!
MRI->getRegClassOrNull(ResVReg))
186 if (ResType == OpType)
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) {
229 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
234 MI.getOperand(1).getReg());
240 MI->eraseFromParent();
271 MRI->replaceRegWith(Def, Source);
281 MI->eraseFromParent();
303 assert(
MI &&
"Machine instr is expected");
304 if (
MI->getOperand(0).isReg()) {
308 switch (
MI->getOpcode()) {
309 case TargetOpcode::G_FCONSTANT:
310 case TargetOpcode::G_CONSTANT: {
312 Type *Ty =
MI->getOperand(1).getCImm()->getType();
314 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
317 case TargetOpcode::G_GLOBAL_VALUE: {
322 Global->getType()->getAddressSpace());
324 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
327 case TargetOpcode::G_ANYEXT:
328 case TargetOpcode::G_SEXT:
329 case TargetOpcode::G_ZEXT: {
330 if (
MI->getOperand(1).isReg()) {
332 MRI.getVRegDef(
MI->getOperand(1).getReg())) {
335 unsigned ExpectedBW =
336 std::max(
MRI.getType(
Reg).getScalarSizeInBits(), CurrentBW);
347 case TargetOpcode::G_PTRTOINT:
349 MRI.getType(
Reg).getScalarSizeInBits(), MIB);
351 case TargetOpcode::G_TRUNC:
352 case TargetOpcode::G_ADDRSPACE_CAST:
353 case TargetOpcode::G_PTR_ADD:
354 case TargetOpcode::COPY: {
367 if (SpvType->
getOpcode() == SPIRV::OpTypePointer &&
378 if (!
MRI.getRegClassOrNull(
Reg))
380 : &SPIRV::iIDRegClass);
401 if (NewWidth != CurrentWidth)
409 if (NewWidth != CurrentWidth) {
419 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.end();
421 while (DefIt !=
MBB.end() &&
422 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
423 DefIt = std::next(DefIt);
431 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
436 SPIRV::AccessQualifier::ReadWrite,
true);
440 if (!
MRI.getRegClassOrNull(Reg))
442 if (!
MRI.getType(Reg).isValid())
450 Register NewReg =
MRI.createGenericVirtualRegister(
MRI.getType(Reg));
452 MRI.setRegClass(NewReg, RegClass);
453 MRI.setRegClass(Reg, RegClass);
461 const uint32_t Flags = Def->getFlags();
467 for (
unsigned I = 0, E = Def->getNumDefs();
I != E; ++
I) {
480 for (
auto &
Op :
MI.operands()) {
481 if (!
Op.isReg() ||
Op.isDef())
485 if (!SpvType && KnownResType) {
486 SpvType = KnownResType;
490 if (!
MRI.getRegClassOrNull(OpReg))
492 if (!
MRI.getType(OpReg).isValid())
510 bool IsExtendedInts =
512 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
513 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions) ||
514 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_int4);
520 bool ReachedBegin =
false;
521 for (
auto MII = std::prev(
MBB->end()), Begin =
MBB->begin();
524 unsigned MIOp =
MI.getOpcode();
526 if (!IsExtendedInts) {
528 for (
auto &MOP :
MI.operands()) {
531 else if (MOP.isCImm())
544 assert(Def &&
"Expecting an instruction that defines the register");
546 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
547 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
555 assert(Def &&
"Expecting an instruction that defines the register");
557 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
558 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
561 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
566 for (
unsigned I = 1,
E =
MI.getNumOperands();
I !=
E && Def; ++
I)
580 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
581 MIOp == TargetOpcode::G_FCONSTANT ||
582 MIOp == TargetOpcode::G_BUILD_VECTOR) {
589 bool NeedAssignType =
true;
595 if (
UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
596 NeedAssignType =
false;
599 if (MIOp == TargetOpcode::G_CONSTANT) {
600 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
601 Ty = TargetExtIt == TargetExtConstTypes.
end()
602 ?
MI.getOperand(1).getCImm()->getType()
603 : TargetExtIt->second;
616 }
else if (PrimaryReg !=
Reg &&
617 MRI.getType(
Reg) ==
MRI.getType(PrimaryReg)) {
618 auto *RCReg =
MRI.getRegClassOrNull(
Reg);
619 auto *RCPrimary =
MRI.getRegClassOrNull(PrimaryReg);
620 if (!RCReg || RCPrimary == RCReg) {
621 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
623 NeedAssignType =
false;
626 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
627 Ty =
MI.getOperand(1).getFPImm()->getType();
629 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
630 Type *ElemTy =
nullptr;
634 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
636 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
645 if (!NextMI || NextMI->
getOpcode() != SPIRV::ASSIGN_TYPE ||
652 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
655 NeedAssignType =
false;
659 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
670 auto It = RegsAlreadyAddedToDT.
find(
MI);
671 if (It != RegsAlreadyAddedToDT.
end())
672 MRI.replaceRegWith(
MI->getOperand(0).getReg(), It->second);
674 MI->eraseFromParent();
681 switch (
MI.getOpcode()) {
682 case TargetOpcode::G_TRUNC:
683 case TargetOpcode::G_ANYEXT:
684 case TargetOpcode::G_SEXT:
685 case TargetOpcode::G_ZEXT:
686 case TargetOpcode::G_PTRTOINT:
687 case TargetOpcode::COPY:
688 case TargetOpcode::G_ADDRSPACE_CAST:
712 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands(); Idx != MISz;
717 if (Idx == AsmDescOp && MO.
isImm()) {
720 AsmDescOp += 1 +
F.getNumOperandRegisters();
741 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
742 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
749 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
753 GR->
add(AsmTargetMIB.getInstr(), AsmTargetMIB);
757 const MDNode *IAMD = I1->getOperand(1).getMetadata();
760 for (
const auto &ArgTy : FTy->params())
762 ArgTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
true));
765 SPIRV::AccessQualifier::ReadWrite,
true);
767 FTy, RetType, ArgTypes, MIRBuilder);
771 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);
772 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
784 GR->
add(AsmMIB.getInstr(), AsmMIB);
791 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
796 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);
799 SPIRV::AccessQualifier::ReadWrite,
true);
803 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
807 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
808 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
812 MI->eraseFromParent();
823 MI.getOpcode() == TargetOpcode::INLINEASM)
827 if (ToProcess.
size() == 0)
830 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
832 "following SPIR-V extension: SPV_INTEL_inline_assembly",
844 return FPMaxError.Spir;
860 MI.getOperand(2).getMetadata(), ST);
862 Intrinsic::spv_assign_fpmaxerror_decoration)) {
864 MI.getOperand(2).getMetadata()->getOperand(0));
869 SPIRV::Decoration::FPMaxErrorDecorationINTEL,
873 MI.getOperand(2).getImm(),
874 MI.getOperand(3).getMetadata());
882 MI->eraseFromParent();
902 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
912 while (
MI.getNumOperands() > 0)
914 for (
auto &MO : NewOperands)
928 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
935 MI->eraseFromParent();
946 BB2MBB[
MBB.getBasicBlock()] = &
MBB;
968 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
970 if (!
MI->getOperand(i).isReg()) {
978 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
983 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
988 auto It = BB2MBB.
find(BB);
989 if (It == BB2MBB.
end())
991 "in a switch statement");
995 ClearAddressTaken.
insert(ReferencedBlock);
996 ToEraseMI.
insert(BuildMBB);
1001 while (
MI->getNumOperands() > 0)
1002 MI->removeOperand(0);
1003 for (
auto &MO : NewOps)
1009 Next =
MI->getNextNode();
1011 if (
Next &&
Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
1020 Succ->setAddressTakenIRBlock(
nullptr);
1031 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
1033 BlockAddrI->getOperand(1).getBlockAddress());
1039 BlockAddrI->eraseFromParent();
1049 if (!
MBB.canFallThrough())
1070 assert(std::distance(
MBB.successors().begin(),
MBB.successors().end()) ==
1077bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
1080 SPIRVGlobalRegistry *GR =
ST.getSPIRVGlobalRegistry();
1081 GR->setCurrentFunc(MF);
1082 MachineIRBuilder MIB(MF);
1084 DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
1107char SPIRVPreLegalizer::
ID = 0;
1110 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...
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 SPIRVType * propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, 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 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.
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 <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.
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)
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.
#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.
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.
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,...
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()
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)
const MachineInstr SPIRVType
@ 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<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)