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();
208 MI->eraseFromParent();
229 assert(
MI &&
"Machine instr is expected");
230 if (
MI->getOperand(0).isReg()) {
234 switch (
MI->getOpcode()) {
235 case TargetOpcode::G_CONSTANT: {
237 Type *Ty =
MI->getOperand(1).getCImm()->getType();
241 case TargetOpcode::G_GLOBAL_VALUE: {
246 Global->getType()->getAddressSpace());
250 case TargetOpcode::G_ANYEXT:
251 case TargetOpcode::G_SEXT:
252 case TargetOpcode::G_ZEXT: {
253 if (
MI->getOperand(1).isReg()) {
255 MRI.getVRegDef(
MI->getOperand(1).getReg())) {
258 unsigned ExpectedBW =
259 std::max(
MRI.getType(Reg).getScalarSizeInBits(), CurrentBW);
270 case TargetOpcode::G_PTRTOINT:
272 MRI.getType(Reg).getScalarSizeInBits(), MIB);
274 case TargetOpcode::G_TRUNC:
275 case TargetOpcode::G_ADDRSPACE_CAST:
276 case TargetOpcode::G_PTR_ADD:
277 case TargetOpcode::COPY: {
289 if (!
MRI.getRegClassOrNull(Reg))
290 MRI.setRegClass(Reg, &SPIRV::iIDRegClass);
300 LLT RegType =
MRI.getType(Reg);
306 unsigned NewSz = std::min(std::max(1u <<
Log2_32_Ceil(Sz), 8u), 64u);
312 bool IsFloat = SpvType->
getOpcode() == SPIRV::OpTypeFloat;
313 return IsFloat ?
true
314 : SpvType->
getOpcode() == SPIRV::OpTypeVector &&
323 case SPIRV::OpTypeFloat:
324 return &SPIRV::fIDRegClass;
325 case SPIRV::OpTypePointer:
327 : &SPIRV::pID32RegClass;
328 case SPIRV::OpTypeVector: {
331 unsigned ElemOpcode = ElemType ? ElemType->
getOpcode() : 0;
332 if (ElemOpcode == SPIRV::OpTypeFloat)
333 return &SPIRV::vfIDRegClass;
334 if (ElemOpcode == SPIRV::OpTypePointer)
336 : &SPIRV::vpID32RegClass;
337 return &SPIRV::vIDRegClass;
340 return &SPIRV::iIDRegClass;
343static std::pair<Register, unsigned>
348 assert(SpvType &&
"VReg is expected to have SPIRV type");
350 LLT SrcLLT =
MRI.getType(SrcReg);
352 auto GetIdOp = IsFloat ? SPIRV::GET_fID : SPIRV::GET_ID;
360 GetIdOp = IsVec ? SPIRV::GET_vpID64 : SPIRV::GET_pID64;
362 GetIdOp = IsVec ? SPIRV::GET_vpID32 : SPIRV::GET_pID32;
366 GetIdOp = IsFloat ? SPIRV::GET_vfID : SPIRV::GET_vID;
370 Register IdReg =
MRI.createGenericVirtualRegister(NewT);
372 return {IdReg, GetIdOp};
385 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
387 (Def->getNextNode() ? Def->getNextNode()->getIterator()
388 : Def->getParent()->end()));
390 Register NewReg =
MRI.createGenericVirtualRegister(
MRI.getType(Reg));
391 if (
auto *RC =
MRI.getRegClassOrNull(Reg)) {
392 MRI.setRegClass(NewReg, RC);
395 MRI.setRegClass(NewReg, RegClass);
396 MRI.setRegClass(Reg, RegClass);
404 const uint32_t Flags = Def->getFlags();
410 Def->getOperand(0).setReg(NewReg);
416 assert(
MI.getNumDefs() > 0 &&
MRI.hasOneUse(
MI.getOperand(0).getReg()));
418 *(
MRI.use_instr_begin(
MI.getOperand(0).getReg()));
422 MI.getOperand(0).setReg(NewReg);
424 (
MI.getNextNode() ?
MI.getNextNode()->getIterator()
425 :
MI.getParent()->end()));
426 for (
auto &
Op :
MI.operands()) {
427 if (!
Op.isReg() ||
Op.isDef())
431 Op.setReg(IdOpInfo.first);
452 bool ReachedBegin =
false;
456 unsigned MIOp =
MI.getOpcode();
459 for (
const auto &MOP :
MI.operands())
472 assert(Def &&
"Expecting an instruction that defines the register");
474 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
475 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
483 assert(Def &&
"Expecting an instruction that defines the register");
485 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
486 Def->getOpcode() != SPIRV::ASSIGN_TYPE)
489 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
490 MIOp == TargetOpcode::G_FCONSTANT ||
491 MIOp == TargetOpcode::G_BUILD_VECTOR) {
498 bool NeedAssignType =
true;
499 if (
MRI.hasOneUse(Reg)) {
506 if (MIOp == TargetOpcode::G_CONSTANT) {
507 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
508 Ty = TargetExtIt == TargetExtConstTypes.
end()
509 ?
MI.getOperand(1).getCImm()->getType()
510 : TargetExtIt->second;
514 GR->
add(OpCI, &MF, Reg);
515 }
else if (PrimaryReg != Reg &&
516 MRI.getType(Reg) ==
MRI.getType(PrimaryReg)) {
517 auto *RCReg =
MRI.getRegClassOrNull(Reg);
518 auto *RCPrimary =
MRI.getRegClassOrNull(PrimaryReg);
519 if (!RCReg || RCPrimary == RCReg) {
520 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
522 NeedAssignType =
false;
525 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
526 Ty =
MI.getOperand(1).getFPImm()->getType();
528 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
529 Type *ElemTy =
nullptr;
533 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
535 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
540 if (!NextMI || NextMI->
getOpcode() != SPIRV::ASSIGN_TYPE ||
545 Ty = VectorType::get(
546 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
549 NeedAssignType =
false;
553 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
564 auto It = RegsAlreadyAddedToDT.
find(
MI);
566 MRI.replaceRegWith(
MI->getOperand(0).getReg(), It->second);
567 MI->eraseFromParent();
574 switch (
MI.getOpcode()) {
575 case TargetOpcode::G_TRUNC:
576 case TargetOpcode::G_ANYEXT:
577 case TargetOpcode::G_SEXT:
578 case TargetOpcode::G_ZEXT:
579 case TargetOpcode::G_PTRTOINT:
580 case TargetOpcode::COPY:
581 case TargetOpcode::G_ADDRSPACE_CAST:
608 if (
MI.getOpcode() != SPIRV::ASSIGN_TYPE)
611 unsigned Opcode =
MRI.getVRegDef(SrcReg)->getOpcode();
617 if (Opcode == TargetOpcode::G_CONSTANT &&
MRI.hasOneUse(DstReg)) {
619 if (
UseMI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST)
622 if (
MRI.getType(DstReg).isPointer())
634 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
635 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
642 MRI.setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
646 GR->
add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);
650 const MDNode *IAMD = I1->getOperand(1).getMetadata();
653 for (
const auto &ArgTy : FTy->params())
658 FTy, RetType, ArgTypes, MIRBuilder);
662 MRI.setRegClass(AsmReg, &SPIRV::iIDRegClass);
663 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
672 addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
675 GR->
add(AsmMIB.getInstr(), &MF, AsmReg);
682 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
687 unsigned I2Sz = I2->getNumOperands();
688 for (
unsigned Idx = StartOp;
Idx != I2Sz; ++
Idx) {
692 if (
Idx == AsmDescOp && MO.
isImm()) {
695 AsmDescOp += 1 +
F.getNumOperandRegisters();
705 MRI.setRegClass(DefReg, &SPIRV::iIDRegClass);
710 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
714 unsigned IntrIdx = 2;
715 for (
unsigned Idx : Ops) {
719 AsmCall.addUse(MO.
getReg());
721 AsmCall.addUse(I1->getOperand(IntrIdx).getReg());
725 MI->eraseFromParent();
735 MI.getOpcode() == TargetOpcode::INLINEASM)
739 if (ToProcess.
size() == 0)
742 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
744 "following SPIR-V extension: SPV_INTEL_inline_assembly",
758 MI.getOperand(2).getMetadata());
763 MI->eraseFromParent();
781 for (
unsigned i = 2; i <
MI.getNumOperands(); ++i) {
789 BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
800 for (
auto &SwIt : Switches) {
804 for (
unsigned i = 0; i < Ins.size(); ++i) {
805 if (Ins[i]->
getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
807 Ins[i]->getOperand(1).getBlockAddress()->getBasicBlock();
808 auto It = BB2MBB.
find(CaseBB);
809 if (It == BB2MBB.
end())
811 "block in a switch statement");
813 MI.getParent()->addSuccessor(It->second);
820 for (
unsigned i =
MI.getNumOperands() - 1; i > 1; --i)
822 for (
auto &MO : NewOps)
827 Next =
MI.getNextNode();
829 if (Next && Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
843 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
845 BlockAddrI->getOperand(1).getBlockAddress());
850 BlockAddrI->eraseFromParent();
892 GR->setCurrentFunc(MF);
914char SPIRVPreLegalizer::
ID = 0;
917 return new SPIRVPreLegalizer();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
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 void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder)
bool getIsFloat(SPIRVType *SpvType, const SPIRVGlobalRegistry &GR)
static void insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR, const SPIRVSubtarget &ST, MachineIRBuilder MIRBuilder, const SmallVector< MachineInstr * > &ToProcess)
static const TargetRegisterClass * getRegClass(SPIRVType *SpvType, const SPIRVGlobalRegistry &GR)
static void removeImplicitFallthroughs(MachineFunction &MF, MachineIRBuilder MIB)
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 SPIRVType * propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, MachineIRBuilder &MIB)
static MachineInstr * findAssignTypeInstr(Register Reg, MachineRegisterInfo *MRI)
static void processSwitches(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)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
LLVM Basic Block Representation.
The address of a basic block.
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 isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
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.
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,...
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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 add(const Constant *C, MachineFunction *MF, Register R)
unsigned getScalarOrVectorComponentCount(Register VReg) const
unsigned getPointerSize() const
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, MachineFunction &MF)
SPIRVType * getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVType *RetType, const SmallVectorImpl< SPIRVType * > &ArgTypes, MachineIRBuilder &MIRBuilder)
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)
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.
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)
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)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)