77#define DEBUG_TYPE "si-fix-sgpr-copies"
80 "amdgpu-enable-merge-m0",
81 cl::desc(
"Merge and hoist M0 initializations"),
99 unsigned NumReadfirstlanes;
101 bool NeedToBeConvertedToVALU =
false;
107 unsigned SiblingPenalty = 0;
109 V2SCopyInfo() : Copy(nullptr),
ID(0){};
111 :
Copy(
C), NumSVCopies(0), NumReadfirstlanes(Width / 32),
ID(
Id){};
112#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
115 <<
"\n\tSV:" << NumSVCopies <<
"\n\tSP: " << SiblingPenalty
116 <<
"\nScore: " << Score <<
"\n";
127 unsigned NextVGPRToSGPRCopyID;
143 unsigned getNextVGPRToSGPRCopyId() {
return ++NextVGPRToSGPRCopyID; }
144 bool needToBeConvertedToVALU(V2SCopyInfo *
I);
175 "SI Fix SGPR copies",
false,
false)
180char SIFixSGPRCopies::
ID = 0;
185 return new SIFixSGPRCopies();
188static std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
192 Register DstReg = Copy.getOperand(0).getReg();
193 Register SrcReg = Copy.getOperand(1).getReg();
196 ?
MRI.getRegClass(SrcReg)
197 :
TRI.getPhysRegBaseClass(SrcReg);
203 ?
MRI.getRegClass(DstReg)
204 :
TRI.getPhysRegBaseClass(DstReg);
206 return std::pair(SrcRC, DstRC);
212 return SrcRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(DstRC) &&
213 TRI.hasVectorRegisters(SrcRC);
219 return DstRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(SrcRC) &&
220 TRI.hasVectorRegisters(DstRC);
227 auto &Src =
MI.getOperand(1);
233 for (
const auto &MO :
MRI.reg_nodbg_operands(DstReg)) {
234 const auto *
UseMI = MO.getParent();
241 unsigned OpIdx = MO.getOperandNo();
243 !
TII->isOperandLegal(*
UseMI, OpIdx, &Src))
247 MRI.setRegClass(DstReg,
TRI->getEquivalentSGPRClass(
MRI.getRegClass(DstReg)));
271 if (!
TRI->isSGPRClass(
MRI.getRegClass(DstReg)))
274 if (!
MRI.hasOneUse(DstReg))
296 if (
SubReg != AMDGPU::NoSubRegister)
299 MRI.setRegClass(DstReg, DstRC);
310 bool IsAGPR =
TRI->isAGPRClass(DstRC);
312 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
314 TRI->getRegClassForOperandReg(
MRI,
MI.getOperand(
I));
316 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
319 Register TmpReg =
MRI.createVirtualRegister(NewSrcRC);
327 Register TmpAReg =
MRI.createVirtualRegister(NewSrcRC);
328 unsigned Opc = NewSrcRC == &AMDGPU::AGPR_32RegClass ?
329 AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::COPY;
336 MI.getOperand(
I).setReg(TmpReg);
348 if (Copy->getOpcode() != AMDGPU::COPY)
351 if (!MoveImm->isMoveImmediate())
355 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
360 if (Copy->getOperand(1).getSubReg())
363 switch (MoveImm->getOpcode()) {
366 case AMDGPU::V_MOV_B32_e32:
367 SMovOp = AMDGPU::S_MOV_B32;
369 case AMDGPU::V_MOV_B64_PSEUDO:
370 SMovOp = AMDGPU::S_MOV_B64_IMM_PSEUDO;
377template <
class UnaryPredicate>
380 UnaryPredicate Predicate) {
387 while (!Worklist.
empty()) {
427 while (
I !=
MBB->
end() &&
TII->isBasicBlockPrologue(*
I))
443 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
450 bool Changed =
false;
452 for (
auto &
MI :
MRI.def_instructions(Reg)) {
454 for (
auto &MO :
MI.operands()) {
455 if ((MO.isReg() && ((MO.isDef() && MO.getReg() != Reg) || !MO.isDef())) ||
456 (!MO.isImm() && !MO.isReg()) || (MO.isImm() && Imm)) {
459 }
else if (MO.isImm())
463 Inits[Imm->getImm()].push_front(&
MI);
468 for (
auto &
Init : Inits) {
469 auto &Defs =
Init.second;
471 for (
auto I1 = Defs.begin(), E = Defs.end(); I1 != E; ) {
474 for (
auto I2 = std::next(I1); I2 != E; ) {
487 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
488 if (!MayClobberFrom && !MayClobberTo)
490 if ((MayClobberFrom && !MayClobberTo) ||
491 (!MayClobberFrom && MayClobberTo))
497 return !((MBBFrom == MBBTo &&
505 return C.first !=
Init.first &&
511 if (!interferes(MI2, MI1)) {
521 if (!interferes(MI1, MI2)) {
539 if (!interferes(MI1,
I) && !interferes(MI2,
I)) {
543 <<
"and moving from "
560 for (
auto &
Init : Inits) {
561 auto &Defs =
Init.second;
562 auto I = Defs.begin();
563 while (
I != Defs.end()) {
564 if (MergedInstrs.
count(*
I)) {
565 (*I)->eraseFromParent();
573 for (
auto &
Init : Inits) {
574 auto &Defs =
Init.second;
575 for (
auto *
MI : Defs) {
576 auto MBB =
MI->getParent();
581 if (!
TII->isBasicBlockPrologue(*
B))
584 auto R = std::next(
MI->getReverseIterator());
585 const unsigned Threshold = 50;
587 for (
unsigned I = 0; R !=
B &&
I < Threshold; ++R, ++
I)
588 if (R->readsRegister(Reg,
TRI) || R->definesRegister(Reg,
TRI) ||
599 MRI.clearKillFlags(Reg);
607 MachineFunctionProperties::Property::Selected))
612 TRI =
ST.getRegisterInfo();
613 TII =
ST.getInstrInfo();
614 MDT = &getAnalysis<MachineDominatorTree>();
624 switch (
MI.getOpcode()) {
629 case AMDGPU::STRICT_WQM:
630 case AMDGPU::SOFT_WQM:
631 case AMDGPU::STRICT_WWM: {
644 S2VCopies.push_back(&
MI);
648 if (lowerSpecialCase(
MI,
I))
651 analyzeVGPRToSGPRCopy(&
MI);
655 case AMDGPU::INSERT_SUBREG:
657 case AMDGPU::REG_SEQUENCE: {
658 if (
TRI->isSGPRClass(
TII->getOpRegClass(
MI, 0))) {
660 if (!MO.isReg() || !MO.getReg().isVirtual())
663 if (
TRI->hasVectorRegisters(SrcRC)) {
665 TRI->getEquivalentSGPRClass(SrcRC);
666 Register NewDst =
MRI->createVirtualRegister(DestRC);
668 MI.isPHI() ?
MI.getOperand(MO.getOperandNo() + 1).getMBB()
673 if (!tryMoveVGPRConstToSGPR(MO, NewDst, BlockToInsertCopy,
674 PointToInsertCopy)) {
676 BuildMI(*BlockToInsertCopy, PointToInsertCopy,
677 PointToInsertCopy->getDebugLoc(),
678 TII->get(AMDGPU::COPY), NewDst)
681 analyzeVGPRToSGPRCopy(NewCopy);
688 PHINodes.push_back(&
MI);
689 else if (
MI.isRegSequence())
690 RegSequences.push_back(&
MI);
694 case AMDGPU::V_WRITELANE_B32: {
697 if (
ST.getConstantBusLimit(
MI.getOpcode()) != 1)
715 Src0.
getReg() != AMDGPU::M0) &&
717 Src1.
getReg() != AMDGPU::M0)) {
725 if (MO->getReg().isVirtual()) {
730 MO->getReg() ==
Def.getReg() &&
731 MO->getSubReg() ==
Def.getSubReg()) {
733 if (Copied.
isImm() &&
748 TII->get(AMDGPU::COPY), AMDGPU::M0)
759 lowerVGPR2SGPRCopies(MF);
762 for (
auto MI : S2VCopies) {
771 for (
auto MI : RegSequences) {
773 if (
MI->isRegSequence())
776 for (
auto MI : PHINodes) {
782 SiblingPenalty.clear();
785 RegSequences.clear();
793 bool AllAGPRUses =
true;
800 bool HasUses =
false;
801 while (!worklist.
empty()) {
804 for (
const auto &
Use :
MRI->use_operands(Reg)) {
821 if (HasUses && AllAGPRUses && !
TRI->isAGPRClass(RC0)) {
823 MRI->setRegClass(PHIRes,
TRI->getEquivalentAGPRClass(RC0));
824 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
831 if (
TRI->isVectorRegister(*
MRI, PHIRes) ||
832 RC0 == &AMDGPU::VReg_1RegClass) {
834 TII->legalizeOperands(
MI, MDT);
838 while (!PHIOperands.
empty()) {
843bool SIFixSGPRCopies::tryMoveVGPRConstToSGPR(
853 if (SrcConst->
isReg())
857 MRI->getRegClass(MaybeVGPRConstMO.
getReg());
858 unsigned MoveSize =
TRI->getRegSizeInBits(*SrcRC);
859 unsigned MoveOp = MoveSize == 64 ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
860 BuildMI(*BlockToInsertTo, PointToInsertTo, PointToInsertTo->getDebugLoc(),
861 TII->get(MoveOp), DstReg)
863 if (
MRI->hasOneUse(MaybeVGPRConstMO.
getReg()))
865 MaybeVGPRConstMO.
setReg(DstReg);
878 if (DstReg == AMDGPU::M0 &&
879 TRI->hasVectorRegisters(
MRI->getRegClass(SrcReg))) {
881 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
883 TII->get(AMDGPU::V_READFIRSTLANE_B32), TmpReg)
884 .
add(
MI.getOperand(1));
885 MI.getOperand(1).setReg(TmpReg);
886 }
else if (tryMoveVGPRConstToSGPR(
MI.getOperand(1), DstReg,
MI.getParent(),
889 MI.eraseFromParent();
896 TII->moveToVALU(worklist, MDT);
905 MI.getOperand(1).ChangeToImmediate(Imm);
906 MI.addImplicitDefUseOperands(*
MI.getParent()->getParent());
907 MI.setDesc(
TII->get(SMovOp));
917 V2SCopyInfo
Info(getNextVGPRToSGPRCopyId(),
MI,
918 TRI->getRegSizeInBits(*DstRC));
924 while (!AnalysisWorklist.
empty()) {
928 if (!Visited.
insert(Inst).second)
943 SiblingPenalty[Inst].insert(
Info.ID);
951 !
I->findRegisterDefOperand(AMDGPU::SCC,
nullptr)) {
952 if (
I->readsRegister(AMDGPU::SCC,
nullptr))
957 if (
TRI->isSGPRReg(*
MRI, Reg) && !
TII->isVALU(*Inst))
958 for (
auto &U :
MRI->use_instructions(Reg))
961 for (
auto U :
Users) {
963 Info.SChain.insert(U);
972bool SIFixSGPRCopies::needToBeConvertedToVALU(V2SCopyInfo *Info) {
973 if (
Info->SChain.empty()) {
979 return SiblingPenalty[A].size() < SiblingPenalty[B].size();
981 Info->Siblings.remove_if([&](
unsigned ID) {
return ID ==
Info->ID; });
988 for (
auto J :
Info->Siblings) {
989 auto InfoIt = V2SCopies.find(J);
990 if (InfoIt != V2SCopies.end()) {
1000 Info->SiblingPenalty = SrcRegs.
size();
1003 Info->NumSVCopies +
Info->SiblingPenalty +
Info->NumReadfirstlanes;
1004 unsigned Profit =
Info->SChain.size();
1005 Info->Score = Penalty > Profit ? 0 : Profit - Penalty;
1006 Info->NeedToBeConvertedToVALU =
Info->Score < 3;
1007 return Info->NeedToBeConvertedToVALU;
1013 for (
auto &
C : V2SCopies) {
1014 if (needToBeConvertedToVALU(&
C.second))
1022 while (!LoweringWorklist.
empty()) {
1024 auto CurInfoIt = V2SCopies.find(CurID);
1025 if (CurInfoIt != V2SCopies.end()) {
1026 V2SCopyInfo
C = CurInfoIt->second;
1028 for (
auto S :
C.Siblings) {
1029 auto SibInfoIt = V2SCopies.find(S);
1030 if (SibInfoIt != V2SCopies.end()) {
1031 V2SCopyInfo &
SI = SibInfoIt->second;
1033 if (!
SI.NeedToBeConvertedToVALU) {
1034 SI.SChain.set_subtract(
C.SChain);
1035 if (needToBeConvertedToVALU(&SI))
1038 SI.Siblings.remove_if([&](
unsigned ID) {
return ID ==
C.ID; });
1042 <<
" is being turned to VALU\n");
1045 V2SCopies.erase(
C.ID);
1054 for (
auto C : V2SCopies) {
1060 <<
" is being turned to v_readfirstlane_b32"
1061 <<
" Score: " <<
C.second.Score <<
"\n");
1062 Register DstReg =
MI->getOperand(0).getReg();
1063 Register SrcReg =
MI->getOperand(1).getReg();
1064 unsigned SubReg =
MI->getOperand(1).getSubReg();
1066 TRI->getRegClassForOperandReg(*
MRI,
MI->getOperand(1));
1067 size_t SrcSize =
TRI->getRegSizeInBits(*SrcRC);
1068 if (SrcSize == 16) {
1071 TII->get(AMDGPU::V_READFIRSTLANE_B32), DstReg);
1072 MIB.addReg(SrcReg, 0, AMDGPU::NoSubRegister);
1073 }
else if (SrcSize == 32) {
1075 TII->get(AMDGPU::V_READFIRSTLANE_B32), DstReg);
1076 MIB.addReg(SrcReg, 0,
SubReg);
1079 TII->get(AMDGPU::REG_SEQUENCE), DstReg);
1080 int N =
TRI->getRegSizeInBits(*SrcRC) / 32;
1081 for (
int i = 0; i <
N; i++) {
1083 Result, *
MRI,
MI->getOperand(1), SrcRC,
1084 TRI->getSubRegFromChannel(i), &AMDGPU::VGPR_32RegClass);
1086 MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
1088 TII->get(AMDGPU::V_READFIRSTLANE_B32), PartialDst)
1090 Result.addReg(PartialDst).addImm(
TRI->getSubRegFromChannel(i));
1093 MI->eraseFromParent();
1110 if (SrcReg == AMDGPU::SCC) {
1112 TRI->getRegClass(AMDGPU::SReg_1_XEXECRegClassID));
1115 TII->get(IsWave32 ? AMDGPU::S_CSELECT_B32
1116 : AMDGPU::S_CSELECT_B64),
1120 I =
BuildMI(*
MI.getParent(), std::next(
I),
I->getDebugLoc(),
1121 TII->get(AMDGPU::COPY), DstReg)
1123 MI.eraseFromParent();
1126 if (DstReg == AMDGPU::SCC) {
1127 unsigned Opcode = IsWave32 ? AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64;
1128 Register Exec = IsWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
1131 MI.getDebugLoc(),
TII->get(Opcode))
1135 MI.eraseFromParent();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Provides AMDGPU specific target descriptions.
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
iv Induction Variable Users
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static std::pair< const TargetRegisterClass *, const TargetRegisterClass * > getCopyRegClasses(const MachineInstr &Copy, const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI)
static cl::opt< bool > EnableM0Merge("amdgpu-enable-merge-m0", cl::desc("Merge and hoist M0 initializations"), cl::init(true))
static bool hoistAndMergeSGPRInits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo *TRI, MachineDominatorTree &MDT, const TargetInstrInfo *TII)
static bool foldVGPRCopyIntoRegSequence(MachineInstr &MI, const SIRegisterInfo *TRI, const SIInstrInfo *TII, MachineRegisterInfo &MRI)
bool searchPredecessors(const MachineBasicBlock *MBB, const MachineBasicBlock *CutOff, UnaryPredicate Predicate)
static bool isReachable(const MachineInstr *From, const MachineInstr *To, const MachineBasicBlock *CutOff, MachineDominatorTree &MDT)
static bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC, const TargetRegisterClass *DstRC, const SIRegisterInfo &TRI)
static bool tryChangeVGPRtoSGPRinCopy(MachineInstr &MI, const SIRegisterInfo *TRI, const SIInstrInfo *TII)
static bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC, const TargetRegisterClass *DstRC, const SIRegisterInfo &TRI)
static bool isSafeToFoldImmIntoCopy(const MachineInstr *Copy, const MachineInstr *MoveImm, const SIInstrInfo *TII, unsigned &SMovOp, int64_t &Imm)
static MachineBasicBlock::iterator getFirstNonPrologue(MachineBasicBlock *MBB, const TargetInstrInfo *TII)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines generic set operations that may be used on set's of different types,...
Class for arbitrary precision integers.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
Test if the given instruction should be considered a scheduling boundary.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
pred_iterator pred_begin()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool hasProperty(Property P) const
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool isRegSequence() const
unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(const ValueT &V)
self_iterator getIterator()
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
@ Resolved
Queried, materialization begun.
NodeAddr< InstrNode * > Instr
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getDefRegState(bool B)
auto max_element(R &&Range)
FunctionPass * createSIFixSGPRCopiesPass()
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Utility to store machine instructions worklist.
void insert(MachineInstr *MI)