77#define DEBUG_TYPE "si-fix-sgpr-copies"
89 unsigned NumSVCopies = 0;
94 unsigned NumReadfirstlanes = 0;
96 bool NeedToBeConvertedToVALU =
false;
104 unsigned SiblingPenalty = 0;
106 V2SCopyInfo() : Copy(
nullptr), ID(0){};
108 : Copy(
C), NumReadfirstlanes(Width / 32), ID(Id){};
109#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 dbgs() << ID <<
" : " << *Copy <<
"\n\tS:" << SChain.
size()
112 <<
"\n\tSV:" << NumSVCopies <<
"\n\tSP: " << SiblingPenalty
113 <<
"\nScore: " << Score <<
"\n";
118class SIFixSGPRCopies {
124 unsigned NextVGPRToSGPRCopyID = 0;
138 unsigned getNextVGPRToSGPRCopyId() {
return ++NextVGPRToSGPRCopyID; }
139 bool needToBeConvertedToVALU(V2SCopyInfo *
I);
167 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
168 SIFixSGPRCopies Impl(MDT);
172 StringRef getPassName()
const override {
return "SI Fix SGPR copies"; }
195char SIFixSGPRCopiesLegacy::ID = 0;
207 ?
MRI.getRegClass(SrcReg)
208 :
TRI.getPhysRegBaseClass(SrcReg);
214 ?
MRI.getRegClass(DstReg)
215 :
TRI.getPhysRegBaseClass(DstReg);
217 return std::pair(SrcRC, DstRC);
223 return SrcRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(DstRC) &&
224 TRI.hasVectorRegisters(SrcRC);
230 return DstRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(SrcRC) &&
231 TRI.hasVectorRegisters(DstRC);
238 auto &Src =
MI.getOperand(1);
244 for (
const auto &MO :
MRI.reg_nodbg_operands(DstReg)) {
245 const auto *
UseMI = MO.getParent();
248 if (MO.isDef() ||
UseMI->getParent() !=
MI.getParent() ||
249 UseMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)
252 unsigned OpIdx = MO.getOperandNo();
253 if (OpIdx >=
UseMI->getDesc().getNumOperands() ||
254 !
TII->isOperandLegal(*
UseMI, OpIdx, &Src))
258 MRI.setRegClass(DstReg,
TRI->getEquivalentSGPRClass(
MRI.getRegClass(DstReg)));
282 if (!
TRI->isSGPRClass(
MRI.getRegClass(DstReg)))
285 if (!
MRI.hasOneUse(DstReg))
307 if (SubReg != AMDGPU::NoSubRegister)
310 MRI.setRegClass(DstReg, DstRC);
321 bool IsAGPR =
TRI->isAGPRClass(DstRC);
323 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
325 TRI->getRegClassForOperandReg(
MRI,
MI.getOperand(
I));
327 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
330 Register TmpReg =
MRI.createVirtualRegister(NewSrcRC);
338 Register TmpAReg =
MRI.createVirtualRegister(NewSrcRC);
339 unsigned Opc = NewSrcRC == &AMDGPU::AGPR_32RegClass ?
340 AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::COPY;
346 MI.getOperand(
I).setReg(TmpReg);
358 if (Copy->getOpcode() != AMDGPU::COPY)
361 if (!MoveImm || !MoveImm->isMoveImmediate())
365 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
370 if (Copy->getOperand(1).getSubReg())
373 switch (MoveImm->getOpcode()) {
376 case AMDGPU::V_MOV_B32_e32:
377 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
378 SMovOp = AMDGPU::S_MOV_B32;
380 case AMDGPU::V_MOV_B64_e32:
381 case AMDGPU::V_MOV_B64_PSEUDO:
382 SMovOp = AMDGPU::S_MOV_B64_IMM_PSEUDO;
389template <
class UnaryPredicate>
399 while (!Worklist.
empty()) {
439 while (
I !=
MBB->end() &&
TII->isBasicBlockPrologue(*
I))
456 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
465 for (
auto &
MI :
MRI.def_instructions(
Reg)) {
467 for (
auto &MO :
MI.operands()) {
468 if ((MO.isReg() && ((MO.isDef() && MO.getReg() !=
Reg) || !MO.isDef())) ||
469 (!MO.isImm() && !MO.isReg()) || (MO.isImm() &&
Imm)) {
477 Inits[
Imm->getImm()].push_front(&
MI);
488 for (
auto &
Init : Inits) {
489 auto &Defs =
Init.second;
491 for (
auto I1 = Defs.begin(),
E = Defs.end(); I1 !=
E; ) {
494 for (
auto I2 = std::next(I1); I2 !=
E; ) {
503 auto interferes = [&MDT, From, To](
MachineInstr* &Clobber) ->
bool {
506 bool MayClobberFrom =
isReachable(Clobber, &*From, MBBTo, MDT);
507 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
508 if (!MayClobberFrom && !MayClobberTo)
510 if ((MayClobberFrom && !MayClobberTo) ||
511 (!MayClobberFrom && MayClobberTo))
517 return !((MBBFrom == MBBTo &&
525 return C.first !=
Init.first &&
531 if (!interferes(MI2, MI1)) {
541 if (!interferes(MI1, MI2)) {
559 if (!interferes(MI1,
I) && !interferes(MI2,
I)) {
563 <<
"and moving from "
580 for (
auto &
Init : Inits) {
581 auto &Defs =
Init.second;
582 auto I = Defs.begin();
583 while (
I != Defs.end()) {
584 if (MergedInstrs.
count(*
I)) {
585 (*I)->eraseFromParent();
593 for (
auto &
Init : Inits) {
594 auto &Defs =
Init.second;
595 for (
auto *
MI : Defs) {
596 auto *
MBB =
MI->getParent();
601 if (!
TII->isBasicBlockPrologue(*
B))
604 auto R = std::next(
MI->getReverseIterator());
605 const unsigned Threshold = 50;
607 for (
unsigned I = 0; R !=
B &&
I < Threshold; ++R, ++
I)
608 if (R->readsRegister(
Reg,
TRI) || R->modifiesRegister(
Reg,
TRI) ||
609 TII->isSchedulingBoundary(*R,
MBB, *
MBB->getParent()))
631 TRI =
ST.getRegisterInfo();
632 TII =
ST.getInstrInfo();
635 SmallVector<MachineInstr *, 8> Relegalize;
636 SmallVector<MachineInstr *, 4> RegMaskInstrs;
638 for (MachineBasicBlock &
MBB : MF) {
641 MachineInstr &
MI = *
I;
646 [](
const MachineOperand &MO) { return MO.isRegMask(); }))
649 switch (
MI.getOpcode()) {
653 if (
TII->isWMMA(
MI) &&
674 if (lowerSpecialCase(
MI,
I))
677 analyzeVGPRToSGPRCopy(&
MI);
682 case AMDGPU::STRICT_WQM:
683 case AMDGPU::SOFT_WQM:
684 case AMDGPU::STRICT_WWM:
685 case AMDGPU::INSERT_SUBREG:
687 case AMDGPU::REG_SEQUENCE: {
688 if (
TRI->isSGPRClass(
TII->getOpRegClass(
MI, 0))) {
689 for (MachineOperand &MO :
MI.operands()) {
693 if (SrcRC == &AMDGPU::VReg_1RegClass)
696 if (
TRI->hasVectorRegisters(SrcRC)) {
698 TRI->getEquivalentSGPRClass(SrcRC);
700 MachineBasicBlock *BlockToInsertCopy =
707 if (!tryMoveVGPRConstToSGPR(MO, NewDst, BlockToInsertCopy,
708 PointToInsertCopy,
DL)) {
709 MachineInstr *NewCopy =
710 BuildMI(*BlockToInsertCopy, PointToInsertCopy,
DL,
711 TII->get(AMDGPU::COPY), NewDst)
714 analyzeVGPRToSGPRCopy(NewCopy);
715 PHISources.
insert(NewCopy);
723 else if (
MI.isRegSequence())
728 case AMDGPU::V_WRITELANE_B32: {
731 if (
ST.getConstantBusLimit(
MI.getOpcode()) != 1)
741 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
743 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src1);
744 MachineOperand &
Src0 =
MI.getOperand(Src0Idx);
745 MachineOperand &
Src1 =
MI.getOperand(Src1Idx);
749 Src0.getReg() != AMDGPU::M0) &&
751 Src1.getReg() != AMDGPU::M0)) {
758 for (MachineOperand *MO : {&
Src0, &
Src1}) {
767 if (Copied.
isImm() &&
768 TII->isInlineConstant(APInt(64, Copied.
getImm(),
true))) {
782 TII->get(AMDGPU::COPY), AMDGPU::M0)
784 Src1.ChangeToRegister(AMDGPU::M0,
false);
793 lowerVGPR2SGPRCopies(MF);
796 for (
auto *
MI : S2VCopies) {
805 for (
auto *
MI : RegSequences) {
807 if (
MI->isRegSequence())
810 for (
auto *
MI : PHINodes) {
813 while (!Relegalize.
empty())
816 if (MF.getTarget().getOptLevel() > CodeGenOptLevel::None &&
817 ST.getCLOpts().enable_merge_m0)
820 SiblingPenalty.clear();
823 RegSequences.clear();
831void SIFixSGPRCopies::processPHINode(MachineInstr &
MI) {
832 bool AllAGPRUses =
true;
833 SetVector<const MachineInstr *> worklist;
834 SmallPtrSet<const MachineInstr *, 4> Visited;
835 SetVector<MachineInstr *> PHIOperands;
839 bool HasUses =
false;
840 while (!worklist.
empty()) {
845 const MachineInstr *
UseMI =
Use.getParent();
860 if (HasUses && AllAGPRUses && !
TRI->isAGPRClass(RC0)) {
863 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
871 RC0 == &AMDGPU::VReg_1RegClass) {
873 TII->legalizeOperands(
MI, MDT);
877 while (!PHIOperands.
empty()) {
882bool SIFixSGPRCopies::tryMoveVGPRConstToSGPR(
883 MachineOperand &MaybeVGPRConstMO,
Register DstReg,
884 MachineBasicBlock *BlockToInsertTo,
891 MachineOperand *SrcConst =
TII->getNamedOperand(*
DefMI, AMDGPU::OpName::src0);
892 if (SrcConst->
isReg())
897 unsigned MoveSize =
TRI->getRegSizeInBits(*SrcRC);
899 MoveSize == 64 ? AMDGPU::S_MOV_B64_IMM_PSEUDO : AMDGPU::S_MOV_B32;
900 BuildMI(*BlockToInsertTo, PointToInsertTo,
DL,
TII->get(MoveOp), DstReg)
904 MaybeVGPRConstMO.
setReg(DstReg);
908bool SIFixSGPRCopies::lowerSpecialCase(MachineInstr &
MI,
918 if (DstReg == AMDGPU::M0 &&
TRI->hasVectorRegisters(SrcRC)) {
922 const MCInstrDesc &ReadFirstLaneDesc =
923 TII->get(AMDGPU::V_READFIRSTLANE_B32);
924 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(), ReadFirstLaneDesc, TmpReg)
925 .
add(
MI.getOperand(1));
927 unsigned SubReg =
MI.getOperand(1).getSubReg();
928 MI.getOperand(1).setReg(TmpReg);
929 MI.getOperand(1).setSubReg(AMDGPU::NoSubRegister);
933 SubReg == AMDGPU::NoSubRegister
935 :
TRI->getMatchingSuperRegClass(SrcRC, OpRC, SubReg);
942 if (tryMoveVGPRConstToSGPR(
MI.getOperand(1), DstReg,
MI.getParent(),
MI,
944 I =
MI.eraseFromParent();
952 SIInstrWorklist worklist;
954 TII->moveToVALU(worklist, MDT);
963 MI.getOperand(1).ChangeToImmediate(
Imm);
964 MI.addImplicitDefUseOperands(*
MI.getMF());
965 MI.setDesc(
TII->get(SMovOp));
971void SIFixSGPRCopies::analyzeVGPRToSGPRCopy(MachineInstr*
MI) {
977 V2SCopyInfo
Info(getNextVGPRToSGPRCopyId(),
MI,
978 TRI->getRegSizeInBits(*DstRC));
979 SmallVector<MachineInstr *, 8> AnalysisWorklist;
982 DenseSet<MachineInstr *> Visited;
984 while (!AnalysisWorklist.
empty()) {
988 if (!Visited.
insert(Inst).second)
1008 SiblingPenalty[Inst].insert(
Info.ID);
1010 SmallVector<MachineInstr *, 4>
Users;
1016 !
I->findRegisterDefOperand(AMDGPU::SCC,
nullptr)) {
1017 if (
I->readsRegister(AMDGPU::SCC,
nullptr))
1023 !
TII->isVALU(*Inst,
true)) {
1025 Users.push_back(&U);
1028 for (
auto *U :
Users) {
1029 if (
TII->isSALU(*U))
1030 Info.SChain.insert(U);
1034 V2SCopies[
Info.ID] = std::move(Info);
1039bool SIFixSGPRCopies::needToBeConvertedToVALU(V2SCopyInfo *Info) {
1040 if (
Info->SChain.empty()) {
1045 Info->SChain, [&](MachineInstr *
A, MachineInstr *
B) ->
bool {
1046 return SiblingPenalty[A].size() < SiblingPenalty[B].size();
1048 Info->Siblings.remove_if([&](
unsigned ID) {
return ID ==
Info->ID; });
1054 SmallSet<std::pair<Register, unsigned>, 4> SrcRegs;
1055 for (
auto J :
Info->Siblings) {
1056 auto *InfoIt = V2SCopies.find(J);
1057 if (InfoIt != V2SCopies.end()) {
1058 MachineInstr *SiblingCopy = InfoIt->second.Copy;
1067 Info->SiblingPenalty = SrcRegs.
size();
1070 Info->NumSVCopies +
Info->SiblingPenalty +
Info->NumReadfirstlanes;
1071 unsigned Profit =
Info->SChain.size();
1072 Info->Score = Penalty > Profit ? 0 : Profit - Penalty;
1073 Info->NeedToBeConvertedToVALU =
Info->Score < 3;
1074 return Info->NeedToBeConvertedToVALU;
1079 SmallVector<unsigned, 8> LoweringWorklist;
1080 for (
auto &
C : V2SCopies) {
1081 if (needToBeConvertedToVALU(&
C.second))
1089 while (!LoweringWorklist.
empty()) {
1091 auto *CurInfoIt = V2SCopies.find(CurID);
1092 if (CurInfoIt != V2SCopies.end() && !CurInfoIt->second.Erased) {
1093 V2SCopyInfo &
C = CurInfoIt->second;
1095 for (
auto S :
C.Siblings) {
1096 auto *SibInfoIt = V2SCopies.find(S);
1097 if (SibInfoIt != V2SCopies.end() && !SibInfoIt->second.Erased) {
1098 V2SCopyInfo &
SI = SibInfoIt->second;
1100 if (!
SI.NeedToBeConvertedToVALU) {
1101 SI.SChain.set_subtract(
C.SChain);
1102 if (needToBeConvertedToVALU(&SI))
1105 SI.Siblings.remove_if([&](
unsigned ID) {
return ID ==
C.ID; });
1109 <<
" is being turned to VALU\n");
1114 V2SCopies.remove_if([](
const auto &
P) {
return P.second.Erased; });
1120 for (
auto C : V2SCopies) {
1121 MachineInstr *
MI =
C.second.Copy;
1126 <<
" is being turned to v_readfirstlane_b32"
1127 <<
" Score: " <<
C.second.Score <<
"\n");
1128 Register DstReg =
MI->getOperand(0).getReg();
1131 Register SrcReg =
MI->getOperand(1).getReg();
1132 unsigned SubReg =
MI->getOperand(1).getSubReg();
1134 TRI->getRegClassForOperandReg(*
MRI,
MI->getOperand(1));
1135 size_t SrcSize =
TRI->getRegSizeInBits(*SrcRC);
1136 if (SrcSize == 16) {
1138 "We do not expect to see 16-bit copies from VGPR to SGPR unless "
1139 "we have 16-bit VGPRs");
1149 .
addReg(SrcReg, {}, SubReg)
1150 .addImm(AMDGPU::lo16)
1155 }
else if (SrcSize == 32) {
1156 const MCInstrDesc &ReadFirstLaneDesc =
1157 TII->get(AMDGPU::V_READFIRSTLANE_B32);
1160 .
addReg(SrcReg, {}, SubReg);
1163 SubReg == AMDGPU::NoSubRegister
1172 TII->get(AMDGPU::REG_SEQUENCE), DstReg);
1173 int N =
TRI->getRegSizeInBits(*SrcRC) / 32;
1174 for (
int i = 0; i <
N; i++) {
1176 Result, *
MRI,
MI->getOperand(1), SrcRC,
1177 TRI->getSubRegFromChannel(i), &AMDGPU::VGPR_32RegClass);
1181 TII->get(AMDGPU::V_READFIRSTLANE_B32), PartialDst)
1183 Result.addReg(PartialDst).addImm(
TRI->getSubRegFromChannel(i));
1186 MI->eraseFromParent();
1195 bool HasCmp =
ST.isWave32() ||
ST.hasScalarCompareEq64();
1196 for (MachineBasicBlock &
MBB : MF) {
1199 MachineInstr &
MI = *
I;
1203 const MachineOperand &Src =
MI.getOperand(1);
1206 if (SrcReg == AMDGPU::SCC) {
1210 MI.getDebugLoc(),
TII->get(LMC.CSelectOpc), SCCCopy)
1213 I =
BuildMI(*
MI.getParent(), std::next(
I),
I->getDebugLoc(),
1214 TII->get(AMDGPU::COPY), DstReg)
1216 MI.eraseFromParent();
1219 if (DstReg == AMDGPU::SCC) {
1222 if (HasCmp && !Src.getSubReg() &&
1223 TII->isMaskedByExec(SrcReg,
MI, *
MRI)) {
1228 TII->get(LMC.CmpLgOpc))
1234 TII->get(LMC.AndOpc))
1239 MI.eraseFromParent();
1250 SIFixSGPRCopies Impl(&MDT);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
iv Induction Variable Users
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
MachineRegisterInfo & MRI
static std::pair< const TargetRegisterClass *, const TargetRegisterClass * > getCopyRegClasses(const MachineInstr &Copy, const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI)
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 hoistAndMergeSGPRInits(unsigned Reg, ArrayRef< MachineInstr * > RegMaskInstrs, const MachineRegisterInfo &MRI, const TargetRegisterInfo *TRI, MachineDominatorTree &MDT, const TargetInstrInfo *TII)
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)
static const LaneMaskConstants & get(const GCNSubtarget &ST)
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()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
An RAII based helper class to modify MachineFunctionProperties when running pass.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
MachineInstrBundleIterator< MachineInstr > iterator
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.
Properties which a MachineFunction may have at a given point in time.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
bool isRegSequence() const
LLVM_ABI 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.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual 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 ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
iterator_range< use_iterator > use_operands(Register Reg) const
This class implements a map that also provides access to all stored values in a deterministic order.
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()
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
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.
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...
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
@ Resolved
Queried, materialization begun.
NodeAddr< DefNode * > Def
NodeAddr< InstrNode * > Instr
NodeAddr< UseNode * > Use
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.
@ Undef
Value of the register doesn't matter.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI 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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr RegState 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
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
void insert(MachineInstr *MI)