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;
109 unsigned SiblingPenalty = 0;
111 V2SCopyInfo() : Copy(nullptr), ID(0){};
112 V2SCopyInfo(
unsigned Id, MachineInstr *
C,
unsigned Width)
113 : Copy(
C), NumReadfirstlanes(Width / 32), ID(
Id){};
114#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
116 dbgs() << ID <<
" : " << *Copy <<
"\n\tS:" << SChain.size()
117 <<
"\n\tSV:" << NumSVCopies <<
"\n\tSP: " << SiblingPenalty
118 <<
"\nScore: " << Score <<
"\n";
123class SIFixSGPRCopies {
124 MachineDominatorTree *MDT;
125 SmallVector<MachineInstr*, 4> SCCCopies;
126 SmallVector<MachineInstr*, 4> RegSequences;
127 SmallVector<MachineInstr*, 4> PHINodes;
128 SmallVector<MachineInstr*, 4> S2VCopies;
129 unsigned NextVGPRToSGPRCopyID = 0;
130 MapVector<unsigned, V2SCopyInfo> V2SCopies;
131 DenseMap<MachineInstr *, SetVector<unsigned>> SiblingPenalty;
132 DenseSet<MachineInstr *> PHISources;
135 MachineRegisterInfo *MRI;
136 const SIRegisterInfo *TRI;
137 const SIInstrInfo *TII;
139 SIFixSGPRCopies(MachineDominatorTree *MDT) : MDT(MDT) {}
143 unsigned getNextVGPRToSGPRCopyId() {
return ++NextVGPRToSGPRCopyID; }
144 bool needToBeConvertedToVALU(V2SCopyInfo *
I);
145 void analyzeVGPRToSGPRCopy(MachineInstr *
MI);
153 void processPHINode(MachineInstr &
MI);
158 bool tryMoveVGPRConstToSGPR(MachineOperand &MO,
Register NewDst,
159 MachineBasicBlock *BlockToInsertTo,
168 SIFixSGPRCopiesLegacy() : MachineFunctionPass(ID) {}
171 MachineDominatorTree *MDT =
172 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
173 SIFixSGPRCopies Impl(MDT);
177 StringRef getPassName()
const override {
return "SI Fix SGPR copies"; }
179 void getAnalysisUsage(AnalysisUsage &AU)
const override {
187 MachineFunctionProperties getClearedProperties()
const override {
188 return MachineFunctionProperties().setNoPHIs();
200char SIFixSGPRCopiesLegacy::ID = 0;
212 ? MRI.getRegClass(SrcReg)
213 :
TRI.getPhysRegBaseClass(SrcReg);
219 ? MRI.getRegClass(DstReg)
220 :
TRI.getPhysRegBaseClass(DstReg);
222 return std::pair(SrcRC, DstRC);
228 return SrcRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(DstRC) &&
229 TRI.hasVectorRegisters(SrcRC);
235 return DstRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(SrcRC) &&
236 TRI.hasVectorRegisters(DstRC);
243 auto &Src =
MI.getOperand(1);
250 const auto *
UseMI = MO.getParent();
253 if (MO.isDef() ||
UseMI->getParent() !=
MI.getParent() ||
254 UseMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)
257 unsigned OpIdx = MO.getOperandNo();
258 if (OpIdx >=
UseMI->getDesc().getNumOperands() ||
259 !
TII->isOperandLegal(*
UseMI, OpIdx, &Src))
312 if (SubReg != AMDGPU::NoSubRegister)
326 bool IsAGPR =
TRI->isAGPRClass(DstRC);
328 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
330 TRI->getRegClassForOperandReg(MRI,
MI.getOperand(
I));
332 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
344 unsigned Opc = NewSrcRC == &AMDGPU::AGPR_32RegClass ?
345 AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::COPY;
351 MI.getOperand(
I).setReg(TmpReg);
363 if (Copy->getOpcode() != AMDGPU::COPY)
366 if (!MoveImm || !MoveImm->isMoveImmediate())
370 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
375 if (Copy->getOperand(1).getSubReg())
378 switch (MoveImm->getOpcode()) {
381 case AMDGPU::V_MOV_B32_e32:
382 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
383 SMovOp = AMDGPU::S_MOV_B32;
385 case AMDGPU::V_MOV_B64_e32:
386 case AMDGPU::V_MOV_B64_PSEUDO:
387 SMovOp = AMDGPU::S_MOV_B64_IMM_PSEUDO;
394template <
class UnaryPredicate>
404 while (!Worklist.
empty()) {
444 while (
I !=
MBB->end() &&
TII->isBasicBlockPrologue(*
I))
461 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
472 for (
auto &MO :
MI.operands()) {
473 if ((MO.isReg() && ((MO.isDef() && MO.getReg() !=
Reg) || !MO.isDef())) ||
474 (!MO.isImm() && !MO.isReg()) || (MO.isImm() &&
Imm)) {
482 Inits[
Imm->getImm()].push_front(&
MI);
493 for (
auto &
Init : Inits) {
494 auto &Defs =
Init.second;
496 for (
auto I1 = Defs.begin(),
E = Defs.end(); I1 !=
E; ) {
499 for (
auto I2 = std::next(I1); I2 !=
E; ) {
508 auto interferes = [&MDT, From, To](
MachineInstr* &Clobber) ->
bool {
511 bool MayClobberFrom =
isReachable(Clobber, &*From, MBBTo, MDT);
512 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
513 if (!MayClobberFrom && !MayClobberTo)
515 if ((MayClobberFrom && !MayClobberTo) ||
516 (!MayClobberFrom && MayClobberTo))
522 return !((MBBFrom == MBBTo &&
530 return C.first !=
Init.first &&
536 if (!interferes(MI2, MI1)) {
546 if (!interferes(MI1, MI2)) {
564 if (!interferes(MI1,
I) && !interferes(MI2,
I)) {
568 <<
"and moving from "
585 for (
auto &
Init : Inits) {
586 auto &Defs =
Init.second;
587 auto I = Defs.begin();
588 while (
I != Defs.end()) {
589 if (MergedInstrs.
count(*
I)) {
590 (*I)->eraseFromParent();
598 for (
auto &
Init : Inits) {
599 auto &Defs =
Init.second;
600 for (
auto *
MI : Defs) {
601 auto *
MBB =
MI->getParent();
606 if (!
TII->isBasicBlockPrologue(*
B))
609 auto R = std::next(
MI->getReverseIterator());
610 const unsigned Threshold = 50;
612 for (
unsigned I = 0; R !=
B &&
I < Threshold; ++R, ++
I)
613 if (R->readsRegister(
Reg,
TRI) || R->modifiesRegister(
Reg,
TRI) ||
614 TII->isSchedulingBoundary(*R,
MBB, *
MBB->getParent()))
636 TRI =
ST.getRegisterInfo();
637 TII =
ST.getInstrInfo();
640 SmallVector<MachineInstr *, 8> Relegalize;
641 SmallVector<MachineInstr *, 4> RegMaskInstrs;
643 for (MachineBasicBlock &
MBB : MF) {
646 MachineInstr &
MI = *
I;
651 [](
const MachineOperand &MO) { return MO.isRegMask(); }))
654 switch (
MI.getOpcode()) {
658 if (
TII->isWMMA(
MI) &&
679 if (lowerSpecialCase(
MI,
I))
682 analyzeVGPRToSGPRCopy(&
MI);
687 case AMDGPU::STRICT_WQM:
688 case AMDGPU::SOFT_WQM:
689 case AMDGPU::STRICT_WWM:
690 case AMDGPU::INSERT_SUBREG:
692 case AMDGPU::REG_SEQUENCE: {
693 if (
TRI->isSGPRClass(
TII->getOpRegClass(
MI, 0))) {
694 for (MachineOperand &MO :
MI.operands()) {
698 if (SrcRC == &AMDGPU::VReg_1RegClass)
701 if (
TRI->hasVectorRegisters(SrcRC)) {
703 TRI->getEquivalentSGPRClass(SrcRC);
704 Register NewDst = MRI->createVirtualRegister(DestRC);
705 MachineBasicBlock *BlockToInsertCopy =
712 if (!tryMoveVGPRConstToSGPR(MO, NewDst, BlockToInsertCopy,
713 PointToInsertCopy,
DL)) {
714 MachineInstr *NewCopy =
715 BuildMI(*BlockToInsertCopy, PointToInsertCopy,
DL,
716 TII->get(AMDGPU::COPY), NewDst)
719 analyzeVGPRToSGPRCopy(NewCopy);
720 PHISources.
insert(NewCopy);
728 else if (
MI.isRegSequence())
733 case AMDGPU::V_WRITELANE_B32: {
736 if (
ST.getConstantBusLimit(
MI.getOpcode()) != 1)
746 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
748 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src1);
749 MachineOperand &
Src0 =
MI.getOperand(Src0Idx);
750 MachineOperand &
Src1 =
MI.getOperand(Src1Idx);
753 if ((
Src0.isReg() &&
TRI->isSGPRReg(*MRI,
Src0.getReg()) &&
754 Src0.getReg() != AMDGPU::M0) &&
755 (
Src1.isReg() &&
TRI->isSGPRReg(*MRI,
Src1.getReg()) &&
756 Src1.getReg() != AMDGPU::M0)) {
763 for (MachineOperand *MO : {&
Src0, &
Src1}) {
765 MachineInstr *
DefMI = MRI->getVRegDef(MO->
getReg());
772 if (Copied.
isImm() &&
773 TII->isInlineConstant(APInt(64, Copied.
getImm(),
true))) {
787 TII->get(AMDGPU::COPY), AMDGPU::M0)
789 Src1.ChangeToRegister(AMDGPU::M0,
false);
798 lowerVGPR2SGPRCopies(MF);
801 for (
auto *
MI : S2VCopies) {
810 for (
auto *
MI : RegSequences) {
812 if (
MI->isRegSequence())
815 for (
auto *
MI : PHINodes) {
818 while (!Relegalize.
empty())
821 if (MF.getTarget().getOptLevel() > CodeGenOptLevel::None &&
EnableM0Merge)
824 SiblingPenalty.clear();
827 RegSequences.clear();
835void SIFixSGPRCopies::processPHINode(MachineInstr &
MI) {
836 bool AllAGPRUses =
true;
837 SetVector<const MachineInstr *> worklist;
838 SmallPtrSet<const MachineInstr *, 4> Visited;
839 SetVector<MachineInstr *> PHIOperands;
843 bool HasUses =
false;
844 while (!worklist.
empty()) {
847 for (
const auto &Use : MRI->use_operands(
Reg)) {
849 const MachineInstr *
UseMI =
Use.getParent();
852 TRI->isAGPR(*MRI,
Use.getReg());
864 if (HasUses && AllAGPRUses && !
TRI->isAGPRClass(RC0)) {
866 MRI->setRegClass(PHIRes,
TRI->getEquivalentAGPRClass(RC0));
867 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
868 MachineInstr *
DefMI = MRI->getVRegDef(
MI.getOperand(
I).getReg());
874 if (
TRI->hasVectorRegisters(MRI->getRegClass(PHIRes)) ||
875 RC0 == &AMDGPU::VReg_1RegClass) {
877 TII->legalizeOperands(
MI, MDT);
881 while (!PHIOperands.
empty()) {
886bool SIFixSGPRCopies::tryMoveVGPRConstToSGPR(
887 MachineOperand &MaybeVGPRConstMO,
Register DstReg,
888 MachineBasicBlock *BlockToInsertTo,
891 MachineInstr *
DefMI = MRI->getVRegDef(MaybeVGPRConstMO.
getReg());
895 MachineOperand *SrcConst =
TII->getNamedOperand(*
DefMI, AMDGPU::OpName::src0);
896 if (SrcConst->
isReg())
900 MRI->getRegClass(MaybeVGPRConstMO.
getReg());
901 unsigned MoveSize =
TRI->getRegSizeInBits(*SrcRC);
903 MoveSize == 64 ? AMDGPU::S_MOV_B64_IMM_PSEUDO : AMDGPU::S_MOV_B32;
904 BuildMI(*BlockToInsertTo, PointToInsertTo,
DL,
TII->get(MoveOp), DstReg)
906 if (MRI->hasOneUse(MaybeVGPRConstMO.
getReg()))
908 MaybeVGPRConstMO.
setReg(DstReg);
912bool SIFixSGPRCopies::lowerSpecialCase(MachineInstr &
MI,
922 if (DstReg == AMDGPU::M0 &&
TRI->hasVectorRegisters(SrcRC)) {
924 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
926 const MCInstrDesc &ReadFirstLaneDesc =
927 TII->get(AMDGPU::V_READFIRSTLANE_B32);
928 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(), ReadFirstLaneDesc, TmpReg)
929 .
add(
MI.getOperand(1));
931 unsigned SubReg =
MI.getOperand(1).getSubReg();
932 MI.getOperand(1).setReg(TmpReg);
933 MI.getOperand(1).setSubReg(AMDGPU::NoSubRegister);
937 SubReg == AMDGPU::NoSubRegister
939 :
TRI->getMatchingSuperRegClass(SrcRC, OpRC, SubReg);
941 if (!MRI->constrainRegClass(SrcReg, ConstrainRC))
946 if (tryMoveVGPRConstToSGPR(
MI.getOperand(1), DstReg,
MI.getParent(),
MI,
948 I =
MI.eraseFromParent();
956 SIInstrWorklist worklist;
958 TII->moveToVALU(worklist, MDT);
967 MI.getOperand(1).ChangeToImmediate(
Imm);
968 MI.addImplicitDefUseOperands(*
MI.getMF());
969 MI.setDesc(
TII->get(SMovOp));
975void SIFixSGPRCopies::analyzeVGPRToSGPRCopy(MachineInstr*
MI) {
981 V2SCopyInfo
Info(getNextVGPRToSGPRCopyId(),
MI,
982 TRI->getRegSizeInBits(*DstRC));
983 SmallVector<MachineInstr *, 8> AnalysisWorklist;
986 DenseSet<MachineInstr *> Visited;
988 while (!AnalysisWorklist.
empty()) {
992 if (!Visited.
insert(Inst).second)
1012 SiblingPenalty[Inst].insert(
Info.ID);
1014 SmallVector<MachineInstr *, 4>
Users;
1020 !
I->findRegisterDefOperand(AMDGPU::SCC,
nullptr)) {
1021 if (
I->readsRegister(AMDGPU::SCC,
nullptr))
1027 !
TII->isVALU(*Inst,
true)) {
1028 for (
auto &U : MRI->use_instructions(
Reg))
1029 Users.push_back(&U);
1032 for (
auto *U :
Users) {
1033 if (
TII->isSALU(*U))
1034 Info.SChain.insert(U);
1038 V2SCopies[
Info.ID] = std::move(Info);
1043bool SIFixSGPRCopies::needToBeConvertedToVALU(V2SCopyInfo *Info) {
1044 if (
Info->SChain.empty()) {
1049 Info->SChain, [&](MachineInstr *
A, MachineInstr *
B) ->
bool {
1050 return SiblingPenalty[A].size() < SiblingPenalty[B].size();
1052 Info->Siblings.remove_if([&](
unsigned ID) {
return ID ==
Info->ID; });
1058 SmallSet<std::pair<Register, unsigned>, 4> SrcRegs;
1059 for (
auto J :
Info->Siblings) {
1060 auto *InfoIt = V2SCopies.find(J);
1061 if (InfoIt != V2SCopies.end()) {
1062 MachineInstr *SiblingCopy = InfoIt->second.Copy;
1071 Info->SiblingPenalty = SrcRegs.
size();
1074 Info->NumSVCopies +
Info->SiblingPenalty +
Info->NumReadfirstlanes;
1075 unsigned Profit =
Info->SChain.size();
1076 Info->Score = Penalty > Profit ? 0 : Profit - Penalty;
1077 Info->NeedToBeConvertedToVALU =
Info->Score < 3;
1078 return Info->NeedToBeConvertedToVALU;
1083 SmallVector<unsigned, 8> LoweringWorklist;
1084 for (
auto &
C : V2SCopies) {
1085 if (needToBeConvertedToVALU(&
C.second))
1093 while (!LoweringWorklist.
empty()) {
1095 auto *CurInfoIt = V2SCopies.find(CurID);
1096 if (CurInfoIt != V2SCopies.end() && !CurInfoIt->second.Erased) {
1097 V2SCopyInfo &
C = CurInfoIt->second;
1099 for (
auto S :
C.Siblings) {
1100 auto *SibInfoIt = V2SCopies.find(S);
1101 if (SibInfoIt != V2SCopies.end() && !SibInfoIt->second.Erased) {
1102 V2SCopyInfo &
SI = SibInfoIt->second;
1104 if (!
SI.NeedToBeConvertedToVALU) {
1105 SI.SChain.set_subtract(
C.SChain);
1106 if (needToBeConvertedToVALU(&SI))
1109 SI.Siblings.remove_if([&](
unsigned ID) {
return ID ==
C.ID; });
1113 <<
" is being turned to VALU\n");
1118 V2SCopies.remove_if([](
const auto &
P) {
return P.second.Erased; });
1124 for (
auto C : V2SCopies) {
1125 MachineInstr *
MI =
C.second.Copy;
1130 <<
" is being turned to v_readfirstlane_b32"
1131 <<
" Score: " <<
C.second.Score <<
"\n");
1132 Register DstReg =
MI->getOperand(0).getReg();
1133 MRI->constrainRegClass(DstReg, &AMDGPU::SReg_32_XM0RegClass);
1135 Register SrcReg =
MI->getOperand(1).getReg();
1136 unsigned SubReg =
MI->getOperand(1).getSubReg();
1138 TRI->getRegClassForOperandReg(*MRI,
MI->getOperand(1));
1139 size_t SrcSize =
TRI->getRegSizeInBits(*SrcRC);
1140 if (SrcSize == 16) {
1142 "We do not expect to see 16-bit copies from VGPR to SGPR unless "
1143 "we have 16-bit VGPRs");
1144 assert(MRI->getRegClass(DstReg) == &AMDGPU::SReg_32RegClass ||
1145 MRI->getRegClass(DstReg) == &AMDGPU::SReg_32_XM0RegClass);
1147 MRI->setRegClass(DstReg, &AMDGPU::SReg_32_XM0RegClass);
1148 Register VReg32 = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1150 Register Undef = MRI->createVirtualRegister(&AMDGPU::VGPR_16RegClass);
1153 .
addReg(SrcReg, {}, SubReg)
1154 .addImm(AMDGPU::lo16)
1159 }
else if (SrcSize == 32) {
1160 const MCInstrDesc &ReadFirstLaneDesc =
1161 TII->get(AMDGPU::V_READFIRSTLANE_B32);
1164 .
addReg(SrcReg, {}, SubReg);
1167 SubReg == AMDGPU::NoSubRegister
1169 :
TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), OpRC,
1172 if (!MRI->constrainRegClass(SrcReg, ConstrainRC))
1176 TII->get(AMDGPU::REG_SEQUENCE), DstReg);
1177 int N =
TRI->getRegSizeInBits(*SrcRC) / 32;
1178 for (
int i = 0; i <
N; i++) {
1180 Result, *MRI,
MI->getOperand(1), SrcRC,
1181 TRI->getSubRegFromChannel(i), &AMDGPU::VGPR_32RegClass);
1183 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
1185 TII->get(AMDGPU::V_READFIRSTLANE_B32), PartialDst)
1187 Result.addReg(PartialDst).addImm(
TRI->getSubRegFromChannel(i));
1190 MI->eraseFromParent();
1199 bool HasCmp =
ST.isWave32() ||
ST.hasScalarCompareEq64();
1200 for (MachineBasicBlock &
MBB : MF) {
1203 MachineInstr &
MI = *
I;
1207 const MachineOperand &Src =
MI.getOperand(1);
1210 if (SrcReg == AMDGPU::SCC) {
1212 MRI->createVirtualRegister(
TRI->getWaveMaskRegClass());
1214 MI.getDebugLoc(),
TII->get(LMC.CSelectOpc), SCCCopy)
1217 I =
BuildMI(*
MI.getParent(), std::next(
I),
I->getDebugLoc(),
1218 TII->get(AMDGPU::COPY), DstReg)
1220 MI.eraseFromParent();
1223 if (DstReg == AMDGPU::SCC) {
1226 if (HasCmp && !Src.getSubReg() &&
1227 TII->isMaskedByExec(SrcReg,
MI, *MRI)) {
1232 TII->get(LMC.CmpLgOpc))
1236 Register Tmp = MRI->createVirtualRegister(
TRI->getBoolRC());
1238 TII->get(LMC.AndOpc))
1243 MI.eraseFromParent();
1253 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)
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 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.
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.
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.
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 void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
use_instr_iterator use_instr_begin(Register RegNo) const
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< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
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.
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.
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)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ 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)