78#define DEBUG_TYPE "si-fix-sgpr-copies"
81 "amdgpu-enable-merge-m0",
82 cl::desc(
"Merge and hoist M0 initializations"),
95 unsigned NumSVCopies = 0;
100 unsigned NumReadfirstlanes = 0;
102 bool NeedToBeConvertedToVALU =
false;
110 unsigned SiblingPenalty = 0;
112 V2SCopyInfo() : Copy(nullptr),
ID(0){};
113 V2SCopyInfo(
unsigned Id, MachineInstr *
C,
unsigned Width)
114 : Copy(
C), NumReadfirstlanes(Width / 32), ID(
Id){};
115#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
117 dbgs() << ID <<
" : " << *Copy <<
"\n\tS:" << SChain.size()
118 <<
"\n\tSV:" << NumSVCopies <<
"\n\tSP: " << SiblingPenalty
119 <<
"\nScore: " << Score <<
"\n";
124class SIFixSGPRCopies {
125 MachineDominatorTree *MDT;
126 SmallVector<MachineInstr*, 4> SCCCopies;
127 SmallVector<MachineInstr*, 4> RegSequences;
128 SmallVector<MachineInstr*, 4> PHINodes;
129 SmallVector<MachineInstr*, 4> S2VCopies;
130 unsigned NextVGPRToSGPRCopyID = 0;
131 MapVector<unsigned, V2SCopyInfo> V2SCopies;
132 DenseMap<MachineInstr *, SetVector<unsigned>> SiblingPenalty;
133 DenseSet<MachineInstr *> PHISources;
136 MachineRegisterInfo *MRI;
137 const SIRegisterInfo *TRI;
138 const SIInstrInfo *TII;
140 SIFixSGPRCopies(MachineDominatorTree *MDT) : MDT(MDT) {}
142 bool run(MachineFunction &MF);
143 void fixSCCCopies(MachineFunction &MF);
144 void prepareRegSequenceAndPHIs(MachineFunction &MF);
145 unsigned getNextVGPRToSGPRCopyId() {
return ++NextVGPRToSGPRCopyID; }
146 bool needToBeConvertedToVALU(V2SCopyInfo *
I);
147 void analyzeVGPRToSGPRCopy(MachineInstr *
MI);
148 void lowerVGPR2SGPRCopies(MachineFunction &MF);
155 void processPHINode(MachineInstr &
MI);
160 bool tryMoveVGPRConstToSGPR(MachineOperand &MO,
Register NewDst,
161 MachineBasicBlock *BlockToInsertTo,
170 SIFixSGPRCopiesLegacy() : MachineFunctionPass(ID) {}
172 bool runOnMachineFunction(MachineFunction &MF)
override {
173 MachineDominatorTree *MDT =
174 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
175 SIFixSGPRCopies Impl(MDT);
179 StringRef getPassName()
const override {
return "SI Fix SGPR copies"; }
181 void getAnalysisUsage(AnalysisUsage &AU)
const override {
190 MachineFunctionProperties getClearedProperties()
const override {
191 return MachineFunctionProperties().setNoPHIs();
203char SIFixSGPRCopiesLegacy::
ID = 0;
208 return new SIFixSGPRCopiesLegacy();
211static std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
215 Register DstReg = Copy.getOperand(0).getReg();
216 Register SrcReg = Copy.getOperand(1).getReg();
220 :
TRI.getPhysRegBaseClass(SrcReg);
227 :
TRI.getPhysRegBaseClass(DstReg);
229 return std::pair(SrcRC, DstRC);
235 return SrcRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(DstRC) &&
236 TRI.hasVectorRegisters(SrcRC);
242 return DstRC != &AMDGPU::VReg_1RegClass &&
TRI.isSGPRClass(SrcRC) &&
243 TRI.hasVectorRegisters(DstRC);
250 auto &Src =
MI.getOperand(1);
257 const auto *
UseMI = MO.getParent();
260 if (MO.isDef() ||
UseMI->getParent() !=
MI.getParent() ||
261 UseMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)
264 unsigned OpIdx = MO.getOperandNo();
265 if (
OpIdx >=
UseMI->getDesc().getNumOperands() ||
319 if (SubReg != AMDGPU::NoSubRegister)
333 bool IsAGPR =
TRI->isAGPRClass(DstRC);
335 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
337 TRI->getRegClassForOperandReg(MRI,
MI.getOperand(
I));
339 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
351 unsigned Opc = NewSrcRC == &AMDGPU::AGPR_32RegClass ?
352 AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::COPY;
359 MI.getOperand(
I).setReg(TmpReg);
371 if (Copy->getOpcode() != AMDGPU::COPY)
374 if (!MoveImm->isMoveImmediate())
378 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
383 if (Copy->getOperand(1).getSubReg())
386 switch (MoveImm->getOpcode()) {
389 case AMDGPU::V_MOV_B32_e32:
390 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
391 SMovOp = AMDGPU::S_MOV_B32;
393 case AMDGPU::V_MOV_B64_e32:
394 case AMDGPU::V_MOV_B64_PSEUDO:
395 SMovOp = AMDGPU::S_MOV_B64_IMM_PSEUDO;
402template <
class UnaryPredicate>
412 while (!Worklist.
empty()) {
452 while (
I !=
MBB->end() &&
TII->isBasicBlockPrologue(*
I))
468 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
479 for (
auto &MO :
MI.operands()) {
480 if ((MO.isReg() && ((MO.isDef() && MO.getReg() !=
Reg) || !MO.isDef())) ||
481 (!MO.isImm() && !MO.isReg()) || (MO.isImm() && Imm)) {
489 Inits[Imm->getImm()].push_front(&
MI);
494 for (
auto &
Init : Inits) {
495 auto &Defs =
Init.second;
497 for (
auto I1 = Defs.begin(),
E = Defs.end(); I1 !=
E; ) {
500 for (
auto I2 = std::next(I1); I2 !=
E; ) {
509 auto interferes = [&MDT, From, To](
MachineInstr* &Clobber) ->
bool {
512 bool MayClobberFrom =
isReachable(Clobber, &*From, MBBTo, MDT);
513 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
514 if (!MayClobberFrom && !MayClobberTo)
516 if ((MayClobberFrom && !MayClobberTo) ||
517 (!MayClobberFrom && MayClobberTo))
523 return !((MBBFrom == MBBTo &&
531 return C.first !=
Init.first &&
537 if (!interferes(MI2, MI1)) {
547 if (!interferes(MI1, MI2)) {
565 if (!interferes(MI1,
I) && !interferes(MI2,
I)) {
569 <<
"and moving from "
586 for (
auto &
Init : Inits) {
587 auto &Defs =
Init.second;
588 auto I = Defs.begin();
589 while (
I != Defs.end()) {
590 if (MergedInstrs.
count(*
I)) {
591 (*I)->eraseFromParent();
599 for (
auto &
Init : Inits) {
600 auto &Defs =
Init.second;
601 for (
auto *
MI : Defs) {
602 auto *
MBB =
MI->getParent();
607 if (!
TII->isBasicBlockPrologue(*
B))
610 auto R = std::next(
MI->getReverseIterator());
611 const unsigned Threshold = 50;
613 for (
unsigned I = 0; R !=
B &&
I < Threshold; ++R, ++
I)
614 if (R->readsRegister(
Reg,
TRI) || R->definesRegister(
Reg,
TRI) ||
615 TII->isSchedulingBoundary(*R,
MBB, *
MBB->getParent()))
637 TRI =
ST.getRegisterInfo();
638 TII =
ST.getInstrInfo();
641 SmallVector<MachineInstr *, 8> Relegalize;
643 for (MachineBasicBlock &
MBB : MF) {
646 MachineInstr &
MI = *
I;
648 switch (
MI.getOpcode()) {
652 if (
TII->isWMMA(
MI) &&
673 if (lowerSpecialCase(
MI,
I))
676 analyzeVGPRToSGPRCopy(&
MI);
681 case AMDGPU::STRICT_WQM:
682 case AMDGPU::SOFT_WQM:
683 case AMDGPU::STRICT_WWM:
684 case AMDGPU::INSERT_SUBREG:
686 case AMDGPU::REG_SEQUENCE: {
687 if (
TRI->isSGPRClass(
TII->getOpRegClass(
MI, 0))) {
688 for (MachineOperand &MO :
MI.operands()) {
689 if (!MO.isReg() || !MO.getReg().isVirtual())
692 if (SrcRC == &AMDGPU::VReg_1RegClass)
695 if (
TRI->hasVectorRegisters(SrcRC)) {
697 TRI->getEquivalentSGPRClass(SrcRC);
698 Register NewDst = MRI->createVirtualRegister(DestRC);
699 MachineBasicBlock *BlockToInsertCopy =
700 MI.isPHI() ?
MI.getOperand(MO.getOperandNo() + 1).getMBB()
706 if (!tryMoveVGPRConstToSGPR(MO, NewDst, BlockToInsertCopy,
707 PointToInsertCopy,
DL)) {
708 MachineInstr *NewCopy =
709 BuildMI(*BlockToInsertCopy, PointToInsertCopy,
DL,
710 TII->get(AMDGPU::COPY), NewDst)
713 analyzeVGPRToSGPRCopy(NewCopy);
714 PHISources.
insert(NewCopy);
722 else if (
MI.isRegSequence())
727 case AMDGPU::V_WRITELANE_B32: {
730 if (
ST.getConstantBusLimit(
MI.getOpcode()) != 1)
740 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
742 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src1);
743 MachineOperand &Src0 =
MI.getOperand(Src0Idx);
744 MachineOperand &Src1 =
MI.getOperand(Src1Idx);
748 Src0.
getReg() != AMDGPU::M0) &&
750 Src1.
getReg() != AMDGPU::M0)) {
757 for (MachineOperand *MO : {&Src0, &Src1}) {
758 if (MO->getReg().isVirtual()) {
759 MachineInstr *
DefMI = MRI->getVRegDef(MO->getReg());
763 MO->getReg() ==
Def.getReg() &&
764 MO->getSubReg() ==
Def.getSubReg()) {
766 if (Copied.
isImm() &&
767 TII->isInlineConstant(APInt(64, Copied.
getImm(),
true))) {
768 MO->ChangeToImmediate(Copied.
getImm());
781 TII->get(AMDGPU::COPY), AMDGPU::M0)
792 lowerVGPR2SGPRCopies(MF);
795 for (
auto *
MI : S2VCopies) {
804 for (
auto *
MI : RegSequences) {
806 if (
MI->isRegSequence())
809 for (
auto *
MI : PHINodes) {
812 while (!Relegalize.
empty())
815 if (MF.getTarget().getOptLevel() > CodeGenOptLevel::None &&
EnableM0Merge)
818 SiblingPenalty.clear();
821 RegSequences.clear();
829void SIFixSGPRCopies::processPHINode(MachineInstr &
MI) {
830 bool AllAGPRUses =
true;
831 SetVector<const MachineInstr *> worklist;
832 SmallPtrSet<const MachineInstr *, 4> Visited;
833 SetVector<MachineInstr *> PHIOperands;
837 bool HasUses =
false;
838 while (!worklist.
empty()) {
841 for (
const auto &Use : MRI->use_operands(
Reg)) {
843 const MachineInstr *
UseMI =
Use.getParent();
846 TRI->isAGPR(*MRI,
Use.getReg());
858 if (HasUses && AllAGPRUses && !
TRI->isAGPRClass(RC0)) {
860 MRI->setRegClass(PHIRes,
TRI->getEquivalentAGPRClass(RC0));
861 for (
unsigned I = 1,
N =
MI.getNumOperands();
I !=
N;
I += 2) {
862 MachineInstr *
DefMI = MRI->getVRegDef(
MI.getOperand(
I).getReg());
868 if (
TRI->hasVectorRegisters(MRI->getRegClass(PHIRes)) ||
869 RC0 == &AMDGPU::VReg_1RegClass) {
871 TII->legalizeOperands(
MI, MDT);
875 while (!PHIOperands.
empty()) {
880bool SIFixSGPRCopies::tryMoveVGPRConstToSGPR(
881 MachineOperand &MaybeVGPRConstMO,
Register DstReg,
882 MachineBasicBlock *BlockToInsertTo,
885 MachineInstr *
DefMI = MRI->getVRegDef(MaybeVGPRConstMO.
getReg());
889 MachineOperand *SrcConst =
TII->getNamedOperand(*
DefMI, AMDGPU::OpName::src0);
890 if (SrcConst->
isReg())
894 MRI->getRegClass(MaybeVGPRConstMO.
getReg());
895 unsigned MoveSize =
TRI->getRegSizeInBits(*SrcRC);
897 MoveSize == 64 ? AMDGPU::S_MOV_B64_IMM_PSEUDO : AMDGPU::S_MOV_B32;
898 BuildMI(*BlockToInsertTo, PointToInsertTo,
DL,
TII->get(MoveOp), DstReg)
900 if (MRI->hasOneUse(MaybeVGPRConstMO.
getReg()))
902 MaybeVGPRConstMO.
setReg(DstReg);
906bool SIFixSGPRCopies::lowerSpecialCase(MachineInstr &
MI,
916 if (DstReg == AMDGPU::M0 &&
TRI->hasVectorRegisters(SrcRC)) {
918 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
920 const MCInstrDesc &ReadFirstLaneDesc =
921 TII->get(AMDGPU::V_READFIRSTLANE_B32);
922 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(), ReadFirstLaneDesc, TmpReg)
923 .
add(
MI.getOperand(1));
925 unsigned SubReg =
MI.getOperand(1).getSubReg();
926 MI.getOperand(1).setReg(TmpReg);
927 MI.getOperand(1).setSubReg(AMDGPU::NoSubRegister);
931 SubReg == AMDGPU::NoSubRegister
933 :
TRI->getMatchingSuperRegClass(SrcRC, OpRC, SubReg);
935 if (!MRI->constrainRegClass(SrcReg, ConstrainRC))
940 if (tryMoveVGPRConstToSGPR(
MI.getOperand(1), DstReg,
MI.getParent(),
MI,
942 I =
MI.eraseFromParent();
950 SIInstrWorklist worklist;
952 TII->moveToVALU(worklist, MDT);
961 MI.getOperand(1).ChangeToImmediate(Imm);
962 MI.addImplicitDefUseOperands(*
MI.getMF());
963 MI.setDesc(
TII->get(SMovOp));
969void SIFixSGPRCopies::analyzeVGPRToSGPRCopy(MachineInstr*
MI) {
975 V2SCopyInfo
Info(getNextVGPRToSGPRCopyId(),
MI,
976 TRI->getRegSizeInBits(*DstRC));
977 SmallVector<MachineInstr *, 8> AnalysisWorklist;
980 DenseSet<MachineInstr *> Visited;
982 while (!AnalysisWorklist.
empty()) {
986 if (!Visited.
insert(Inst).second)
1006 SiblingPenalty[Inst].insert(
Info.ID);
1008 SmallVector<MachineInstr *, 4>
Users;
1014 !
I->findRegisterDefOperand(AMDGPU::SCC,
nullptr)) {
1015 if (
I->readsRegister(AMDGPU::SCC,
nullptr))
1021 !
TII->isVALU(*Inst,
true)) {
1022 for (
auto &U : MRI->use_instructions(
Reg))
1023 Users.push_back(&U);
1026 for (
auto *U :
Users) {
1027 if (
TII->isSALU(*U))
1028 Info.SChain.insert(U);
1032 V2SCopies[
Info.ID] = std::move(Info);
1037bool SIFixSGPRCopies::needToBeConvertedToVALU(V2SCopyInfo *Info) {
1038 if (
Info->SChain.empty()) {
1043 Info->SChain, [&](MachineInstr *
A, MachineInstr *
B) ->
bool {
1044 return SiblingPenalty[A].size() < SiblingPenalty[B].size();
1046 Info->Siblings.remove_if([&](
unsigned ID) {
return ID ==
Info->ID; });
1052 SmallSet<std::pair<Register, unsigned>, 4> SrcRegs;
1053 for (
auto J :
Info->Siblings) {
1054 auto *InfoIt = V2SCopies.find(J);
1055 if (InfoIt != V2SCopies.end()) {
1056 MachineInstr *SiblingCopy = InfoIt->second.Copy;
1065 Info->SiblingPenalty = SrcRegs.
size();
1068 Info->NumSVCopies +
Info->SiblingPenalty +
Info->NumReadfirstlanes;
1069 unsigned Profit =
Info->SChain.size();
1070 Info->Score = Penalty > Profit ? 0 : Profit - Penalty;
1071 Info->NeedToBeConvertedToVALU =
Info->Score < 3;
1072 return Info->NeedToBeConvertedToVALU;
1075void SIFixSGPRCopies::lowerVGPR2SGPRCopies(MachineFunction &MF) {
1077 SmallVector<unsigned, 8> LoweringWorklist;
1078 for (
auto &
C : V2SCopies) {
1079 if (needToBeConvertedToVALU(&
C.second))
1087 while (!LoweringWorklist.
empty()) {
1089 auto *CurInfoIt = V2SCopies.find(CurID);
1090 if (CurInfoIt != V2SCopies.end() && !CurInfoIt->second.Erased) {
1091 V2SCopyInfo &
C = CurInfoIt->second;
1093 for (
auto S :
C.Siblings) {
1094 auto *SibInfoIt = V2SCopies.find(S);
1095 if (SibInfoIt != V2SCopies.end() && !SibInfoIt->second.Erased) {
1096 V2SCopyInfo &
SI = SibInfoIt->second;
1098 if (!
SI.NeedToBeConvertedToVALU) {
1099 SI.SChain.set_subtract(
C.SChain);
1100 if (needToBeConvertedToVALU(&SI))
1103 SI.Siblings.remove_if([&](
unsigned ID) {
return ID ==
C.ID; });
1107 <<
" is being turned to VALU\n");
1112 V2SCopies.remove_if([](
const auto &
P) {
return P.second.Erased; });
1118 for (
auto C : V2SCopies) {
1119 MachineInstr *
MI =
C.second.Copy;
1120 MachineBasicBlock *
MBB =
MI->getParent();
1124 <<
" is being turned to v_readfirstlane_b32"
1125 <<
" Score: " <<
C.second.Score <<
"\n");
1126 Register DstReg =
MI->getOperand(0).getReg();
1127 MRI->constrainRegClass(DstReg, &AMDGPU::SReg_32_XM0RegClass);
1129 Register SrcReg =
MI->getOperand(1).getReg();
1130 unsigned SubReg =
MI->getOperand(1).getSubReg();
1132 TRI->getRegClassForOperandReg(*MRI,
MI->getOperand(1));
1133 size_t SrcSize =
TRI->getRegSizeInBits(*SrcRC);
1134 if (SrcSize == 16) {
1136 "We do not expect to see 16-bit copies from VGPR to SGPR unless "
1137 "we have 16-bit VGPRs");
1138 assert(MRI->getRegClass(DstReg) == &AMDGPU::SReg_32RegClass ||
1139 MRI->getRegClass(DstReg) == &AMDGPU::SReg_32_XM0RegClass);
1141 MRI->setRegClass(DstReg, &AMDGPU::SReg_32_XM0RegClass);
1142 Register VReg32 = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1144 Register Undef = MRI->createVirtualRegister(&AMDGPU::VGPR_16RegClass);
1147 .
addReg(SrcReg, {}, SubReg)
1148 .addImm(AMDGPU::lo16)
1153 }
else if (SrcSize == 32) {
1154 const MCInstrDesc &ReadFirstLaneDesc =
1155 TII->get(AMDGPU::V_READFIRSTLANE_B32);
1158 .
addReg(SrcReg, {}, SubReg);
1161 SubReg == AMDGPU::NoSubRegister
1163 :
TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), OpRC,
1166 if (!MRI->constrainRegClass(SrcReg, ConstrainRC))
1170 TII->get(AMDGPU::REG_SEQUENCE), DstReg);
1171 int N =
TRI->getRegSizeInBits(*SrcRC) / 32;
1172 for (
int i = 0; i <
N; i++) {
1174 Result, *MRI,
MI->getOperand(1), SrcRC,
1175 TRI->getSubRegFromChannel(i), &AMDGPU::VGPR_32RegClass);
1177 MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
1179 TII->get(AMDGPU::V_READFIRSTLANE_B32), PartialDst)
1181 Result.addReg(PartialDst).addImm(
TRI->getSubRegFromChannel(i));
1184 MI->eraseFromParent();
1188void SIFixSGPRCopies::fixSCCCopies(MachineFunction &MF) {
1189 const AMDGPU::LaneMaskConstants &LMC =
1191 for (MachineBasicBlock &
MBB : MF) {
1194 MachineInstr &
MI = *
I;
1200 if (SrcReg == AMDGPU::SCC) {
1202 MRI->createVirtualRegister(
TRI->getWaveMaskRegClass());
1207 I =
BuildMI(*
MI.getParent(), std::next(
I),
I->getDebugLoc(),
1208 TII->get(AMDGPU::COPY), DstReg)
1210 MI.eraseFromParent();
1213 if (DstReg == AMDGPU::SCC) {
1214 Register Tmp = MRI->createVirtualRegister(
TRI->getBoolRC());
1220 MI.eraseFromParent();
1230 SIFixSGPRCopies Impl(&MDT);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
MachineInstr unsigned OpIdx
#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)
const unsigned CSelectOpc
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()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI 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.
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
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 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,...
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(uint64_t Opcode, OpName NamedIdx)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(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.
@ Kill
The last use of a register.
@ 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.
FunctionPass * createSIFixSGPRCopiesLegacyPass()
MCRegisterClass TargetRegisterClass
void insert(MachineInstr *MI)