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);
64 RegsAlreadyAddedToDT[&
MI] = Reg;
68 if (
auto *ConstVec = dyn_cast<ConstantDataVector>(Const)) {
69 auto *BuildVec =
MRI.getVRegDef(SrcReg);
71 BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
72 for (
unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
75 Constant *ElemConst = ConstVec->getElementAsConstant(i);
78 GR->
add(ElemConst, &MF, BuildVec->getOperand(1 + i).getReg());
80 BuildVec->getOperand(1 + i).setReg(ElemReg);
83 GR->
add(Const, &MF, SrcReg);
84 TrackedConstRegs.
insert(SrcReg);
85 if (Const->getType()->isTargetExtTy()) {
88 if (SrcMI && (SrcMI->
getOpcode() == TargetOpcode::G_CONSTANT ||
89 SrcMI->
getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
90 TargetExtConstTypes[SrcMI] = Const->getType();
91 if (Const->isNullValue()) {
101 RegsAlreadyAddedToDT[&
MI] = Reg;
104 assert(
MI.getOperand(2).isReg() &&
"Reg operand is expected");
106 if (SrcMI &&
isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
115 Reg = RegsAlreadyAddedToDT[
MI];
116 auto *RC =
MRI.getRegClassOrNull(
MI->getOperand(0).getReg());
117 if (!
MRI.getRegClassOrNull(Reg) && RC)
118 MRI.setRegClass(Reg, RC);
119 MRI.replaceRegWith(
MI->getOperand(0).getReg(), Reg);
120 MI->eraseFromParent();
123 MI->eraseFromParent();
131 const unsigned AssignNameOperandShift = 2;
136 unsigned NumOp =
MI.getNumExplicitDefs() + AssignNameOperandShift;
137 while (
MI.getOperand(NumOp).isReg()) {
141 MI.removeOperand(NumOp);
145 if (
MRI.use_empty(DefReg) && !TrackedConstRegs.
contains(DefReg))
151 MI->eraseFromParent();
157 IE =
MRI->use_instr_end();
172 assert(ResType && OpType &&
"Operand types are expected");
176 if (!
MRI->getRegClassOrNull(ResVReg))
178 if (ResType == OpType)
210 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
214 MI.getOperand(1).getReg());
219 MI->eraseFromParent();
255 MRI->replaceRegWith(Def, Source);
263 MI->eraseFromParent();
284 assert(
MI &&
"Machine instr is expected");
285 if (
MI->getOperand(0).isReg()) {
289 switch (
MI->getOpcode()) {
290 case TargetOpcode::G_FCONSTANT:
291 case TargetOpcode::G_CONSTANT: {
293 Type *Ty =
MI->getOperand(1).getCImm()->getType();
297 case TargetOpcode::G_GLOBAL_VALUE: {
302 Global->getType()->getAddressSpace());
306 case TargetOpcode::G_ANYEXT:
307 case TargetOpcode::G_SEXT:
308 case TargetOpcode::G_ZEXT: {
309 if (
MI->getOperand(1).isReg()) {
311 MRI.getVRegDef(
MI->getOperand(1).getReg())) {
314 unsigned ExpectedBW =
315 std::max(
MRI.getType(Reg).getScalarSizeInBits(), CurrentBW);
326 case TargetOpcode::G_PTRTOINT:
328 MRI.getType(Reg).getScalarSizeInBits(), MIB);
330 case TargetOpcode::G_TRUNC:
331 case TargetOpcode::G_ADDRSPACE_CAST:
332 case TargetOpcode::G_PTR_ADD:
333 case TargetOpcode::COPY: {
345 LLT RegType =
MRI.getType(Reg);
346 if (SpvType->
getOpcode() == SPIRV::OpTypePointer &&
358 if (!
MRI.getRegClassOrNull(Reg))
360 : &SPIRV::iIDRegClass);
370 LLT RegType =
MRI.getType(Reg);
376 unsigned NewSz = std::min(std::max(1u <<
Log2_32_Ceil(Sz), 8u), 64u);
381static std::pair<Register, unsigned>
388 MRI.setRegClass(Reg, RC);
389 unsigned GetIdOp = SPIRV::GET_ID;
390 if (RC == &SPIRV::fIDRegClass)
391 GetIdOp = SPIRV::GET_fID;
392 else if (RC == &SPIRV::pIDRegClass)
393 GetIdOp = SPIRV::GET_pID;
394 else if (RC == &SPIRV::vfIDRegClass)
395 GetIdOp = SPIRV::GET_vfID;
396 else if (RC == &SPIRV::vpIDRegClass)
397 GetIdOp = SPIRV::GET_vpID;
398 else if (RC == &SPIRV::vIDRegClass)
399 GetIdOp = SPIRV::GET_vID;
400 return {Reg, GetIdOp};
406 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.
end();
408 while (DefIt !=
MBB.
end() &&
409 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
410 DefIt = std::next(DefIt);
423 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
427 Register NewReg =
MRI.createGenericVirtualRegister(
MRI.getType(Reg));
428 if (
auto *RC =
MRI.getRegClassOrNull(Reg)) {
429 MRI.setRegClass(NewReg, RC);
432 MRI.setRegClass(NewReg, RegClass);
433 MRI.setRegClass(Reg, RegClass);
441 const uint32_t Flags = Def->getFlags();
447 for (
unsigned I = 0, E = Def->getNumDefs();
I != E; ++
I) {
460 for (
auto &
Op :
MI.operands()) {
461 if (!
Op.isReg() ||
Op.isDef())
468 if (RC !=
MRI.getRegClassOrNull(OpReg))
469 MRI.setRegClass(OpReg, RC);
470 Op.setReg(IdOpInfo.first);
487 bool IsExtendedInts =
489 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
490 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
496 bool ReachedBegin =
false;
500 unsigned MIOp =
MI.getOpcode();
502 if (!IsExtendedInts) {
504 for (
const auto &MOP :
MI.operands())
518 assert(Def &&
"Expecting an instruction that defines the register");
520 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
521 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
529 assert(Def &&
"Expecting an instruction that defines the register");
531 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
532 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
535 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
540 for (
unsigned I = 1, E =
MI.getNumOperands();
I != E && Def; ++
I)
546 cast<MDString>(MD->
getOperand(1))->getString();
554 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
555 MIOp == TargetOpcode::G_FCONSTANT ||
556 MIOp == TargetOpcode::G_BUILD_VECTOR) {
563 bool NeedAssignType =
true;
564 if (
MRI.hasOneUse(Reg)) {
569 if (
UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
570 NeedAssignType =
false;
573 if (MIOp == TargetOpcode::G_CONSTANT) {
574 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
575 Ty = TargetExtIt == TargetExtConstTypes.
end()
576 ?
MI.getOperand(1).getCImm()->getType()
577 : TargetExtIt->second;
589 GR->
add(OpCI, &MF, Reg);
590 }
else if (PrimaryReg != Reg &&
591 MRI.getType(Reg) ==
MRI.getType(PrimaryReg)) {
592 auto *RCReg =
MRI.getRegClassOrNull(Reg);
593 auto *RCPrimary =
MRI.getRegClassOrNull(PrimaryReg);
594 if (!RCReg || RCPrimary == RCReg) {
595 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
597 NeedAssignType =
false;
600 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
601 Ty =
MI.getOperand(1).getFPImm()->getType();
603 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
604 Type *ElemTy =
nullptr;
608 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
610 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
615 if (!NextMI || NextMI->
getOpcode() != SPIRV::ASSIGN_TYPE ||
620 Ty = VectorType::get(
621 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
624 NeedAssignType =
false;
628 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
639 auto It = RegsAlreadyAddedToDT.
find(
MI);
641 MRI.replaceRegWith(
MI->getOperand(0).getReg(), It->second);
642 MI->eraseFromParent();
649 switch (
MI.getOpcode()) {
650 case TargetOpcode::G_TRUNC:
651 case TargetOpcode::G_ANYEXT:
652 case TargetOpcode::G_SEXT:
653 case TargetOpcode::G_ZEXT:
654 case TargetOpcode::G_PTRTOINT:
655 case TargetOpcode::COPY:
656 case TargetOpcode::G_ADDRSPACE_CAST:
683 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands();
Idx != MISz;
688 if (
Idx == AsmDescOp && MO.
isImm()) {
691 AsmDescOp += 1 +
F.getNumOperandRegisters();
712 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
713 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
720 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
724 GR->
add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);
728 const MDNode *IAMD = I1->getOperand(1).getMetadata();
731 for (
const auto &ArgTy : FTy->params())
736 FTy, RetType, ArgTypes, MIRBuilder);
740 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);
741 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
750 addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
753 GR->
add(AsmMIB.getInstr(), &MF, AsmReg);
760 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
765 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);
771 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
775 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
776 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
779 MI->eraseFromParent();
789 MI.getOpcode() == TargetOpcode::INLINEASM)
793 if (ToProcess.
size() == 0)
796 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
798 "following SPIR-V extension: SPV_INTEL_inline_assembly",
812 MI.getOperand(2).getMetadata());
817 MI->eraseFromParent();
836 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
846 while (
MI.getNumOperands() > 0)
848 for (
auto &MO : NewOperands)
861 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
867 MI->eraseFromParent();
899 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
901 if (!
MI->getOperand(i).isReg()) {
909 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
914 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
919 auto It = BB2MBB.
find(BB);
920 if (It == BB2MBB.
end())
922 "in a switch statement");
926 ClearAddressTaken.
insert(ReferencedBlock);
927 ToEraseMI.
insert(BuildMBB);
932 while (
MI->getNumOperands() > 0)
933 MI->removeOperand(0);
934 for (
auto &MO : NewOps)
940 Next =
MI->getNextNode();
942 if (Next && Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
951 Succ->setAddressTakenIRBlock(
nullptr);
962 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
964 BlockAddrI->getOperand(1).getBlockAddress());
969 BlockAddrI->eraseFromParent();
1011 GR->setCurrentFunc(MF);
1038char SPIRVPreLegalizer::
ID = 0;
1041 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)
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)