77#define DEBUG_TYPE "si-fix-sgpr-copies"
80 "amdgpu-enable-merge-m0",
81 cl::desc(
"Merge and hoist M0 initializations"),
94 unsigned NumSVCopies = 0;
99 unsigned NumReadfirstlanes = 0;
101 bool NeedToBeConvertedToVALU =
false;
107 unsigned SiblingPenalty = 0;
109 V2SCopyInfo() : Copy(nullptr),
ID(0){};
111 :
Copy(
C), NumReadfirstlanes(Width / 32),
ID(
Id){};
112#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
115 <<
"\n\tSV:" << NumSVCopies <<
"\n\tSP: " << SiblingPenalty
116 <<
"\nScore: " << Score <<
"\n";
121class SIFixSGPRCopies {
127 unsigned NextVGPRToSGPRCopyID = 0;
141 unsigned getNextVGPRToSGPRCopyId() {
return ++NextVGPRToSGPRCopyID; }
142 bool needToBeConvertedToVALU(V2SCopyInfo *
I);
169 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
170 SIFixSGPRCopies Impl(MDT);
192char SIFixSGPRCopiesLegacy::
ID = 0;
197 return new SIFixSGPRCopiesLegacy();
200static std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
204 Register DstReg = Copy.getOperand(0).getReg();
205 Register SrcReg = Copy.getOperand(1).getReg();
208 ?
MRI.getRegClass(SrcReg)
209 :
TRI.getPhysRegBaseClass(SrcReg);
215 ?
MRI.getRegClass(DstReg)
216 :
TRI.getPhysRegBaseClass(DstReg);
218 return std::pair(SrcRC, DstRC);
224 return SrcRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(DstRC) &&
225 TRI.hasVectorRegisters(SrcRC);
231 return DstRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(SrcRC) &&
232 TRI.hasVectorRegisters(DstRC);
239 auto &Src =
MI.getOperand(1);
245 for (
const auto &MO :
MRI.reg_nodbg_operands(DstReg)) {
246 const auto *
UseMI = MO.getParent();
253 unsigned OpIdx = MO.getOperandNo();
255 !
TII->isOperandLegal(*
UseMI, OpIdx, &Src))
259 MRI.setRegClass(DstReg,
TRI->getEquivalentSGPRClass(
MRI.getRegClass(DstReg)));
283 if (!
TRI->isSGPRClass(
MRI.getRegClass(DstReg)))
286 if (!
MRI.hasOneUse(DstReg))
308 if (
SubReg != AMDGPU::NoSubRegister)
311 MRI.setRegClass(DstReg, DstRC);
322 bool IsAGPR =
TRI->isAGPRClass(DstRC);
324 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
326 TRI->getRegClassForOperandReg(
MRI,
MI.getOperand(
I));
328 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
331 Register TmpReg =
MRI.createVirtualRegister(NewSrcRC);
339 Register TmpAReg =
MRI.createVirtualRegister(NewSrcRC);
340 unsigned Opc = NewSrcRC == &AMDGPU::AGPR_32RegClass ?
341 AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::COPY;
348 MI.getOperand(
I).setReg(TmpReg);
360 if (Copy->getOpcode() != AMDGPU::COPY)
363 if (!MoveImm->isMoveImmediate())
367 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
372 if (Copy->getOperand(1).getSubReg())
375 switch (MoveImm->getOpcode()) {
378 case AMDGPU::V_MOV_B32_e32:
379 SMovOp = AMDGPU::S_MOV_B32;
381 case AMDGPU::V_MOV_B64_PSEUDO:
382 SMovOp = AMDGPU::S_MOV_B64_IMM_PSEUDO;
389template <
class UnaryPredicate>
392 UnaryPredicate Predicate) {
399 while (!Worklist.
empty()) {
439 while (
I !=
MBB->
end() &&
TII->isBasicBlockPrologue(*
I))
455 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
462 bool Changed =
false;
464 for (
auto &
MI :
MRI.def_instructions(Reg)) {
466 for (
auto &MO :
MI.operands()) {
467 if ((MO.isReg() && ((MO.isDef() && MO.getReg() != Reg) || !MO.isDef())) ||
468 (!MO.isImm() && !MO.isReg()) || (MO.isImm() && Imm)) {
476 Inits[Imm->getImm()].push_front(&
MI);
481 for (
auto &
Init : Inits) {
482 auto &Defs =
Init.second;
484 for (
auto I1 = Defs.begin(), E = Defs.end(); I1 != E; ) {
487 for (
auto I2 = std::next(I1); I2 != E; ) {
500 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
501 if (!MayClobberFrom && !MayClobberTo)
503 if ((MayClobberFrom && !MayClobberTo) ||
504 (!MayClobberFrom && MayClobberTo))
510 return !((MBBFrom == MBBTo &&
518 return C.first !=
Init.first &&
524 if (!interferes(MI2, MI1)) {
534 if (!interferes(MI1, MI2)) {
552 if (!interferes(MI1,
I) && !interferes(MI2,
I)) {
556 <<
"and moving from "
573 for (
auto &
Init : Inits) {
574 auto &Defs =
Init.second;
575 auto I = Defs.begin();
576 while (
I != Defs.end()) {
577 if (MergedInstrs.
count(*
I)) {
578 (*I)->eraseFromParent();
586 for (
auto &
Init : Inits) {
587 auto &Defs =
Init.second;
588 for (
auto *
MI : Defs) {
589 auto *
MBB =
MI->getParent();
594 if (!
TII->isBasicBlockPrologue(*
B))
597 auto R = std::next(
MI->getReverseIterator());
598 const unsigned Threshold = 50;
600 for (
unsigned I = 0; R !=
B &&
I < Threshold; ++R, ++
I)
601 if (R->readsRegister(Reg,
TRI) || R->definesRegister(Reg,
TRI) ||
612 MRI.clearKillFlags(Reg);
620 MachineFunctionProperties::Property::Selected))
625 TRI =
ST.getRegisterInfo();
626 TII =
ST.getInstrInfo();
633 switch (
MI.getOpcode()) {
638 case AMDGPU::STRICT_WQM:
639 case AMDGPU::SOFT_WQM:
640 case AMDGPU::STRICT_WWM: {
653 S2VCopies.push_back(&
MI);
657 if (lowerSpecialCase(
MI,
I))
660 analyzeVGPRToSGPRCopy(&
MI);
664 case AMDGPU::INSERT_SUBREG:
666 case AMDGPU::REG_SEQUENCE: {
667 if (
TRI->isSGPRClass(
TII->getOpRegClass(
MI, 0))) {
669 if (!MO.isReg() || !MO.getReg().isVirtual())
672 if (
TRI->hasVectorRegisters(SrcRC)) {
674 TRI->getEquivalentSGPRClass(SrcRC);
675 Register NewDst =
MRI->createVirtualRegister(DestRC);
677 MI.isPHI() ?
MI.getOperand(MO.getOperandNo() + 1).getMBB()
682 if (!tryMoveVGPRConstToSGPR(MO, NewDst, BlockToInsertCopy,
683 PointToInsertCopy)) {
685 BuildMI(*BlockToInsertCopy, PointToInsertCopy,
686 PointToInsertCopy->getDebugLoc(),
687 TII->get(AMDGPU::COPY), NewDst)
690 analyzeVGPRToSGPRCopy(NewCopy);
697 PHINodes.push_back(&
MI);
698 else if (
MI.isRegSequence())
699 RegSequences.push_back(&
MI);
703 case AMDGPU::V_WRITELANE_B32: {
706 if (
ST.getConstantBusLimit(
MI.getOpcode()) != 1)
724 Src0.
getReg() != AMDGPU::M0) &&
726 Src1.
getReg() != AMDGPU::M0)) {
734 if (MO->getReg().isVirtual()) {
739 MO->getReg() ==
Def.getReg() &&
740 MO->getSubReg() ==
Def.getSubReg()) {
742 if (Copied.
isImm() &&
757 TII->get(AMDGPU::COPY), AMDGPU::M0)
768 lowerVGPR2SGPRCopies(MF);
771 for (
auto *
MI : S2VCopies) {
780 for (
auto *
MI : RegSequences) {
782 if (
MI->isRegSequence())
785 for (
auto *
MI : PHINodes) {
788 if (MF.getTarget().getOptLevel() > CodeGenOptLevel::None &&
EnableM0Merge)
791 SiblingPenalty.clear();
794 RegSequences.clear();
802 bool AllAGPRUses =
true;
809 bool HasUses =
false;
810 while (!worklist.
empty()) {
813 for (
const auto &
Use :
MRI->use_operands(Reg)) {
830 if (HasUses && AllAGPRUses && !
TRI->isAGPRClass(RC0)) {
832 MRI->setRegClass(PHIRes,
TRI->getEquivalentAGPRClass(RC0));
833 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
840 if (
TRI->isVectorRegister(*
MRI, PHIRes) ||
841 RC0 == &AMDGPU::VReg_1RegClass) {
843 TII->legalizeOperands(
MI, MDT);
847 while (!PHIOperands.
empty()) {
852bool SIFixSGPRCopies::tryMoveVGPRConstToSGPR(
862 if (SrcConst->
isReg())
866 MRI->getRegClass(MaybeVGPRConstMO.
getReg());
867 unsigned MoveSize =
TRI->getRegSizeInBits(*SrcRC);
868 unsigned MoveOp = MoveSize == 64 ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
869 BuildMI(*BlockToInsertTo, PointToInsertTo, PointToInsertTo->getDebugLoc(),
870 TII->get(MoveOp), DstReg)
872 if (
MRI->hasOneUse(MaybeVGPRConstMO.
getReg()))
874 MaybeVGPRConstMO.
setReg(DstReg);
887 if (DstReg == AMDGPU::M0 &&
888 TRI->hasVectorRegisters(
MRI->getRegClass(SrcReg))) {
890 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
892 TII->get(AMDGPU::V_READFIRSTLANE_B32), TmpReg)
893 .
add(
MI.getOperand(1));
894 MI.getOperand(1).setReg(TmpReg);
895 }
else if (tryMoveVGPRConstToSGPR(
MI.getOperand(1), DstReg,
MI.getParent(),
898 MI.eraseFromParent();
905 TII->moveToVALU(worklist, MDT);
914 MI.getOperand(1).ChangeToImmediate(Imm);
915 MI.addImplicitDefUseOperands(*
MI.getParent()->getParent());
916 MI.setDesc(
TII->get(SMovOp));
926 V2SCopyInfo
Info(getNextVGPRToSGPRCopyId(),
MI,
927 TRI->getRegSizeInBits(*DstRC));
933 while (!AnalysisWorklist.
empty()) {
937 if (!Visited.
insert(Inst).second)
952 SiblingPenalty[Inst].insert(
Info.ID);
960 !
I->findRegisterDefOperand(AMDGPU::SCC,
nullptr)) {
961 if (
I->readsRegister(AMDGPU::SCC,
nullptr))
966 if (
TRI->isSGPRReg(*
MRI, Reg) && !
TII->isVALU(*Inst))
967 for (
auto &U :
MRI->use_instructions(Reg))
970 for (
auto *U :
Users) {
972 Info.SChain.insert(U);
981bool SIFixSGPRCopies::needToBeConvertedToVALU(V2SCopyInfo *Info) {
982 if (
Info->SChain.empty()) {
988 return SiblingPenalty[A].size() < SiblingPenalty[B].size();
990 Info->Siblings.remove_if([&](
unsigned ID) {
return ID ==
Info->ID; });
997 for (
auto J :
Info->Siblings) {
998 auto *InfoIt = V2SCopies.find(J);
999 if (InfoIt != V2SCopies.end()) {
1009 Info->SiblingPenalty = SrcRegs.
size();
1012 Info->NumSVCopies +
Info->SiblingPenalty +
Info->NumReadfirstlanes;
1013 unsigned Profit =
Info->SChain.size();
1014 Info->Score = Penalty > Profit ? 0 : Profit - Penalty;
1015 Info->NeedToBeConvertedToVALU =
Info->Score < 3;
1016 return Info->NeedToBeConvertedToVALU;
1022 for (
auto &
C : V2SCopies) {
1023 if (needToBeConvertedToVALU(&
C.second))
1031 while (!LoweringWorklist.
empty()) {
1033 auto *CurInfoIt = V2SCopies.find(CurID);
1034 if (CurInfoIt != V2SCopies.end()) {
1035 V2SCopyInfo
C = CurInfoIt->second;
1037 for (
auto S :
C.Siblings) {
1038 auto *SibInfoIt = V2SCopies.find(S);
1039 if (SibInfoIt != V2SCopies.end()) {
1040 V2SCopyInfo &
SI = SibInfoIt->second;
1042 if (!
SI.NeedToBeConvertedToVALU) {
1043 SI.SChain.set_subtract(
C.SChain);
1044 if (needToBeConvertedToVALU(&SI))
1047 SI.Siblings.remove_if([&](
unsigned ID) {
return ID ==
C.ID; });
1051 <<
" is being turned to VALU\n");
1054 V2SCopies.erase(
C.ID);
1063 for (
auto C : V2SCopies) {
1069 <<
" is being turned to v_readfirstlane_b32"
1070 <<
" Score: " <<
C.second.Score <<
"\n");
1071 Register DstReg =
MI->getOperand(0).getReg();
1072 Register SrcReg =
MI->getOperand(1).getReg();
1073 unsigned SubReg =
MI->getOperand(1).getSubReg();
1075 TRI->getRegClassForOperandReg(*
MRI,
MI->getOperand(1));
1076 size_t SrcSize =
TRI->getRegSizeInBits(*SrcRC);
1077 if (SrcSize == 16) {
1080 TII->get(AMDGPU::V_READFIRSTLANE_B32), DstReg);
1081 MIB.addReg(SrcReg, 0, AMDGPU::NoSubRegister);
1082 }
else if (SrcSize == 32) {
1084 TII->get(AMDGPU::V_READFIRSTLANE_B32), DstReg);
1085 MIB.addReg(SrcReg, 0,
SubReg);
1088 TII->get(AMDGPU::REG_SEQUENCE), DstReg);
1089 int N =
TRI->getRegSizeInBits(*SrcRC) / 32;
1090 for (
int i = 0; i <
N; i++) {
1092 Result, *
MRI,
MI->getOperand(1), SrcRC,
1093 TRI->getSubRegFromChannel(i), &AMDGPU::VGPR_32RegClass);
1095 MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
1097 TII->get(AMDGPU::V_READFIRSTLANE_B32), PartialDst)
1099 Result.addReg(PartialDst).addImm(
TRI->getSubRegFromChannel(i));
1102 MI->eraseFromParent();
1117 if (SrcReg == AMDGPU::SCC) {
1119 MRI->createVirtualRegister(
TRI->getWaveMaskRegClass());
1122 TII->get(IsWave32 ? AMDGPU::S_CSELECT_B32
1123 : AMDGPU::S_CSELECT_B64),
1127 I =
BuildMI(*
MI.getParent(), std::next(
I),
I->getDebugLoc(),
1128 TII->get(AMDGPU::COPY), DstReg)
1130 MI.eraseFromParent();
1133 if (DstReg == AMDGPU::SCC) {
1134 unsigned Opcode = IsWave32 ? AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64;
1135 Register Exec = IsWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
1138 MI.getDebugLoc(),
TII->get(Opcode))
1142 MI.eraseFromParent();
1152 SIFixSGPRCopies Impl(&MDT);
1153 bool Changed = Impl.run(MF);
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())
Class for arbitrary precision integers.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
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 '...
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *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 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.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
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.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
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)
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ 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.
PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
char & SIFixSGPRCopiesLegacyID
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
FunctionPass * createSIFixSGPRCopiesLegacyPass()
Utility to store machine instructions worklist.
void insert(MachineInstr *MI)