23#include "llvm/IR/IntrinsicsSPIRV.h"
26#define DEBUG_TYPE "spirv-prelegalizer"
56 cast<Constant>(cast<ConstantAsMetadata>(
57 MI.getOperand(3).getMetadata()->getOperand(0))
59 if (
auto *GV = dyn_cast<GlobalValue>(Const)) {
62 GR->
add(GV, &MF, SrcReg);
65 RegsAlreadyAddedToDT[&
MI] = Reg;
69 if (
auto *ConstVec = dyn_cast<ConstantDataVector>(Const)) {
70 auto *BuildVec =
MRI.getVRegDef(SrcReg);
72 BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
73 for (
unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
76 Constant *ElemConst = ConstVec->getElementAsConstant(i);
79 GR->
add(ElemConst, &MF, BuildVec->getOperand(1 + i).getReg());
81 BuildVec->getOperand(1 + i).setReg(ElemReg);
84 GR->
add(Const, &MF, SrcReg);
85 TrackedConstRegs.
insert(SrcReg);
86 if (Const->getType()->isTargetExtTy()) {
89 if (SrcMI && (SrcMI->
getOpcode() == TargetOpcode::G_CONSTANT ||
90 SrcMI->
getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
91 TargetExtConstTypes[SrcMI] = Const->getType();
92 if (Const->isNullValue()) {
102 RegsAlreadyAddedToDT[&
MI] = Reg;
105 assert(
MI.getOperand(2).isReg() &&
"Reg operand is expected");
107 if (SrcMI &&
isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
116 Reg = RegsAlreadyAddedToDT[
MI];
117 auto *RC =
MRI.getRegClassOrNull(
MI->getOperand(0).getReg());
118 if (!
MRI.getRegClassOrNull(Reg) && RC)
119 MRI.setRegClass(Reg, RC);
120 MRI.replaceRegWith(
MI->getOperand(0).getReg(), Reg);
121 MI->eraseFromParent();
124 MI->eraseFromParent();
132 const unsigned AssignNameOperandShift = 2;
137 unsigned NumOp =
MI.getNumExplicitDefs() + AssignNameOperandShift;
138 while (
MI.getOperand(NumOp).isReg()) {
142 MI.removeOperand(NumOp);
146 if (
MRI.use_empty(DefReg) && !TrackedConstRegs.
contains(DefReg))
152 MI->eraseFromParent();
158 IE =
MRI->use_instr_end();
173 assert(ResType && OpType &&
"Operand types are expected");
177 if (!
MRI->getRegClassOrNull(ResVReg))
179 if (ResType == OpType)
211 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
215 MI.getOperand(1).getReg());
220 MI->eraseFromParent();
256 MRI->replaceRegWith(Def, Source);
264 MI->eraseFromParent();
285 assert(
MI &&
"Machine instr is expected");
286 if (
MI->getOperand(0).isReg()) {
290 switch (
MI->getOpcode()) {
291 case TargetOpcode::G_FCONSTANT:
292 case TargetOpcode::G_CONSTANT: {
294 Type *Ty =
MI->getOperand(1).getCImm()->getType();
298 case TargetOpcode::G_GLOBAL_VALUE: {
303 Global->getType()->getAddressSpace());
307 case TargetOpcode::G_ANYEXT:
308 case TargetOpcode::G_SEXT:
309 case TargetOpcode::G_ZEXT: {
310 if (
MI->getOperand(1).isReg()) {
312 MRI.getVRegDef(
MI->getOperand(1).getReg())) {
315 unsigned ExpectedBW =
316 std::max(
MRI.getType(Reg).getScalarSizeInBits(), CurrentBW);
327 case TargetOpcode::G_PTRTOINT:
329 MRI.getType(Reg).getScalarSizeInBits(), MIB);
331 case TargetOpcode::G_TRUNC:
332 case TargetOpcode::G_ADDRSPACE_CAST:
333 case TargetOpcode::G_PTR_ADD:
334 case TargetOpcode::COPY: {
346 LLT RegType =
MRI.getType(Reg);
347 if (SpvType->
getOpcode() == SPIRV::OpTypePointer &&
359 if (!
MRI.getRegClassOrNull(Reg))
361 : &SPIRV::iIDRegClass);
371 LLT RegType =
MRI.getType(Reg);
377 unsigned NewSz = std::min(std::max(1u <<
Log2_32_Ceil(Sz), 8u), 64u);
382static std::pair<Register, unsigned>
389 MRI.setRegClass(Reg, RC);
390 unsigned GetIdOp = SPIRV::GET_ID;
391 if (RC == &SPIRV::fIDRegClass)
392 GetIdOp = SPIRV::GET_fID;
393 else if (RC == &SPIRV::pIDRegClass)
394 GetIdOp = SPIRV::GET_pID;
395 else if (RC == &SPIRV::vfIDRegClass)
396 GetIdOp = SPIRV::GET_vfID;
397 else if (RC == &SPIRV::vpIDRegClass)
398 GetIdOp = SPIRV::GET_vpID;
399 else if (RC == &SPIRV::vIDRegClass)
400 GetIdOp = SPIRV::GET_vID;
401 return {Reg, GetIdOp};
407 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.
end();
409 while (DefIt !=
MBB.
end() &&
410 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
411 DefIt = std::next(DefIt);
424 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
428 Register NewReg =
MRI.createGenericVirtualRegister(
MRI.getType(Reg));
429 if (
auto *RC =
MRI.getRegClassOrNull(Reg)) {
430 MRI.setRegClass(NewReg, RC);
433 MRI.setRegClass(NewReg, RegClass);
434 MRI.setRegClass(Reg, RegClass);
442 const uint32_t Flags = Def->getFlags();
448 for (
unsigned I = 0, E = Def->getNumDefs();
I != E; ++
I) {
461 for (
auto &
Op :
MI.operands()) {
462 if (!
Op.isReg() ||
Op.isDef())
469 if (RC !=
MRI.getRegClassOrNull(OpReg))
470 MRI.setRegClass(OpReg, RC);
471 Op.setReg(IdOpInfo.first);
488 bool IsExtendedInts =
490 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
491 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
497 bool ReachedBegin =
false;
501 unsigned MIOp =
MI.getOpcode();
503 if (!IsExtendedInts) {
505 for (
const auto &MOP :
MI.operands())
519 assert(Def &&
"Expecting an instruction that defines the register");
521 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
522 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
530 assert(Def &&
"Expecting an instruction that defines the register");
532 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
533 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
536 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
541 for (
unsigned I = 1, E =
MI.getNumOperands();
I != E && Def; ++
I)
547 cast<MDString>(MD->
getOperand(1))->getString();
555 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
556 MIOp == TargetOpcode::G_FCONSTANT ||
557 MIOp == TargetOpcode::G_BUILD_VECTOR) {
564 bool NeedAssignType =
true;
565 if (
MRI.hasOneUse(Reg)) {
570 if (
UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
571 NeedAssignType =
false;
574 if (MIOp == TargetOpcode::G_CONSTANT) {
575 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
576 Ty = TargetExtIt == TargetExtConstTypes.
end()
577 ?
MI.getOperand(1).getCImm()->getType()
578 : TargetExtIt->second;
590 GR->
add(OpCI, &MF, Reg);
591 }
else if (PrimaryReg != Reg &&
592 MRI.getType(Reg) ==
MRI.getType(PrimaryReg)) {
593 auto *RCReg =
MRI.getRegClassOrNull(Reg);
594 auto *RCPrimary =
MRI.getRegClassOrNull(PrimaryReg);
595 if (!RCReg || RCPrimary == RCReg) {
596 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
598 NeedAssignType =
false;
601 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
602 Ty =
MI.getOperand(1).getFPImm()->getType();
604 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
605 Type *ElemTy =
nullptr;
609 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
611 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
616 if (!NextMI || NextMI->
getOpcode() != SPIRV::ASSIGN_TYPE ||
621 Ty = VectorType::get(
622 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
625 NeedAssignType =
false;
629 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
640 auto It = RegsAlreadyAddedToDT.
find(
MI);
642 MRI.replaceRegWith(
MI->getOperand(0).getReg(), It->second);
643 MI->eraseFromParent();
650 switch (
MI.getOpcode()) {
651 case TargetOpcode::G_TRUNC:
652 case TargetOpcode::G_ANYEXT:
653 case TargetOpcode::G_SEXT:
654 case TargetOpcode::G_ZEXT:
655 case TargetOpcode::G_PTRTOINT:
656 case TargetOpcode::COPY:
657 case TargetOpcode::G_ADDRSPACE_CAST:
684 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands();
Idx != MISz;
689 if (
Idx == AsmDescOp && MO.
isImm()) {
692 AsmDescOp += 1 +
F.getNumOperandRegisters();
713 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
714 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
721 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
725 GR->
add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);
729 const MDNode *IAMD = I1->getOperand(1).getMetadata();
732 for (
const auto &ArgTy : FTy->params())
737 FTy, RetType, ArgTypes, MIRBuilder);
741 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);
742 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
751 addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
754 GR->
add(AsmMIB.getInstr(), &MF, AsmReg);
761 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
766 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);
772 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
776 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
777 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
780 MI->eraseFromParent();
790 MI.getOpcode() == TargetOpcode::INLINEASM)
794 if (ToProcess.
size() == 0)
797 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
799 "following SPIR-V extension: SPV_INTEL_inline_assembly",
813 MI.getOperand(2).getMetadata());
818 MI->eraseFromParent();
837 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
847 while (
MI.getNumOperands() > 0)
849 for (
auto &MO : NewOperands)
862 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
868 MI->eraseFromParent();
900 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
902 if (!
MI->getOperand(i).isReg()) {
910 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
915 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
920 auto It = BB2MBB.
find(BB);
921 if (It == BB2MBB.
end())
923 "in a switch statement");
927 ClearAddressTaken.
insert(ReferencedBlock);
928 ToEraseMI.
insert(BuildMBB);
933 while (
MI->getNumOperands() > 0)
934 MI->removeOperand(0);
935 for (
auto &MO : NewOps)
941 Next =
MI->getNextNode();
943 if (Next && Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
952 Succ->setAddressTakenIRBlock(
nullptr);
963 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
965 BlockAddrI->getOperand(1).getBlockAddress());
970 BlockAddrI->eraseFromParent();
1012 GR->setCurrentFunc(MF);
1039char SPIRVPreLegalizer::
ID = 0;
1042 return new SPIRVPreLegalizer();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
This file contains the simple types necessary to represent the attributes associated with functions a...
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
#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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Register collectInlineAsmInstrOperands(MachineInstr *MI, SmallVector< unsigned, 4 > *Ops=nullptr)
static void cleanupHelperInstructions(MachineFunction &MF)
static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder)
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 void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def)
static bool isImplicitFallthrough(MachineBasicBlock &MBB)
bool isTypeFoldingSupported(unsigned Opcode)
static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void processInstrsWithTypeFolding(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void widenScalarLLTNextPow2(Register Reg, MachineRegisterInfo &MRI)
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 buildOpBitcast(SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, Register ResVReg, Register OpReg)
static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
static void addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &STI, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes, SmallSet< Register, 4 > &TrackedConstRegs)
static void foldConstantsIntoIntrinsics(MachineFunction &MF, const SmallSet< Register, 4 > &TrackedConstRegs)
static void insertSpirvDecorations(MachineFunction &MF, MachineIRBuilder MIB)
static std::pair< Register, unsigned > createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI, const SPIRVGlobalRegistry &GR)
static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)
LLVM Basic Block Representation.
The address of a basic block.
BasicBlock * getBasicBlock() const
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
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)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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.
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.
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
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.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
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)
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
static MachineOperand CreateImm(int64_t Val)
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,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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)
void add(const Constant *C, MachineFunction *MF, Register R)
bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const
unsigned getScalarOrVectorComponentCount(Register VReg) const
SPIRVType * getPointeeType(SPIRVType *PtrType)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
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
Register find(const MachineInstr *MI, MachineFunction *MF)
SPIRVType * getOrCreateSPIRVPointerType(SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SClass=SPIRV::StorageClass::Function)
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder)
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)
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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 Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static 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.
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.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
FunctionPass * createSPIRVPreLegalizerPass()
Register 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,...
iterator_range< po_iterator< T > > post_order(const T &G)
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
Type * toTypedPointer(Type *Ty)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Global
Append to llvm.global_dtors.
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
Type * getMDOperandAsType(const MDNode *N, unsigned I)
void initializeSPIRVPreLegalizerPass(PassRegistry &)
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)