27#include "llvm/IR/IntrinsicsSPIRV.h"
30#define DEBUG_TYPE "spirv-prelegalizer"
44void SPIRVPreLegalizerLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
52 MI->eraseFromParent();
70 MI.getOperand(3).getMetadata()->getOperand(0))
78 RegsAlreadyAddedToDT[&
MI] =
Reg;
85 BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
86 GR->
add(Const, BuildVec);
87 for (
unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
90 Constant *ElemConst = ConstVec->getElementAsConstant(i);
94 MRI.
getVRegDef(BuildVec->getOperand(1 + i).getReg()));
96 BuildVec->getOperand(1 + i).setReg(ElemReg);
99 if (Const->getType()->isTargetExtTy()) {
103 GR->
add(Const, SrcMI);
104 if (SrcMI && (SrcMI->
getOpcode() == TargetOpcode::G_CONSTANT ||
105 SrcMI->
getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
106 TargetExtConstTypes[SrcMI] = Const->getType();
107 if (Const->isNullValue()) {
111 Const->getType(), MIB, SPIRV::AccessQualifier::ReadWrite,
113 assert(SrcMI &&
"Expected source instruction to be valid");
120 RegsAlreadyAddedToDT[&
MI] =
Reg;
123 assert(
MI.getOperand(2).isReg() &&
"Reg operand is expected");
125 if (SrcMI &&
isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
133 auto It = RegsAlreadyAddedToDT.
find(
MI);
134 if (It != RegsAlreadyAddedToDT.
end())
154 const MDNode *MD =
MI.getOperand(2).getMetadata();
176 UseMI->getOperand(1).getReg() ==
Reg)
186 assert(ResType && OpType &&
"Operand types are expected");
192 if (ResType == OpType)
223 "Expected destination SPIR-V type to have been assigned already.");
226 "Expected source SPIR-V type to have been assigned already.");
227 if (DstType == SrcType) {
235 if (
MI.getOpcode() != TargetOpcode::G_BITCAST)
240 MI.getOperand(1).getReg());
267 SPIRV::Extension::SPV_INTEL_function_pointers)
268 ? SPIRV::StorageClass::CodeSectionINTEL
283 AssignedPtrType->
getOpcode() == SPIRV::OpTypeUntypedPointerKHR
286 SPIRV::AccessQualifier::ReadWrite,
324 assert(
MI &&
"Machine instr is expected");
325 if (
MI->getOperand(0).isReg()) {
329 switch (
MI->getOpcode()) {
330 case TargetOpcode::G_FCONSTANT:
331 case TargetOpcode::G_CONSTANT: {
333 Type *Ty =
MI->getOperand(1).getCImm()->getType();
335 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
338 case TargetOpcode::G_GLOBAL_VALUE: {
342 unsigned AddrSpace =
Global->getType()->getAddressSpace();
347 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
352 Ty, MIB, SPIRV::AccessQualifier::ReadWrite,
true);
355 case TargetOpcode::G_ANYEXT:
356 case TargetOpcode::G_SEXT:
357 case TargetOpcode::G_ZEXT: {
358 if (
MI->getOperand(1).isReg()) {
364 unsigned ExpectedBW =
376 case TargetOpcode::G_PTRTOINT:
380 case TargetOpcode::G_TRUNC:
381 case TargetOpcode::G_ADDRSPACE_CAST:
382 case TargetOpcode::G_PTR_ADD:
383 case TargetOpcode::COPY: {
396 if (SpvType.
isPointer() && RegType.isPointer() &&
398 RegType.getAddressSpace()) {
402 bool SkipCorrection =
403 MI->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
405 SPIRV::StorageClass::CodeSectionINTEL;
406 if (!SkipCorrection) {
418 : &SPIRV::iIDRegClass);
435 if (!RegType.isScalar())
439 if (NewWidth != CurrentWidth)
447 if (NewWidth != CurrentWidth) {
457 Def->getNextNode() ? Def->getNextNode()->getIterator() :
MBB.end();
459 while (DefIt !=
MBB.end() &&
460 (DefIt->isPHI() || DefIt->isDebugOrPseudoInstr()))
461 DefIt = std::next(DefIt);
469 assert((Ty || SpvType) &&
"Either LLVM or SPIRV type is expected.");
474 SPIRV::AccessQualifier::ReadWrite,
true);
486 for (
auto &
Op :
MI.operands()) {
487 if (!
Op.isReg() ||
Op.isDef())
491 if (!SpvType && KnownResType) {
492 SpvType = KnownResType;
515 switch (
MI.getOpcode()) {
516 case TargetOpcode::G_ASHR:
517 case TargetOpcode::G_SDIV:
518 case TargetOpcode::G_SREM:
520 case TargetOpcode::G_ICMP:
547 unsigned W = Ty.getScalarSizeInBits();
550 Info.OrigWidth.try_emplace(
Reg, W);
558 unsigned N =
MI.getNumOperands();
563 bool NeedsRewrite = RecordIfNarrow(
LHS.getReg());
564 NeedsRewrite = RecordIfNarrow(
RHS.getReg()) || NeedsRewrite;
566 Info.Worklist.push_back(&
MI);
587 auto SignExtendReg = [&](
Register Reg,
unsigned OldW,
605 unsigned N =
MI->getNumOperands();
610 if (
auto It = Info.OrigWidth.find(LHSReg); It != Info.OrigWidth.end())
611 LHS.setReg(SignExtendReg(LHSReg, It->second, *
MI));
614 if (RHSReg == LHSReg) {
618 if (
auto It = Info.OrigWidth.find(RHSReg); It != Info.OrigWidth.end())
619 RHS.setReg(SignExtendReg(RHSReg, It->second, *
MI));
635 bool IsExtendedInts =
637 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
638 ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions) ||
639 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_int4);
641 if (!IsExtendedInts) {
668 unsigned MIOp =
MI.getOpcode();
669 if (MIOp != TargetOpcode::G_TRUNC)
681 (SrcTy.isScalar() || SrcTy.isVector()) &&
682 "Expected scalar or vector G_TRUNC types");
684 "Expected matching scalar/vector G_TRUNC types");
687 "Expected equal vector element counts");
690 unsigned OriginalSrcWidth = SrcTy.getScalarSizeInBits();
699 if (OriginalDstWidth == NewDstWidth) {
716 MIB.
buildAnd(MaskedReg, SrcReg, MaskReg);
718 if (NewSrcWidth == NewDstWidth) {
723 unsigned W = It->second;
730 MI.getOperand(1).setReg(MaskedReg);
735 MI->eraseFromParent();
744 bool ReachedBegin =
false;
745 for (
auto MII = std::prev(
MBB->end()), Begin =
MBB->begin();
748 unsigned MIOp =
MI.getOpcode();
750 if (!IsExtendedInts) {
752 for (
auto &MOP :
MI.operands()) {
755 else if (MOP.isCImm())
765 if (SC == SPIRV::StorageClass::Function &&
767 ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
768 SC = SPIRV::StorageClass::CodeSectionINTEL;
773 if (ST->canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers) &&
776 ElementTy, MIB, SPIRV::AccessQualifier::ReadWrite,
790 assert(Def &&
"Expecting an instruction that defines the register");
792 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
800 assert(Def &&
"Expecting an instruction that defines the register");
802 if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
804 if (Def->getOpcode() == TargetOpcode::COPY &&
isVector1(Ty))
808 }
else if (MIOp == TargetOpcode::FAKE_USE &&
MI.getNumOperands() > 0) {
813 for (
unsigned I = 1,
E =
MI.getNumOperands();
I !=
E && Def; ++
I)
827 }
else if (MIOp == TargetOpcode::G_CONSTANT ||
828 MIOp == TargetOpcode::G_FCONSTANT ||
829 MIOp == TargetOpcode::G_BUILD_VECTOR) {
835 if (MIOp == TargetOpcode::G_CONSTANT) {
836 auto TargetExtIt = TargetExtConstTypes.
find(&
MI);
837 Ty = TargetExtIt == TargetExtConstTypes.
end()
838 ?
MI.getOperand(1).getCImm()->getType()
839 : TargetExtIt->second;
852 }
else if (PrimaryReg !=
Reg &&
856 if (!RCReg || RCPrimary == RCReg) {
857 RegsAlreadyAddedToDT[&
MI] = PrimaryReg;
859 NeedAssignType =
false;
862 }
else if (MIOp == TargetOpcode::G_FCONSTANT) {
863 Ty =
MI.getOperand(1).getFPImm()->getType();
865 assert(MIOp == TargetOpcode::G_BUILD_VECTOR);
866 Type *ElemTy =
nullptr;
870 if (ElemMI->
getOpcode() == TargetOpcode::G_CONSTANT) {
872 }
else if (ElemMI->
getOpcode() == TargetOpcode::G_FCONSTANT) {
881 ElemTy,
MI.getNumExplicitOperands() -
MI.getNumExplicitDefs(),
884 NeedAssignType =
false;
888 }
else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
899 auto It = RegsAlreadyAddedToDT.
find(
MI);
900 if (It != RegsAlreadyAddedToDT.
end())
909 switch (
MI.getOpcode()) {
910 case TargetOpcode::G_TRUNC:
911 case TargetOpcode::G_ANYEXT:
912 case TargetOpcode::G_SEXT:
913 case TargetOpcode::G_ZEXT:
914 case TargetOpcode::G_PTRTOINT:
915 case TargetOpcode::COPY:
916 case TargetOpcode::G_ADDRSPACE_CAST:
940 for (
unsigned Idx = StartOp, MISz =
MI->getNumOperands(); Idx != MISz;
945 if (Idx == AsmDescOp && MO.
isImm()) {
948 AsmDescOp += 1 +
F.getNumOperandRegisters();
968 for (
unsigned i = 0, Sz = ToProcess.
size(); i + 1 < Sz; i += 2) {
969 MachineInstr *I1 = ToProcess[i], *I2 = ToProcess[i + 1];
976 MRI.
setRegClass(AsmTargetReg, &SPIRV::iIDRegClass);
980 GR->
add(AsmTargetMIB.getInstr(), AsmTargetMIB);
984 const MDNode *IAMD = I1->getOperand(1).getMetadata();
987 for (
const auto &ArgTy : FTy->params())
989 ArgTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
true));
992 SPIRV::AccessQualifier::ReadWrite,
true);
994 FTy, RetType, ArgTypes, MIRBuilder);
999 auto AsmMIB = MIRBuilder.
buildInstr(SPIRV::OpAsmINTEL)
1011 GR->
add(AsmMIB.getInstr(), AsmMIB);
1018 .
addImm(
static_cast<uint32_t>(SPIRV::Decoration::SideEffectsINTEL));
1026 SPIRV::AccessQualifier::ReadWrite,
true);
1030 auto AsmCall = MIRBuilder.
buildInstr(SPIRV::OpAsmCallINTEL)
1034 for (
unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
1035 AsmCall.
addUse(I1->getOperand(IntrIdx).getReg());
1044 if (CopyMI.
getOpcode() == TargetOpcode::COPY) {
1048 if (TruncMI.
getOpcode() == TargetOpcode::G_TRUNC) {
1070 MI.getOpcode() == TargetOpcode::INLINEASM)
1074 if (ToProcess.
size() == 0)
1077 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly))
1079 "following SPIR-V extension: SPV_INTEL_inline_assembly",
1098 MI.getOperand(2).getMetadata(), ST);
1100 Intrinsic::spv_assign_fpmaxerror_decoration)) {
1102 MI.getOperand(2).getMetadata()->getOperand(0));
1106 SPIRV::Decoration::FPMaxErrorDecorationINTEL,
1110 MI.getOperand(2).getImm(),
1111 MI.getOperand(3).getMetadata());
1137 for (
unsigned i = 3; i <
MI.getNumOperands(); i += 2) {
1147 while (
MI.getNumOperands() > 0)
1148 MI.removeOperand(0);
1149 for (
auto &MO : NewOperands)
1163 MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
1179 BB2MBB[
MBB.getBasicBlock()] = &
MBB;
1201 for (
unsigned i = 0; i <
MI->getNumOperands(); ++i) {
1203 if (!
MI->getOperand(i).isReg()) {
1211 if (!BuildMBB || BuildMBB->
getOpcode() != TargetOpcode::G_BLOCK_ADDR) {
1216 assert(BuildMBB && BuildMBB->
getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
1221 auto It = BB2MBB.
find(BB);
1222 if (It == BB2MBB.
end())
1224 "in a switch statement");
1228 ClearAddressTaken.
insert(ReferencedBlock);
1229 ToEraseMI.
insert(BuildMBB);
1234 while (
MI->getNumOperands() > 0)
1235 MI->removeOperand(0);
1236 for (
auto &MO : NewOps)
1242 Next =
MI->getNextNode();
1244 if (
Next &&
Next->getOpcode() == TargetOpcode::G_BRINDIRECT)
1253 Succ->setAddressTakenIRBlock(
nullptr);
1264 if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
1266 BlockAddrI->getOperand(1).getBlockAddress());
1277 return MBB.getNextNode() !=
nullptr;
1281 if (!
MBB.canFallThrough())
1312 GR->setCurrentFunc(MF);
1338char SPIRVPreLegalizerLegacy::ID = 0;
1341 return new SPIRVPreLegalizerLegacy();
1344bool SPIRVPreLegalizerLegacy::runOnMachineFunction(
MachineFunction &MF) {
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 bool runPreLegalizer(MachineFunction &MF)
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 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 SignSensitiveWideningInfo recordSignSensitiveOperandWidths(MachineFunction &MF, MachineRegisterInfo &MRI)
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 SPIRVTypeInst propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, MachineIRBuilder &MIB)
static bool isSignSensitiveOp(const MachineInstr &MI)
static void invalidateAndEraseMI(SPIRVGlobalRegistry *GR, MachineInstr *MI)
static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB, DenseMap< MachineInstr *, Type * > &TargetExtConstTypes)
static void widenSignSensitiveOps(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, const SignSensitiveWideningInfo &Info)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
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
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
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)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool erase(const 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 isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr ElementCount getElementCount() const
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
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 buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildBuildVectorConstant(const DstOp &Res, ArrayRef< APInt > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ... where each OpN is built with G_CONSTANT.
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.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildSExtInReg(const DstOp &Res, const SrcOp &Op, int64_t ImmOp)
Build and insert Res = G_SEXT_INREG Op, ImmOp.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
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)
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,...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
static use_instr_iterator use_instr_end()
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void assignSPIRVTypeToVReg(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
SPIRVTypeInst getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVTypeInst RetType, const SmallVectorImpl< SPIRVTypeInst > &ArgTypes, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC, bool ForceTyped=false)
const TargetRegisterClass * getRegClass(SPIRVTypeInst SpvType) const
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
void setUntypedPtrElementType(Register Reg, SPIRVTypeInst ElemType)
SPIRVTypeInst getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
SPIRVTypeInst getOrCreateSPIRVVectorType(SPIRVTypeInst BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
unsigned getScalarOrVectorComponentCount(Register VReg) const
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
bool isBitcastCompatible(SPIRVTypeInst Type1, SPIRVTypeInst Type2) const
LLT getRegType(SPIRVTypeInst SpvType) const
void invalidateMachineInstr(MachineInstr *MI)
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
SPIRVTypeInst changePointerStorageClass(SPIRVTypeInst PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Type * getDeducedGlobalValueType(const GlobalValue *Global)
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
SPIRVTypeInst getUntypedPtrElementType(Register Reg) const
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI)
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
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.
Pass manager infrastructure for declaring and invalidating analyses.
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.
StringMapEntry< Value * > ValueName
void addStringImm(StringRef Str, MCInst &Inst)
bool isTypeFoldingSupported(unsigned Opcode)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
void updateRegType(Register Reg, Type *Ty, SPIRVTypeInst SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Helper external function for assigning a SPIRV type to a register, ensuring the register class and ty...
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
Type * toTypedPointer(Type *Ty)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
auto post_order(const T &G)
Post-order traversal of a graph.
MachineInstr * passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ 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)
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR, SPIRVTypeInst KnownResType)
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
FunctionPass * createSPIRVPreLegalizerLegacyPass()
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
SmallVector< MachineInstr * > Worklist
DenseMap< Register, unsigned > OrigWidth