29#define GET_REGINFO_TARGET_DESC
30#include "AMDGPUGenRegisterInfo.inc"
33 "amdgpu-spill-sgpr-to-vgpr",
34 cl::desc(
"Enable spilling SGPRs to VGPRs"),
39 "amdgpu-spill-cfi-saved-regs",
40 cl::desc(
"Enable spilling the registers required for CFI emission"),
45 cl::desc(
"Limit VGPRs to N registers by reserving the rest"));
49 cl::desc(
"Limit AGPRs to N registers by reserving the rest"));
53 cl::desc(
"Limit SGPRs to N registers by reserving the rest"));
55std::array<std::vector<int16_t>, 32> SIRegisterInfo::RegSplitParts;
56std::array<std::array<uint16_t, 32>, 9> SIRegisterInfo::SubRegFromChannelTable;
63 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 9};
66 const Twine &ErrMsg) {
139 MI->getOperand(0).isKill(),
Index,
RS) {}
154 MovOpc = AMDGPU::S_MOV_B32;
155 NotOpc = AMDGPU::S_NOT_B32;
158 MovOpc = AMDGPU::S_MOV_B64;
159 NotOpc = AMDGPU::S_NOT_B64;
164 SuperReg != AMDGPU::EXEC &&
"exec should never spill");
195 assert(
RS &&
"Cannot spill SGPR to memory without RegScavenger");
196 TmpVGPR =
RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false,
224 IsWave32 ? AMDGPU::SGPR_32RegClass : AMDGPU::SGPR_64RegClass;
244 if (
RS->isRegUsed(AMDGPU::SCC))
246 "unhandled SGPR spill to memory");
256 I->getOperand(2).setIsDead();
291 I->getOperand(2).setIsDead();
320 if (
RS->isRegUsed(AMDGPU::SCC))
322 "unhandled SGPR spill to memory");
347 ST.getAMDGPUDwarfFlavour(),
352 assert(getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() == 3 &&
353 getSubRegIndexLaneMask(AMDGPU::sub31).getAsInteger() == (3ULL << 62) &&
354 (getSubRegIndexLaneMask(AMDGPU::lo16) |
355 getSubRegIndexLaneMask(AMDGPU::hi16)).getAsInteger() ==
356 getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() &&
357 "getNumCoveredRegs() will not work with generated subreg masks!");
359 RegPressureIgnoredUnits.resize(getNumRegUnits());
360 RegPressureIgnoredUnits.set(
362 for (
auto Reg : AMDGPU::VGPR_16RegClass) {
364 RegPressureIgnoredUnits.set(
365 static_cast<unsigned>(*regunits(Reg).begin()));
371 static auto InitializeRegSplitPartsOnce = [
this]() {
372 for (
unsigned Idx = 1, E = getNumSubRegIndices() - 1; Idx < E; ++Idx) {
373 unsigned Size = getSubRegIdxSize(Idx);
376 std::vector<int16_t> &Vec = RegSplitParts[
Size / 16 - 1];
377 unsigned Pos = getSubRegIdxOffset(Idx);
382 unsigned MaxNumParts = 1024 /
Size;
383 Vec.resize(MaxNumParts);
391 static auto InitializeSubRegFromChannelTableOnce = [
this]() {
392 for (
auto &Row : SubRegFromChannelTable)
393 Row.fill(AMDGPU::NoSubRegister);
394 for (
unsigned Idx = 1; Idx < getNumSubRegIndices(); ++Idx) {
395 unsigned Width = getSubRegIdxSize(Idx) / 32;
396 unsigned Offset = getSubRegIdxOffset(Idx) / 32;
401 unsigned TableIdx = Width - 1;
402 assert(TableIdx < SubRegFromChannelTable.size());
404 SubRegFromChannelTable[TableIdx][
Offset] = Idx;
408 llvm::call_once(InitializeRegSplitPartsFlag, InitializeRegSplitPartsOnce);
410 InitializeSubRegFromChannelTableOnce);
427 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_SaveList
428 : CSR_AMDGPU_SaveList;
431 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_SaveList
432 : CSR_AMDGPU_SI_Gfx_SaveList;
434 return CSR_AMDGPU_CS_ChainPreserve_SaveList;
437 static const MCPhysReg NoCalleeSavedReg = AMDGPU::NoRegister;
438 return &NoCalleeSavedReg;
454 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_RegMask
455 : CSR_AMDGPU_RegMask;
458 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_RegMask
459 : CSR_AMDGPU_SI_Gfx_RegMask;
464 return AMDGPU_AllVGPRs_RegMask;
471 return CSR_AMDGPU_NoRegs_RegMask;
475 return VGPR >= AMDGPU::VGPR0 && VGPR < AMDGPU::VGPR8;
486 if (RC == &AMDGPU::VGPR_32RegClass || RC == &AMDGPU::AGPR_32RegClass)
487 return &AMDGPU::AV_32RegClass;
488 if (RC == &AMDGPU::VReg_64RegClass || RC == &AMDGPU::AReg_64RegClass)
489 return &AMDGPU::AV_64RegClass;
490 if (RC == &AMDGPU::VReg_64_Align2RegClass ||
491 RC == &AMDGPU::AReg_64_Align2RegClass)
492 return &AMDGPU::AV_64_Align2RegClass;
493 if (RC == &AMDGPU::VReg_96RegClass || RC == &AMDGPU::AReg_96RegClass)
494 return &AMDGPU::AV_96RegClass;
495 if (RC == &AMDGPU::VReg_96_Align2RegClass ||
496 RC == &AMDGPU::AReg_96_Align2RegClass)
497 return &AMDGPU::AV_96_Align2RegClass;
498 if (RC == &AMDGPU::VReg_128RegClass || RC == &AMDGPU::AReg_128RegClass)
499 return &AMDGPU::AV_128RegClass;
500 if (RC == &AMDGPU::VReg_128_Align2RegClass ||
501 RC == &AMDGPU::AReg_128_Align2RegClass)
502 return &AMDGPU::AV_128_Align2RegClass;
503 if (RC == &AMDGPU::VReg_160RegClass || RC == &AMDGPU::AReg_160RegClass)
504 return &AMDGPU::AV_160RegClass;
505 if (RC == &AMDGPU::VReg_160_Align2RegClass ||
506 RC == &AMDGPU::AReg_160_Align2RegClass)
507 return &AMDGPU::AV_160_Align2RegClass;
508 if (RC == &AMDGPU::VReg_192RegClass || RC == &AMDGPU::AReg_192RegClass)
509 return &AMDGPU::AV_192RegClass;
510 if (RC == &AMDGPU::VReg_192_Align2RegClass ||
511 RC == &AMDGPU::AReg_192_Align2RegClass)
512 return &AMDGPU::AV_192_Align2RegClass;
513 if (RC == &AMDGPU::VReg_256RegClass || RC == &AMDGPU::AReg_256RegClass)
514 return &AMDGPU::AV_256RegClass;
515 if (RC == &AMDGPU::VReg_256_Align2RegClass ||
516 RC == &AMDGPU::AReg_256_Align2RegClass)
517 return &AMDGPU::AV_256_Align2RegClass;
518 if (RC == &AMDGPU::VReg_512RegClass || RC == &AMDGPU::AReg_512RegClass)
519 return &AMDGPU::AV_512RegClass;
520 if (RC == &AMDGPU::VReg_512_Align2RegClass ||
521 RC == &AMDGPU::AReg_512_Align2RegClass)
522 return &AMDGPU::AV_512_Align2RegClass;
523 if (RC == &AMDGPU::VReg_1024RegClass || RC == &AMDGPU::AReg_1024RegClass)
524 return &AMDGPU::AV_1024RegClass;
525 if (RC == &AMDGPU::VReg_1024_Align2RegClass ||
526 RC == &AMDGPU::AReg_1024_Align2RegClass)
527 return &AMDGPU::AV_1024_Align2RegClass;
557 return AMDGPU_AllVGPRs_RegMask;
561 return AMDGPU_AllAGPRs_RegMask;
565 return AMDGPU_AllVectorRegs_RegMask;
569 return AMDGPU_AllAllocatableSRegs_RegMask;
576 assert(NumRegIndex &&
"Not implemented");
577 assert(Channel < SubRegFromChannelTable[NumRegIndex - 1].
size());
578 return SubRegFromChannelTable[NumRegIndex - 1][Channel];
587 const unsigned Align,
590 MCRegister BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx));
591 return getMatchingSuperReg(BaseReg, AMDGPU::sub0, RC);
609 reserveRegisterTuples(
Reserved, AMDGPU::EXEC);
610 reserveRegisterTuples(
Reserved, AMDGPU::FLAT_SCR);
613 reserveRegisterTuples(
Reserved, AMDGPU::M0);
616 reserveRegisterTuples(
Reserved, AMDGPU::SRC_VCCZ);
617 reserveRegisterTuples(
Reserved, AMDGPU::SRC_EXECZ);
618 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SCC);
621 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_BASE);
622 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_LIMIT);
623 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_BASE);
624 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_LIMIT);
625 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_LO);
626 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_HI);
629 reserveRegisterTuples(
Reserved, AMDGPU::ASYNCcnt);
630 reserveRegisterTuples(
Reserved, AMDGPU::TENSORcnt);
633 reserveRegisterTuples(
Reserved, AMDGPU::SRC_POPS_EXITING_WAVE_ID);
636 reserveRegisterTuples(
Reserved, AMDGPU::XNACK_MASK);
639 reserveRegisterTuples(
Reserved, AMDGPU::LDS_DIRECT);
642 reserveRegisterTuples(
Reserved, AMDGPU::TBA);
643 reserveRegisterTuples(
Reserved, AMDGPU::TMA);
644 reserveRegisterTuples(
Reserved, AMDGPU::TTMP0_TTMP1);
645 reserveRegisterTuples(
Reserved, AMDGPU::TTMP2_TTMP3);
646 reserveRegisterTuples(
Reserved, AMDGPU::TTMP4_TTMP5);
647 reserveRegisterTuples(
Reserved, AMDGPU::TTMP6_TTMP7);
648 reserveRegisterTuples(
Reserved, AMDGPU::TTMP8_TTMP9);
649 reserveRegisterTuples(
Reserved, AMDGPU::TTMP10_TTMP11);
650 reserveRegisterTuples(
Reserved, AMDGPU::TTMP12_TTMP13);
651 reserveRegisterTuples(
Reserved, AMDGPU::TTMP14_TTMP15);
654 reserveRegisterTuples(
Reserved, AMDGPU::SGPR_NULL64);
658 unsigned MaxNumSGPRs = ST.getMaxNumSGPRs(MF);
661 unsigned TotalNumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
664 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
667 if (Index + NumRegs > MaxNumSGPRs && Index < TotalNumSGPRs &&
668 Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
676 if (ScratchRSrcReg != AMDGPU::NoRegister) {
680 reserveRegisterTuples(
Reserved, ScratchRSrcReg);
684 if (LongBranchReservedReg)
685 reserveRegisterTuples(
Reserved, LongBranchReservedReg);
692 reserveRegisterTuples(
Reserved, StackPtrReg);
693 assert(!isSubRegister(ScratchRSrcReg, StackPtrReg));
698 reserveRegisterTuples(
Reserved, FrameReg);
699 assert(!isSubRegister(ScratchRSrcReg, FrameReg));
704 reserveRegisterTuples(
Reserved, BasePtrReg);
705 assert(!isSubRegister(ScratchRSrcReg, BasePtrReg));
712 reserveRegisterTuples(
Reserved, ExecCopyReg);
716 auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.
getFunction());
726 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
729 if (Index + NumRegs > MaxNumVGPRs)
736 if (!ST.hasMAIInsts())
740 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
743 if (Index + NumRegs > MaxNumAGPRs)
751 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
759 if (!NonWWMRegMask.
empty()) {
760 for (
unsigned RegI = AMDGPU::VGPR0, RegE = AMDGPU::VGPR0 + MaxNumVGPRs;
761 RegI < RegE; ++RegI) {
762 if (NonWWMRegMask.
test(RegI))
763 reserveRegisterTuples(
Reserved, RegI);
768 reserveRegisterTuples(
Reserved, Reg);
772 reserveRegisterTuples(
Reserved, Reg);
775 reserveRegisterTuples(
Reserved, Reg);
792 if (Info->isBottomOfStack())
800 if (Info->isEntryFunction()) {
833 int OffIdx = AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
834 AMDGPU::OpName::offset);
835 return MI->getOperand(OffIdx).getImm();
840 switch (
MI->getOpcode()) {
841 case AMDGPU::V_ADD_U32_e32:
842 case AMDGPU::V_ADD_U32_e64:
843 case AMDGPU::V_ADD_CO_U32_e32: {
844 int OtherIdx = Idx == 1 ? 2 : 1;
848 case AMDGPU::V_ADD_CO_U32_e64: {
849 int OtherIdx = Idx == 2 ? 3 : 2;
860 assert((Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
861 AMDGPU::OpName::vaddr) ||
862 (Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
863 AMDGPU::OpName::saddr))) &&
864 "Should never see frame index on non-address operand");
876 return Src1.
isImm() || (Src1.
isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
881 return Src0.
isImm() || (Src0.
isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
890 switch (
MI->getOpcode()) {
891 case AMDGPU::V_ADD_U32_e32: {
894 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e32) < 2 &&
899 case AMDGPU::V_ADD_U32_e64:
909 return !ST.hasFlatScratchEnabled();
910 case AMDGPU::V_ADD_CO_U32_e32:
911 if (ST.getConstantBusLimit(AMDGPU::V_ADD_CO_U32_e32) < 2 &&
916 return MI->getOperand(3).isDead();
917 case AMDGPU::V_ADD_CO_U32_e64:
919 return MI->getOperand(1).isDead();
931 return !
TII->isLegalMUBUFImmOffset(FullOffset);
943 if (Ins !=
MBB->end())
944 DL = Ins->getDebugLoc();
950 ST.hasFlatScratchEnabled() ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
953 ST.hasFlatScratchEnabled() ? &AMDGPU::SReg_32_XEXEC_HIRegClass
954 : &AMDGPU::VGPR_32RegClass);
965 ? &AMDGPU::SReg_32_XM0RegClass
966 : &AMDGPU::VGPR_32RegClass);
973 if (ST.hasFlatScratchEnabled()) {
982 TII->getAddNoCarry(*
MBB, Ins,
DL, BaseReg)
994 switch (
MI.getOpcode()) {
995 case AMDGPU::V_ADD_U32_e32:
996 case AMDGPU::V_ADD_CO_U32_e32: {
1002 if (!ImmOp->
isImm()) {
1005 TII->legalizeOperandsVOP2(
MI.getMF()->getRegInfo(),
MI);
1010 if (TotalOffset == 0) {
1011 MI.setDesc(
TII->get(AMDGPU::COPY));
1012 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
1013 MI.removeOperand(
I);
1015 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
1019 ImmOp->
setImm(TotalOffset);
1034 MI.getOperand(2).ChangeToRegister(BaseRegVGPR,
false);
1036 MI.getOperand(2).ChangeToRegister(BaseReg,
false);
1040 case AMDGPU::V_ADD_U32_e64:
1041 case AMDGPU::V_ADD_CO_U32_e64: {
1042 int Src0Idx =
MI.getNumExplicitDefs();
1048 if (!ImmOp->
isImm()) {
1050 TII->legalizeOperandsVOP3(
MI.getMF()->getRegInfo(),
MI);
1055 if (TotalOffset == 0) {
1056 MI.setDesc(
TII->get(AMDGPU::COPY));
1058 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
1059 MI.removeOperand(
I);
1061 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
1064 ImmOp->
setImm(TotalOffset);
1073 bool IsFlat =
TII->isFLATScratch(
MI);
1077 bool SeenFI =
false;
1089 TII->getNamedOperand(
MI, IsFlat ? AMDGPU::OpName::saddr
1090 : AMDGPU::OpName::vaddr);
1095 assert(FIOp && FIOp->
isFI() &&
"frame index must be address operand");
1101 "offset should be legal");
1112 assert(
TII->isLegalMUBUFImmOffset(NewOffset) &&
"offset should be legal");
1122 switch (
MI->getOpcode()) {
1123 case AMDGPU::V_ADD_U32_e32:
1124 case AMDGPU::V_ADD_CO_U32_e32:
1126 case AMDGPU::V_ADD_U32_e64:
1127 case AMDGPU::V_ADD_CO_U32_e64:
1140 return TII->isLegalMUBUFImmOffset(NewOffset);
1151 return &AMDGPU::VGPR_32RegClass;
1156 return RC == &AMDGPU::SCC_CLASSRegClass ? &AMDGPU::SReg_32RegClass : RC;
1162 unsigned Op =
MI.getOpcode();
1164 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
1165 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
1166 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE:
1171 (
uint64_t)
TII->getNamedOperand(
MI, AMDGPU::OpName::mask)->getImm());
1172 case AMDGPU::SI_SPILL_S1024_SAVE:
1173 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
1174 case AMDGPU::SI_SPILL_S1024_RESTORE:
1175 case AMDGPU::SI_SPILL_V1024_SAVE:
1176 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
1177 case AMDGPU::SI_SPILL_V1024_RESTORE:
1178 case AMDGPU::SI_SPILL_A1024_SAVE:
1179 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
1180 case AMDGPU::SI_SPILL_A1024_RESTORE:
1181 case AMDGPU::SI_SPILL_AV1024_SAVE:
1182 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
1183 case AMDGPU::SI_SPILL_AV1024_RESTORE:
1185 case AMDGPU::SI_SPILL_S512_SAVE:
1186 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
1187 case AMDGPU::SI_SPILL_S512_RESTORE:
1188 case AMDGPU::SI_SPILL_V512_SAVE:
1189 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
1190 case AMDGPU::SI_SPILL_V512_RESTORE:
1191 case AMDGPU::SI_SPILL_A512_SAVE:
1192 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
1193 case AMDGPU::SI_SPILL_A512_RESTORE:
1194 case AMDGPU::SI_SPILL_AV512_SAVE:
1195 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
1196 case AMDGPU::SI_SPILL_AV512_RESTORE:
1198 case AMDGPU::SI_SPILL_S384_SAVE:
1199 case AMDGPU::SI_SPILL_S384_RESTORE:
1200 case AMDGPU::SI_SPILL_V384_SAVE:
1201 case AMDGPU::SI_SPILL_V384_RESTORE:
1202 case AMDGPU::SI_SPILL_A384_SAVE:
1203 case AMDGPU::SI_SPILL_A384_RESTORE:
1204 case AMDGPU::SI_SPILL_AV384_SAVE:
1205 case AMDGPU::SI_SPILL_AV384_RESTORE:
1207 case AMDGPU::SI_SPILL_S352_SAVE:
1208 case AMDGPU::SI_SPILL_S352_RESTORE:
1209 case AMDGPU::SI_SPILL_V352_SAVE:
1210 case AMDGPU::SI_SPILL_V352_RESTORE:
1211 case AMDGPU::SI_SPILL_A352_SAVE:
1212 case AMDGPU::SI_SPILL_A352_RESTORE:
1213 case AMDGPU::SI_SPILL_AV352_SAVE:
1214 case AMDGPU::SI_SPILL_AV352_RESTORE:
1216 case AMDGPU::SI_SPILL_S320_SAVE:
1217 case AMDGPU::SI_SPILL_S320_RESTORE:
1218 case AMDGPU::SI_SPILL_V320_SAVE:
1219 case AMDGPU::SI_SPILL_V320_RESTORE:
1220 case AMDGPU::SI_SPILL_A320_SAVE:
1221 case AMDGPU::SI_SPILL_A320_RESTORE:
1222 case AMDGPU::SI_SPILL_AV320_SAVE:
1223 case AMDGPU::SI_SPILL_AV320_RESTORE:
1225 case AMDGPU::SI_SPILL_S288_SAVE:
1226 case AMDGPU::SI_SPILL_S288_RESTORE:
1227 case AMDGPU::SI_SPILL_V288_SAVE:
1228 case AMDGPU::SI_SPILL_V288_RESTORE:
1229 case AMDGPU::SI_SPILL_A288_SAVE:
1230 case AMDGPU::SI_SPILL_A288_RESTORE:
1231 case AMDGPU::SI_SPILL_AV288_SAVE:
1232 case AMDGPU::SI_SPILL_AV288_RESTORE:
1234 case AMDGPU::SI_SPILL_S256_SAVE:
1235 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
1236 case AMDGPU::SI_SPILL_S256_RESTORE:
1237 case AMDGPU::SI_SPILL_V256_SAVE:
1238 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
1239 case AMDGPU::SI_SPILL_V256_RESTORE:
1240 case AMDGPU::SI_SPILL_A256_SAVE:
1241 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
1242 case AMDGPU::SI_SPILL_A256_RESTORE:
1243 case AMDGPU::SI_SPILL_AV256_SAVE:
1244 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
1245 case AMDGPU::SI_SPILL_AV256_RESTORE:
1247 case AMDGPU::SI_SPILL_S224_SAVE:
1248 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
1249 case AMDGPU::SI_SPILL_S224_RESTORE:
1250 case AMDGPU::SI_SPILL_V224_SAVE:
1251 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
1252 case AMDGPU::SI_SPILL_V224_RESTORE:
1253 case AMDGPU::SI_SPILL_A224_SAVE:
1254 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
1255 case AMDGPU::SI_SPILL_A224_RESTORE:
1256 case AMDGPU::SI_SPILL_AV224_SAVE:
1257 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
1258 case AMDGPU::SI_SPILL_AV224_RESTORE:
1260 case AMDGPU::SI_SPILL_S192_SAVE:
1261 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
1262 case AMDGPU::SI_SPILL_S192_RESTORE:
1263 case AMDGPU::SI_SPILL_V192_SAVE:
1264 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
1265 case AMDGPU::SI_SPILL_V192_RESTORE:
1266 case AMDGPU::SI_SPILL_A192_SAVE:
1267 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
1268 case AMDGPU::SI_SPILL_A192_RESTORE:
1269 case AMDGPU::SI_SPILL_AV192_SAVE:
1270 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
1271 case AMDGPU::SI_SPILL_AV192_RESTORE:
1273 case AMDGPU::SI_SPILL_S160_SAVE:
1274 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
1275 case AMDGPU::SI_SPILL_S160_RESTORE:
1276 case AMDGPU::SI_SPILL_V160_SAVE:
1277 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
1278 case AMDGPU::SI_SPILL_V160_RESTORE:
1279 case AMDGPU::SI_SPILL_A160_SAVE:
1280 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
1281 case AMDGPU::SI_SPILL_A160_RESTORE:
1282 case AMDGPU::SI_SPILL_AV160_SAVE:
1283 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
1284 case AMDGPU::SI_SPILL_AV160_RESTORE:
1286 case AMDGPU::SI_SPILL_S128_SAVE:
1287 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
1288 case AMDGPU::SI_SPILL_S128_RESTORE:
1289 case AMDGPU::SI_SPILL_V128_SAVE:
1290 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
1291 case AMDGPU::SI_SPILL_V128_RESTORE:
1292 case AMDGPU::SI_SPILL_A128_SAVE:
1293 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
1294 case AMDGPU::SI_SPILL_A128_RESTORE:
1295 case AMDGPU::SI_SPILL_AV128_SAVE:
1296 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
1297 case AMDGPU::SI_SPILL_AV128_RESTORE:
1299 case AMDGPU::SI_SPILL_S96_SAVE:
1300 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
1301 case AMDGPU::SI_SPILL_S96_RESTORE:
1302 case AMDGPU::SI_SPILL_V96_SAVE:
1303 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
1304 case AMDGPU::SI_SPILL_V96_RESTORE:
1305 case AMDGPU::SI_SPILL_A96_SAVE:
1306 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
1307 case AMDGPU::SI_SPILL_A96_RESTORE:
1308 case AMDGPU::SI_SPILL_AV96_SAVE:
1309 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
1310 case AMDGPU::SI_SPILL_AV96_RESTORE:
1312 case AMDGPU::SI_SPILL_S64_SAVE:
1313 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
1314 case AMDGPU::SI_SPILL_S64_RESTORE:
1315 case AMDGPU::SI_SPILL_V64_SAVE:
1316 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
1317 case AMDGPU::SI_SPILL_V64_RESTORE:
1318 case AMDGPU::SI_SPILL_A64_SAVE:
1319 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
1320 case AMDGPU::SI_SPILL_A64_RESTORE:
1321 case AMDGPU::SI_SPILL_AV64_SAVE:
1322 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
1323 case AMDGPU::SI_SPILL_AV64_RESTORE:
1325 case AMDGPU::SI_SPILL_S32_SAVE:
1326 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
1327 case AMDGPU::SI_SPILL_S32_RESTORE:
1328 case AMDGPU::SI_SPILL_V32_SAVE:
1329 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
1330 case AMDGPU::SI_SPILL_V32_RESTORE:
1331 case AMDGPU::SI_SPILL_A32_SAVE:
1332 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
1333 case AMDGPU::SI_SPILL_A32_RESTORE:
1334 case AMDGPU::SI_SPILL_AV32_SAVE:
1335 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
1336 case AMDGPU::SI_SPILL_AV32_RESTORE:
1337 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
1338 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1339 case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1340 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
1341 case AMDGPU::SI_SPILL_V16_SAVE:
1342 case AMDGPU::SI_SPILL_V16_RESTORE:
1350 case AMDGPU::BUFFER_STORE_DWORD_OFFEN:
1351 return AMDGPU::BUFFER_STORE_DWORD_OFFSET;
1352 case AMDGPU::BUFFER_STORE_BYTE_OFFEN:
1353 return AMDGPU::BUFFER_STORE_BYTE_OFFSET;
1354 case AMDGPU::BUFFER_STORE_SHORT_OFFEN:
1355 return AMDGPU::BUFFER_STORE_SHORT_OFFSET;
1356 case AMDGPU::BUFFER_STORE_DWORDX2_OFFEN:
1357 return AMDGPU::BUFFER_STORE_DWORDX2_OFFSET;
1358 case AMDGPU::BUFFER_STORE_DWORDX3_OFFEN:
1359 return AMDGPU::BUFFER_STORE_DWORDX3_OFFSET;
1360 case AMDGPU::BUFFER_STORE_DWORDX4_OFFEN:
1361 return AMDGPU::BUFFER_STORE_DWORDX4_OFFSET;
1362 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN:
1363 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET;
1364 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN:
1365 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET;
1373 case AMDGPU::BUFFER_LOAD_DWORD_OFFEN:
1374 return AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
1375 case AMDGPU::BUFFER_LOAD_UBYTE_OFFEN:
1376 return AMDGPU::BUFFER_LOAD_UBYTE_OFFSET;
1377 case AMDGPU::BUFFER_LOAD_SBYTE_OFFEN:
1378 return AMDGPU::BUFFER_LOAD_SBYTE_OFFSET;
1379 case AMDGPU::BUFFER_LOAD_USHORT_OFFEN:
1380 return AMDGPU::BUFFER_LOAD_USHORT_OFFSET;
1381 case AMDGPU::BUFFER_LOAD_SSHORT_OFFEN:
1382 return AMDGPU::BUFFER_LOAD_SSHORT_OFFSET;
1383 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN:
1384 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET;
1385 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN:
1386 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET;
1387 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN:
1388 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET;
1389 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN:
1390 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET;
1391 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN:
1392 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET;
1393 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN:
1394 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET;
1395 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN:
1396 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET;
1397 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN:
1398 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET;
1399 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN:
1400 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET;
1408 case AMDGPU::BUFFER_STORE_DWORD_OFFSET:
1409 return AMDGPU::BUFFER_STORE_DWORD_OFFEN;
1410 case AMDGPU::BUFFER_STORE_BYTE_OFFSET:
1411 return AMDGPU::BUFFER_STORE_BYTE_OFFEN;
1412 case AMDGPU::BUFFER_STORE_SHORT_OFFSET:
1413 return AMDGPU::BUFFER_STORE_SHORT_OFFEN;
1414 case AMDGPU::BUFFER_STORE_DWORDX2_OFFSET:
1415 return AMDGPU::BUFFER_STORE_DWORDX2_OFFEN;
1416 case AMDGPU::BUFFER_STORE_DWORDX3_OFFSET:
1417 return AMDGPU::BUFFER_STORE_DWORDX3_OFFEN;
1418 case AMDGPU::BUFFER_STORE_DWORDX4_OFFSET:
1419 return AMDGPU::BUFFER_STORE_DWORDX4_OFFEN;
1420 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET:
1421 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN;
1422 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET:
1423 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN;
1431 case AMDGPU::BUFFER_LOAD_DWORD_OFFSET:
1432 return AMDGPU::BUFFER_LOAD_DWORD_OFFEN;
1433 case AMDGPU::BUFFER_LOAD_UBYTE_OFFSET:
1434 return AMDGPU::BUFFER_LOAD_UBYTE_OFFEN;
1435 case AMDGPU::BUFFER_LOAD_SBYTE_OFFSET:
1436 return AMDGPU::BUFFER_LOAD_SBYTE_OFFEN;
1437 case AMDGPU::BUFFER_LOAD_USHORT_OFFSET:
1438 return AMDGPU::BUFFER_LOAD_USHORT_OFFEN;
1439 case AMDGPU::BUFFER_LOAD_SSHORT_OFFSET:
1440 return AMDGPU::BUFFER_LOAD_SSHORT_OFFEN;
1441 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET:
1442 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN;
1443 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET:
1444 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN;
1445 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET:
1446 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN;
1447 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET:
1448 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN;
1449 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET:
1450 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN;
1451 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET:
1452 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN;
1453 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET:
1454 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN;
1455 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET:
1456 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN;
1457 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET:
1458 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN;
1467 unsigned ValueReg,
bool IsKill,
bool NeedsCFI) {
1475 if (
Reg == AMDGPU::NoRegister)
1478 bool IsStore =
MI->mayStore();
1482 unsigned Dst = IsStore ?
Reg : ValueReg;
1483 unsigned Src = IsStore ? ValueReg :
Reg;
1484 bool IsVGPR =
TRI->isVGPR(MRI,
Reg);
1486 if (IsVGPR ==
TRI->isVGPR(MRI, ValueReg)) {
1498 unsigned Opc = (IsStore ^ IsVGPR) ? AMDGPU::V_ACCVGPR_WRITE_B32_e64
1499 : AMDGPU::V_ACCVGPR_READ_B32_e64;
1519 bool IsStore =
MI->mayStore();
1521 unsigned Opc =
MI->getOpcode();
1522 int LoadStoreOp = IsStore ?
1524 if (LoadStoreOp == -1)
1535 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::srsrc))
1536 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset))
1543 AMDGPU::OpName::vdata_in);
1545 NewMI.
add(*VDataIn);
1550 unsigned LoadStoreOp,
1552 bool IsStore =
TII->get(LoadStoreOp).mayStore();
1558 if (
TII->isBlockLoadStore(LoadStoreOp))
1563 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
1564 : AMDGPU::SCRATCH_LOAD_DWORD_SADDR;
1567 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX2_SADDR
1568 : AMDGPU::SCRATCH_LOAD_DWORDX2_SADDR;
1571 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX3_SADDR
1572 : AMDGPU::SCRATCH_LOAD_DWORDX3_SADDR;
1575 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX4_SADDR
1576 : AMDGPU::SCRATCH_LOAD_DWORDX4_SADDR;
1592 unsigned LoadStoreOp,
int Index,
Register ValueReg,
bool IsKill,
1595 assert((!RS || !LiveUnits) &&
"Only RS or LiveUnits can be set but not both");
1604 bool IsStore =
Desc->mayStore();
1605 bool IsFlat =
TII->isFLATScratch(LoadStoreOp);
1606 bool IsBlock =
TII->isBlockLoadStore(LoadStoreOp);
1608 bool CanClobberSCC =
false;
1609 bool Scavenged =
false;
1614 const bool IsAGPR = !ST.hasGFX90AInsts() &&
isAGPRClass(RC);
1625 bool IsRegMisaligned =
false;
1626 if (!IsBlock && !IsAGPR && RegWidth > 4) {
1627 unsigned SpillOpcode =
1630 IsStore ? AMDGPU::getNamedOperandIdx(SpillOpcode, AMDGPU::OpName::vdata)
1633 TII->getRegClass(
TII->get(SpillOpcode), VDataIdx);
1634 if (!ExpectedRC->
contains(ValueReg)) {
1638 getMatchingSuperRegClass(RC, ExpectedRC, SubIdx);
1639 if (!MatchRC || !MatchRC->
contains(ValueReg))
1640 IsRegMisaligned =
true;
1644 if (IsRegMisaligned)
1649 unsigned EltSize = IsBlock ? RegWidth
1650 : (IsFlat && !IsAGPR) ? std::min(RegWidth, 16u)
1652 unsigned NumSubRegs = RegWidth / EltSize;
1653 unsigned Size = NumSubRegs * EltSize;
1654 unsigned RemSize = RegWidth -
Size;
1655 unsigned NumRemSubRegs = RemSize ? 1 : 0;
1657 if (IsRegMisaligned)
1660 int64_t MaterializedOffset =
Offset;
1665 int64_t MaxOffset =
Offset +
Size - (RemSize ? 0 : EltSize);
1666 int64_t ScratchOffsetRegDelta = 0;
1667 int64_t AdditionalCFIOffset = 0;
1669 if (IsFlat && EltSize > 4) {
1671 Desc = &
TII->get(LoadStoreOp);
1678 "unexpected VGPR spill offset");
1685 bool UseVGPROffset =
false;
1692 if (IsFlat && SGPRBase) {
1697 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) >= 2) {
1716 bool IsOffsetLegal =
1719 :
TII->isLegalMUBUFImmOffset(MaxOffset);
1720 if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
1728 SOffset = RS->scavengeRegisterBackwards(AMDGPU::SGPR_32RegClass,
MI,
false, 0,
false);
1731 CanClobberSCC = !RS->isRegUsed(AMDGPU::SCC);
1732 }
else if (LiveUnits) {
1733 CanClobberSCC = LiveUnits->
available(AMDGPU::SCC);
1734 for (
MCRegister Reg : AMDGPU::SGPR_32RegClass) {
1742 if (ScratchOffsetReg != AMDGPU::NoRegister && !CanClobberSCC)
1746 UseVGPROffset =
true;
1749 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1752 for (
MCRegister Reg : AMDGPU::VGPR_32RegClass) {
1754 TmpOffsetVGPR = Reg;
1761 }
else if (!SOffset && CanClobberSCC) {
1772 if (!ScratchOffsetReg)
1774 SOffset = ScratchOffsetReg;
1775 ScratchOffsetRegDelta =
Offset;
1780 AdditionalCFIOffset =
Offset;
1784 if (!IsFlat && !UseVGPROffset)
1785 Offset *= ST.getWavefrontSize();
1787 if (!UseVGPROffset && !SOffset)
1790 if (UseVGPROffset) {
1792 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR,
Offset);
1793 }
else if (ScratchOffsetReg == AMDGPU::NoRegister) {
1798 .
addReg(ScratchOffsetReg)
1800 Add->getOperand(3).setIsDead();
1806 if (IsFlat && SOffset == AMDGPU::NoRegister) {
1807 assert(AMDGPU::getNamedOperandIdx(LoadStoreOp, AMDGPU::OpName::vaddr) < 0
1808 &&
"Unexpected vaddr for flat scratch with a FI operand");
1810 if (UseVGPROffset) {
1813 assert(ST.hasFlatScratchSTMode());
1814 assert(!
TII->isBlockLoadStore(LoadStoreOp) &&
"Block ops don't have ST");
1818 Desc = &
TII->get(LoadStoreOp);
1823 unsigned OrigEltSize = EltSize;
1824 for (
unsigned i = 0, e = NumSubRegs + NumRemSubRegs, RegOffset = 0; i != e;
1825 ++i, RegOffset += EltSize) {
1826 if (IsRegMisaligned) {
1834 IsRegMisaligned =
false;
1835 EltSize = OrigEltSize;
1839 if (i == NumSubRegs) {
1843 Desc = &
TII->get(LoadStoreOp);
1845 if (!IsFlat && UseVGPROffset) {
1848 Desc = &
TII->get(NewLoadStoreOp);
1851 if (UseVGPROffset && TmpOffsetVGPR == TmpIntermediateVGPR) {
1858 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, MaterializedOffset);
1861 unsigned NumRegs = EltSize / 4;
1869 const bool IsLastSubReg = i + 1 == e;
1870 const bool IsFirstSubReg = i == 0;
1879 bool NeedSuperRegDef = e > 1 && IsStore && IsFirstSubReg;
1880 bool NeedSuperRegImpOperand = e > 1;
1884 unsigned RemEltSize = EltSize;
1892 for (
int LaneS = (RegOffset + EltSize) / 4 - 1, Lane = LaneS,
1893 LaneE = RegOffset / 4;
1894 Lane >= LaneE; --Lane) {
1895 bool IsSubReg = e > 1 || EltSize > 4;
1901 if (!MIB.getInstr())
1903 if (NeedSuperRegDef || (IsSubReg && IsStore && Lane == LaneS && IsFirstSubReg)) {
1905 NeedSuperRegDef =
false;
1907 if ((IsSubReg || NeedSuperRegImpOperand) && (IsFirstSubReg || IsLastSubReg)) {
1908 NeedSuperRegImpOperand =
true;
1910 if (!IsLastSubReg || (Lane != LaneE))
1912 if (!IsFirstSubReg || (Lane != LaneS))
1922 if (RemEltSize != EltSize) {
1923 assert(IsFlat && EltSize > 4);
1925 unsigned NumRegs = RemEltSize / 4;
1926 SubReg =
Register(getSubReg(ValueReg,
1932 unsigned FinalReg = SubReg;
1937 if (!TmpIntermediateVGPR) {
1943 TII->get(AMDGPU::V_ACCVGPR_READ_B32_e64),
1944 TmpIntermediateVGPR)
1946 if (NeedSuperRegDef)
1948 if (NeedSuperRegImpOperand && (IsFirstSubReg || IsLastSubReg))
1952 SubReg = TmpIntermediateVGPR;
1953 }
else if (UseVGPROffset) {
1954 if (!TmpOffsetVGPR) {
1955 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
1957 RS->setRegUsed(TmpOffsetVGPR);
1962 if (LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_SADDR ||
1963 LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_ST) {
1967 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1983 if (UseVGPROffset) {
1992 if (SOffset == AMDGPU::NoRegister) {
1994 if (UseVGPROffset && ScratchOffsetReg) {
1995 MIB.addReg(ScratchOffsetReg);
2002 MIB.addReg(SOffset, SOffsetRegState);
2012 MIB.addMemOperand(NewMMO);
2014 if (FinalValueReg != ValueReg) {
2016 ValueReg = getSubReg(ValueReg, AMDGPU::lo16);
2022 ValueReg = FinalValueReg;
2025 if (IsStore && NeedsCFI) {
2026 if (
TII->isBlockLoadStore(LoadStoreOp)) {
2028 "expected whole register block to be treated as single element");
2033 (
Offset + RegOffset) * ST.getWavefrontSize() + AdditionalCFIOffset);
2037 if (!IsAGPR && NeedSuperRegDef)
2040 if (!IsStore && IsAGPR && TmpIntermediateVGPR != AMDGPU::NoRegister) {
2048 bool PartialReloadCopy = (RemEltSize != EltSize) && !IsStore;
2049 if (NeedSuperRegImpOperand &&
2050 (IsFirstSubReg || (IsLastSubReg && !IsSrcDstDef))) {
2052 if (PartialReloadCopy)
2077 if (!IsStore &&
MI !=
MBB.end() &&
MI->isReturn() &&
2078 MI->readsRegister(SubReg,
this)) {
2080 MIB->tieOperands(0, MIB->getNumOperands() - 1);
2088 if (!IsStore &&
TII->isBlockLoadStore(LoadStoreOp))
2092 if (ScratchOffsetRegDelta != 0) {
2096 .
addImm(-ScratchOffsetRegDelta);
2105 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2106 for (
unsigned RegOffset = 1; RegOffset < 32; ++RegOffset)
2107 if (!(Mask & (1 << RegOffset)) &&
2108 isCalleeSavedPhysReg(BaseVGPR + RegOffset, *MF))
2119 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2120 for (
unsigned RegOffset = 0; RegOffset < 32; ++RegOffset) {
2121 Register VGPR = BaseVGPR + RegOffset;
2122 if (Mask & (1 << RegOffset)) {
2123 assert(isCalleeSavedPhysReg(VGPR, *MF));
2124 ST.getFrameLowering()->buildCFIForVGPRToVMEMSpill(
2126 (
Offset + RegOffset) * ST.getWavefrontSize());
2127 }
else if (isCalleeSavedPhysReg(VGPR, *MF)) {
2132 BaseVGPR + RegOffset);
2139 bool IsKill)
const {
2149 Align Alignment = FrameInfo.getObjectAlign(Index);
2156 unsigned Opc = ST.hasFlatScratchEnabled()
2157 ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2158 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2162 unsigned Opc = ST.hasFlatScratchEnabled()
2163 ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2164 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2175 bool SpillToPhysVGPRLane,
bool NeedsCFI)
const {
2176 assert(!
MI->getOperand(0).isUndef() &&
2177 "undef spill should have been deleted earlier");
2184 bool SpillToVGPR = !VGPRSpills.
empty();
2185 if (OnlyToVGPR && !SpillToVGPR)
2200 "Num of SGPRs spilled should be less than or equal to num of "
2203 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2210 bool IsFirstSubreg = i == 0;
2212 bool UseKill = SB.
IsKill && IsLastSubreg;
2218 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), Spill.VGPR)
2228 AMDGPU::PC_REG, VGPRSpills);
2231 Spill.VGPR, Spill.Lane);
2251 if (SB.
NumSubRegs > 1 && (IsFirstSubreg || IsLastSubreg))
2271 for (
unsigned i =
Offset * PVD.PerVGPR,
2281 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), SB.
TmpVGPR)
2282 .
addReg(SubReg, SubKillState)
2313 ST.getWavefrontSize();
2315 AMDGPU::PC_REG, CFIOffset);
2324 MI->eraseFromParent();
2336 bool SpillToPhysVGPRLane)
const {
2342 bool SpillToVGPR = !VGPRSpills.
empty();
2343 if (OnlyToVGPR && !SpillToVGPR)
2347 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2355 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2378 for (
unsigned i =
Offset * PVD.PerVGPR,
2386 bool LastSubReg = (i + 1 == e);
2388 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2405 MI->eraseFromParent();
2425 for (
unsigned i =
Offset * PVD.PerVGPR,
2436 .
addReg(SubReg, SubKillState)
2454 MI = RestoreMBB.
end();
2460 for (
unsigned i =
Offset * PVD.PerVGPR,
2469 bool LastSubReg = (i + 1 == e);
2490 bool NeedsCFI =
false;
2491 switch (
MI->getOpcode()) {
2492 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2493 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2494 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2495 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2496 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2497 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2498 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2499 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2500 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2501 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
2504 case AMDGPU::SI_SPILL_S1024_SAVE:
2505 case AMDGPU::SI_SPILL_S512_SAVE:
2506 case AMDGPU::SI_SPILL_S384_SAVE:
2507 case AMDGPU::SI_SPILL_S352_SAVE:
2508 case AMDGPU::SI_SPILL_S320_SAVE:
2509 case AMDGPU::SI_SPILL_S288_SAVE:
2510 case AMDGPU::SI_SPILL_S256_SAVE:
2511 case AMDGPU::SI_SPILL_S224_SAVE:
2512 case AMDGPU::SI_SPILL_S192_SAVE:
2513 case AMDGPU::SI_SPILL_S160_SAVE:
2514 case AMDGPU::SI_SPILL_S128_SAVE:
2515 case AMDGPU::SI_SPILL_S96_SAVE:
2516 case AMDGPU::SI_SPILL_S64_SAVE:
2517 case AMDGPU::SI_SPILL_S32_SAVE:
2518 return spillSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane,
2520 case AMDGPU::SI_SPILL_S1024_RESTORE:
2521 case AMDGPU::SI_SPILL_S512_RESTORE:
2522 case AMDGPU::SI_SPILL_S384_RESTORE:
2523 case AMDGPU::SI_SPILL_S352_RESTORE:
2524 case AMDGPU::SI_SPILL_S320_RESTORE:
2525 case AMDGPU::SI_SPILL_S288_RESTORE:
2526 case AMDGPU::SI_SPILL_S256_RESTORE:
2527 case AMDGPU::SI_SPILL_S224_RESTORE:
2528 case AMDGPU::SI_SPILL_S192_RESTORE:
2529 case AMDGPU::SI_SPILL_S160_RESTORE:
2530 case AMDGPU::SI_SPILL_S128_RESTORE:
2531 case AMDGPU::SI_SPILL_S96_RESTORE:
2532 case AMDGPU::SI_SPILL_S64_RESTORE:
2533 case AMDGPU::SI_SPILL_S32_RESTORE:
2534 return restoreSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane);
2541 int SPAdj,
unsigned FIOperandNum,
2550 assert(SPAdj == 0 &&
"unhandled SP adjustment in call sequence?");
2553 "unreserved scratch RSRC register");
2556 int Index =
MI->getOperand(FIOperandNum).getIndex();
2562 bool NeedsCFI =
false;
2564 switch (
MI->getOpcode()) {
2566 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2567 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2568 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2569 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2570 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2571 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2572 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2573 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2574 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2575 case AMDGPU::SI_SPILL_S32_CFI_SAVE: {
2579 case AMDGPU::SI_SPILL_S1024_SAVE:
2580 case AMDGPU::SI_SPILL_S512_SAVE:
2581 case AMDGPU::SI_SPILL_S384_SAVE:
2582 case AMDGPU::SI_SPILL_S352_SAVE:
2583 case AMDGPU::SI_SPILL_S320_SAVE:
2584 case AMDGPU::SI_SPILL_S288_SAVE:
2585 case AMDGPU::SI_SPILL_S256_SAVE:
2586 case AMDGPU::SI_SPILL_S224_SAVE:
2587 case AMDGPU::SI_SPILL_S192_SAVE:
2588 case AMDGPU::SI_SPILL_S160_SAVE:
2589 case AMDGPU::SI_SPILL_S128_SAVE:
2590 case AMDGPU::SI_SPILL_S96_SAVE:
2591 case AMDGPU::SI_SPILL_S64_SAVE:
2592 case AMDGPU::SI_SPILL_S32_SAVE: {
2599 case AMDGPU::SI_SPILL_S1024_RESTORE:
2600 case AMDGPU::SI_SPILL_S512_RESTORE:
2601 case AMDGPU::SI_SPILL_S384_RESTORE:
2602 case AMDGPU::SI_SPILL_S352_RESTORE:
2603 case AMDGPU::SI_SPILL_S320_RESTORE:
2604 case AMDGPU::SI_SPILL_S288_RESTORE:
2605 case AMDGPU::SI_SPILL_S256_RESTORE:
2606 case AMDGPU::SI_SPILL_S224_RESTORE:
2607 case AMDGPU::SI_SPILL_S192_RESTORE:
2608 case AMDGPU::SI_SPILL_S160_RESTORE:
2609 case AMDGPU::SI_SPILL_S128_RESTORE:
2610 case AMDGPU::SI_SPILL_S96_RESTORE:
2611 case AMDGPU::SI_SPILL_S64_RESTORE:
2612 case AMDGPU::SI_SPILL_S32_RESTORE: {
2614 FrameInfo.getStackID(Index) ==
2619 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
2620 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
2621 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
2622 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
2623 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
2624 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
2625 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
2626 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
2627 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
2628 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
2629 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
2630 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
2631 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
2632 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
2633 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
2634 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
2635 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
2636 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
2637 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
2638 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
2639 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
2640 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
2641 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
2642 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
2643 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
2644 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
2645 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
2646 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
2647 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
2648 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
2649 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
2652 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
2653 case AMDGPU::SI_SPILL_V1024_SAVE:
2654 case AMDGPU::SI_SPILL_V512_SAVE:
2655 case AMDGPU::SI_SPILL_V384_SAVE:
2656 case AMDGPU::SI_SPILL_V352_SAVE:
2657 case AMDGPU::SI_SPILL_V320_SAVE:
2658 case AMDGPU::SI_SPILL_V288_SAVE:
2659 case AMDGPU::SI_SPILL_V256_SAVE:
2660 case AMDGPU::SI_SPILL_V224_SAVE:
2661 case AMDGPU::SI_SPILL_V192_SAVE:
2662 case AMDGPU::SI_SPILL_V160_SAVE:
2663 case AMDGPU::SI_SPILL_V128_SAVE:
2664 case AMDGPU::SI_SPILL_V96_SAVE:
2665 case AMDGPU::SI_SPILL_V64_SAVE:
2666 case AMDGPU::SI_SPILL_V32_SAVE:
2667 case AMDGPU::SI_SPILL_V16_SAVE:
2668 case AMDGPU::SI_SPILL_A1024_SAVE:
2669 case AMDGPU::SI_SPILL_A512_SAVE:
2670 case AMDGPU::SI_SPILL_A384_SAVE:
2671 case AMDGPU::SI_SPILL_A352_SAVE:
2672 case AMDGPU::SI_SPILL_A320_SAVE:
2673 case AMDGPU::SI_SPILL_A288_SAVE:
2674 case AMDGPU::SI_SPILL_A256_SAVE:
2675 case AMDGPU::SI_SPILL_A224_SAVE:
2676 case AMDGPU::SI_SPILL_A192_SAVE:
2677 case AMDGPU::SI_SPILL_A160_SAVE:
2678 case AMDGPU::SI_SPILL_A128_SAVE:
2679 case AMDGPU::SI_SPILL_A96_SAVE:
2680 case AMDGPU::SI_SPILL_A64_SAVE:
2681 case AMDGPU::SI_SPILL_A32_SAVE:
2682 case AMDGPU::SI_SPILL_AV1024_SAVE:
2683 case AMDGPU::SI_SPILL_AV512_SAVE:
2684 case AMDGPU::SI_SPILL_AV384_SAVE:
2685 case AMDGPU::SI_SPILL_AV352_SAVE:
2686 case AMDGPU::SI_SPILL_AV320_SAVE:
2687 case AMDGPU::SI_SPILL_AV288_SAVE:
2688 case AMDGPU::SI_SPILL_AV256_SAVE:
2689 case AMDGPU::SI_SPILL_AV224_SAVE:
2690 case AMDGPU::SI_SPILL_AV192_SAVE:
2691 case AMDGPU::SI_SPILL_AV160_SAVE:
2692 case AMDGPU::SI_SPILL_AV128_SAVE:
2693 case AMDGPU::SI_SPILL_AV96_SAVE:
2694 case AMDGPU::SI_SPILL_AV64_SAVE:
2695 case AMDGPU::SI_SPILL_AV32_SAVE:
2696 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2697 case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
2699 MI->getOpcode() != AMDGPU::SI_BLOCK_SPILL_V1024_SAVE &&
2700 "block spill does not currenty support spilling non-CSR registers");
2702 if (
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE)
2706 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2709 AMDGPU::OpName::vdata);
2711 MI->eraseFromParent();
2715 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2719 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_SAVE) {
2720 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2721 Opc = AMDGPU::SCRATCH_STORE_SHORT_SADDR_t16;
2723 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE
2724 ? AMDGPU::SCRATCH_STORE_BLOCK_SADDR
2725 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2726 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2729 auto *
MBB =
MI->getParent();
2730 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2731 if (IsWWMRegSpill) {
2733 RS->isRegUsed(AMDGPU::SCC));
2737 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2738 *
MI->memoperands_begin(), RS,
nullptr, NeedsCFI);
2743 MI->eraseFromParent();
2746 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE: {
2750 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2753 case AMDGPU::SI_SPILL_V16_RESTORE:
2754 case AMDGPU::SI_SPILL_V32_RESTORE:
2755 case AMDGPU::SI_SPILL_V64_RESTORE:
2756 case AMDGPU::SI_SPILL_V96_RESTORE:
2757 case AMDGPU::SI_SPILL_V128_RESTORE:
2758 case AMDGPU::SI_SPILL_V160_RESTORE:
2759 case AMDGPU::SI_SPILL_V192_RESTORE:
2760 case AMDGPU::SI_SPILL_V224_RESTORE:
2761 case AMDGPU::SI_SPILL_V256_RESTORE:
2762 case AMDGPU::SI_SPILL_V288_RESTORE:
2763 case AMDGPU::SI_SPILL_V320_RESTORE:
2764 case AMDGPU::SI_SPILL_V352_RESTORE:
2765 case AMDGPU::SI_SPILL_V384_RESTORE:
2766 case AMDGPU::SI_SPILL_V512_RESTORE:
2767 case AMDGPU::SI_SPILL_V1024_RESTORE:
2768 case AMDGPU::SI_SPILL_A32_RESTORE:
2769 case AMDGPU::SI_SPILL_A64_RESTORE:
2770 case AMDGPU::SI_SPILL_A96_RESTORE:
2771 case AMDGPU::SI_SPILL_A128_RESTORE:
2772 case AMDGPU::SI_SPILL_A160_RESTORE:
2773 case AMDGPU::SI_SPILL_A192_RESTORE:
2774 case AMDGPU::SI_SPILL_A224_RESTORE:
2775 case AMDGPU::SI_SPILL_A256_RESTORE:
2776 case AMDGPU::SI_SPILL_A288_RESTORE:
2777 case AMDGPU::SI_SPILL_A320_RESTORE:
2778 case AMDGPU::SI_SPILL_A352_RESTORE:
2779 case AMDGPU::SI_SPILL_A384_RESTORE:
2780 case AMDGPU::SI_SPILL_A512_RESTORE:
2781 case AMDGPU::SI_SPILL_A1024_RESTORE:
2782 case AMDGPU::SI_SPILL_AV32_RESTORE:
2783 case AMDGPU::SI_SPILL_AV64_RESTORE:
2784 case AMDGPU::SI_SPILL_AV96_RESTORE:
2785 case AMDGPU::SI_SPILL_AV128_RESTORE:
2786 case AMDGPU::SI_SPILL_AV160_RESTORE:
2787 case AMDGPU::SI_SPILL_AV192_RESTORE:
2788 case AMDGPU::SI_SPILL_AV224_RESTORE:
2789 case AMDGPU::SI_SPILL_AV256_RESTORE:
2790 case AMDGPU::SI_SPILL_AV288_RESTORE:
2791 case AMDGPU::SI_SPILL_AV320_RESTORE:
2792 case AMDGPU::SI_SPILL_AV352_RESTORE:
2793 case AMDGPU::SI_SPILL_AV384_RESTORE:
2794 case AMDGPU::SI_SPILL_AV512_RESTORE:
2795 case AMDGPU::SI_SPILL_AV1024_RESTORE:
2796 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2797 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
2799 AMDGPU::OpName::vdata);
2800 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2804 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_RESTORE) {
2805 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2806 Opc = ST.d16PreservesUnusedBits()
2807 ? AMDGPU::SCRATCH_LOAD_SHORT_D16_SADDR_t16
2808 : AMDGPU::SCRATCH_LOAD_USHORT_SADDR;
2810 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE
2811 ? AMDGPU::SCRATCH_LOAD_BLOCK_SADDR
2812 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2813 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2816 auto *
MBB =
MI->getParent();
2817 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2818 if (IsWWMRegSpill) {
2820 RS->isRegUsed(AMDGPU::SCC));
2825 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2826 *
MI->memoperands_begin(), RS);
2831 MI->eraseFromParent();
2834 case AMDGPU::V_ADD_U32_e32:
2835 case AMDGPU::V_ADD_U32_e64:
2836 case AMDGPU::V_ADD_CO_U32_e32:
2837 case AMDGPU::V_ADD_CO_U32_e64: {
2839 unsigned NumDefs =
MI->getNumExplicitDefs();
2840 unsigned Src0Idx = NumDefs;
2842 bool HasClamp =
false;
2845 switch (
MI->getOpcode()) {
2846 case AMDGPU::V_ADD_U32_e32:
2848 case AMDGPU::V_ADD_U32_e64:
2849 HasClamp =
MI->getOperand(3).getImm();
2851 case AMDGPU::V_ADD_CO_U32_e32:
2852 VCCOp = &
MI->getOperand(3);
2854 case AMDGPU::V_ADD_CO_U32_e64:
2855 VCCOp = &
MI->getOperand(1);
2856 HasClamp =
MI->getOperand(4).getImm();
2861 bool DeadVCC = !VCCOp || VCCOp->
isDead();
2865 unsigned OtherOpIdx =
2866 FIOperandNum == Src0Idx ? FIOperandNum + 1 : Src0Idx;
2869 unsigned Src1Idx = Src0Idx + 1;
2870 Register MaterializedReg = FrameReg;
2873 int64_t
Offset = FrameInfo.getObjectOffset(Index);
2877 if (OtherOp->
isImm()) {
2888 OtherOp->
setImm(TotalOffset);
2892 if (FrameReg && !ST.hasFlatScratchEnabled()) {
2900 ScavengedVGPR = RS->scavengeRegisterBackwards(
2901 AMDGPU::VGPR_32RegClass,
MI,
false, 0);
2907 .
addImm(ST.getWavefrontSizeLog2())
2909 MaterializedReg = ScavengedVGPR;
2912 if ((!OtherOp->
isImm() || OtherOp->
getImm() != 0) && MaterializedReg) {
2913 if (ST.hasFlatScratchEnabled() &&
2914 !
TII->isOperandLegal(*
MI, Src1Idx, OtherOp)) {
2921 if (!ScavengedVGPR) {
2922 ScavengedVGPR = RS->scavengeRegisterBackwards(
2923 AMDGPU::VGPR_32RegClass,
MI,
false,
2927 assert(ScavengedVGPR != DstReg);
2932 MaterializedReg = ScavengedVGPR;
2941 AddI32.
add(
MI->getOperand(1));
2946 if (
isVGPRClass(getPhysRegBaseClass(MaterializedReg))) {
2951 .addReg(MaterializedReg, MaterializedRegFlags);
2956 .addReg(MaterializedReg, MaterializedRegFlags)
2960 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
2961 MI->getOpcode() == AMDGPU::V_ADD_U32_e64)
2964 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e32)
2965 AddI32.setOperandDead(3);
2967 MaterializedReg = DstReg;
2973 }
else if (
Offset != 0) {
2974 assert(!MaterializedReg);
2978 if (DeadVCC && !HasClamp) {
2983 if (OtherOp->
isReg() && OtherOp->
getReg() == DstReg) {
2985 MI->eraseFromParent();
2990 MI->setDesc(
TII->get(AMDGPU::V_MOV_B32_e32));
2991 MI->removeOperand(FIOperandNum);
2993 unsigned NumOps =
MI->getNumOperands();
2994 for (
unsigned I =
NumOps - 2;
I >= NumDefs + 1; --
I)
2995 MI->removeOperand(
I);
2998 MI->removeOperand(1);
3010 if (!
TII->isOperandLegal(*
MI, Src1Idx) &&
TII->commuteInstruction(*
MI)) {
3018 for (
unsigned SrcIdx : {FIOperandNum, OtherOpIdx}) {
3019 if (!
TII->isOperandLegal(*
MI, SrcIdx)) {
3023 if (!ScavengedVGPR) {
3024 ScavengedVGPR = RS->scavengeRegisterBackwards(
3025 AMDGPU::VGPR_32RegClass,
MI,
false,
3029 assert(ScavengedVGPR != DstReg);
3035 Src.ChangeToRegister(ScavengedVGPR,
false);
3036 Src.setIsKill(
true);
3042 if (FIOp->
isImm() && FIOp->
getImm() == 0 && DeadVCC && !HasClamp) {
3043 if (OtherOp->
isReg() && OtherOp->
getReg() != DstReg) {
3047 MI->eraseFromParent();
3052 case AMDGPU::S_ADD_I32:
3053 case AMDGPU::S_ADD_U32: {
3055 unsigned OtherOpIdx = FIOperandNum == 1 ? 2 : 1;
3062 Register MaterializedReg = FrameReg;
3065 bool DeadSCC =
MI->getOperand(3).isDead();
3074 if (FrameReg && !ST.hasFlatScratchEnabled()) {
3079 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3086 .
addImm(ST.getWavefrontSizeLog2())
3089 MaterializedReg = TmpReg;
3092 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3097 if (OtherOp.
isImm()) {
3101 if (MaterializedReg)
3105 }
else if (MaterializedReg) {
3109 if (!TmpReg && MaterializedReg == FrameReg) {
3110 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3124 MaterializedReg = DstReg;
3137 if (DeadSCC && OtherOp.
isImm() && OtherOp.
getImm() == 0) {
3139 MI->removeOperand(3);
3140 MI->removeOperand(OtherOpIdx);
3142 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3143 }
else if (DeadSCC && FIOp->
isImm() && FIOp->
getImm() == 0) {
3145 MI->removeOperand(3);
3146 MI->removeOperand(FIOperandNum);
3148 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3159 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3160 if (ST.hasFlatScratchEnabled()) {
3161 if (
TII->isFLATScratch(*
MI)) {
3163 (int16_t)FIOperandNum ==
3164 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::saddr));
3171 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset);
3182 unsigned Opc =
MI->getOpcode();
3186 }
else if (ST.hasFlatScratchSTMode()) {
3196 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
3197 bool TiedVDst = VDstIn != -1 &&
MI->getOperand(VDstIn).isReg() &&
3198 MI->getOperand(VDstIn).isTied();
3200 MI->untieRegOperand(VDstIn);
3203 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::saddr));
3207 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
3209 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
3210 assert(NewVDst != -1 && NewVDstIn != -1 &&
"Must be tied!");
3211 MI->tieOperands(NewVDst, NewVDstIn);
3213 MI->setDesc(
TII->get(NewOpc));
3221 if (
TII->isImmOperandLegal(*
MI, FIOperandNum, *FIOp))
3228 bool UseSGPR =
TII->isOperandLegal(*
MI, FIOperandNum, FIOp);
3230 if (!
Offset && FrameReg && UseSGPR) {
3236 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3239 RS->scavengeRegisterBackwards(*RC,
MI,
false, 0, !UseSGPR);
3243 if ((!FrameReg || !
Offset) && TmpReg) {
3244 unsigned Opc = UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
3247 MIB.addReg(FrameReg);
3254 bool NeedSaveSCC = (RS->isRegUsed(AMDGPU::SCC) &&
3255 !
MI->definesRegister(AMDGPU::SCC,
nullptr)) ||
3256 MI->readsRegister(AMDGPU::SCC,
nullptr);
3260 : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3261 MI,
false, 0, !UseSGPR);
3263 if (!TmpSReg || (!TmpReg && !UseSGPR)) {
3264 assert(!FrameReg &&
"there is a frame register!");
3266 if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
3267 Register TmpVGPR = RS->scavengeRegisterBackwards(
3268 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3274 int64_t FullOffset =
3276 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3277 auto [ImmOffset, RemainderOffset] =
3281 .
addImm(RemainderOffset);
3283 .
add(
MI->getOperand(0))
3286 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::cpol));
3287 MI->eraseFromParent();
3301 assert(!(
Offset & 0x1) &&
"Flat scratch offset must be aligned!");
3321 if (TmpSReg == FrameReg) {
3324 !
MI->registerDefIsDead(AMDGPU::SCC,
nullptr)) {
3348 bool IsMUBUF =
TII->isMUBUF(*
MI);
3354 bool LiveSCC = RS->isRegUsed(AMDGPU::SCC) &&
3355 !
MI->definesRegister(AMDGPU::SCC,
nullptr);
3357 ? &AMDGPU::SReg_32RegClass
3358 : &AMDGPU::VGPR_32RegClass;
3359 bool IsCopy =
MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
3360 MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
3361 MI->getOpcode() == AMDGPU::S_MOV_B32;
3363 IsCopy ?
MI->getOperand(0).getReg()
3364 : RS->scavengeRegisterBackwards(*RC,
MI,
false, 0);
3366 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3369 IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
3371 if (IsSALU && LiveSCC) {
3372 TmpResultReg = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
3377 if (OpCode == AMDGPU::V_LSHRREV_B32_e64)
3380 Shift.addImm(ST.getWavefrontSizeLog2()).addReg(FrameReg);
3382 Shift.addReg(FrameReg).addImm(ST.getWavefrontSizeLog2());
3383 if (IsSALU && !LiveSCC)
3384 Shift.getInstr()->getOperand(3).setIsDead();
3385 if (IsSALU && LiveSCC) {
3389 NewDest = ResultReg;
3391 NewDest = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3396 ResultReg = NewDest;
3401 if ((MIB =
TII->getAddNoCarry(*
MBB,
MI,
DL, ResultReg, *RS)) !=
3408 .
addImm(ST.getWavefrontSizeLog2())
3411 const bool IsVOP2 = MIB->
getOpcode() == AMDGPU::V_ADD_U32_e32;
3423 "Need to reuse carry out register");
3428 ConstOffsetReg = getSubReg(MIB.
getReg(1), AMDGPU::sub0);
3430 ConstOffsetReg = MIB.
getReg(1);
3441 if (!MIB || IsSALU) {
3448 Register TmpScaledReg = IsCopy && IsSALU
3450 : RS->scavengeRegisterBackwards(
3451 AMDGPU::SReg_32_XM0RegClass,
MI,
3453 Register ScaledReg = TmpScaledReg.
isValid() ? TmpScaledReg : FrameReg;
3459 .
addImm(ST.getWavefrontSizeLog2());
3464 TmpResultReg = RS->scavengeRegisterBackwards(
3465 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3468 if ((
Add =
TII->getAddNoCarry(*
MBB,
MI,
DL, TmpResultReg, *RS))) {
3471 .
addImm(ST.getWavefrontSizeLog2())
3473 if (
Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
3483 "offset is unsafe for v_mad_u32_u24");
3492 bool IsInlinableLiteral =
3494 if (!IsInlinableLiteral) {
3503 if (!IsInlinableLiteral) {
3509 Add.addImm(ST.getWavefrontSize()).addReg(FrameReg).addImm(0);
3512 .
addImm(ST.getWavefrontSizeLog2())
3518 NewDest = ResultReg;
3520 NewDest = RS->scavengeRegisterBackwards(
3521 AMDGPU::SReg_32_XM0RegClass, *
Add,
false, 0,
3528 ResultReg = NewDest;
3534 if (!TmpScaledReg.
isValid()) {
3540 .
addImm(ST.getWavefrontSizeLog2());
3547 MI->eraseFromParent();
3557 static_cast<int>(FIOperandNum) ==
3558 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::vaddr));
3560 auto &SOffset = *
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset);
3561 assert((SOffset.isImm() && SOffset.getImm() == 0));
3563 if (FrameReg != AMDGPU::NoRegister)
3564 SOffset.ChangeToRegister(FrameReg,
false);
3566 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3568 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3569 int64_t NewOffset = OldImm +
Offset;
3571 if (
TII->isLegalMUBUFImmOffset(NewOffset) &&
3573 MI->eraseFromParent();
3582 if (!
TII->isImmOperandLegal(*
MI, FIOperandNum, *FIOp)) {
3584 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
3604 return &AMDGPU::VReg_64RegClass;
3606 return &AMDGPU::VReg_96RegClass;
3608 return &AMDGPU::VReg_128RegClass;
3610 return &AMDGPU::VReg_160RegClass;
3612 return &AMDGPU::VReg_192RegClass;
3614 return &AMDGPU::VReg_224RegClass;
3616 return &AMDGPU::VReg_256RegClass;
3618 return &AMDGPU::VReg_288RegClass;
3620 return &AMDGPU::VReg_320RegClass;
3622 return &AMDGPU::VReg_352RegClass;
3624 return &AMDGPU::VReg_384RegClass;
3626 return &AMDGPU::VReg_512RegClass;
3628 return &AMDGPU::VReg_1024RegClass;
3636 return &AMDGPU::VReg_64_Align2RegClass;
3638 return &AMDGPU::VReg_96_Align2RegClass;
3640 return &AMDGPU::VReg_128_Align2RegClass;
3642 return &AMDGPU::VReg_160_Align2RegClass;
3644 return &AMDGPU::VReg_192_Align2RegClass;
3646 return &AMDGPU::VReg_224_Align2RegClass;
3648 return &AMDGPU::VReg_256_Align2RegClass;
3650 return &AMDGPU::VReg_288_Align2RegClass;
3652 return &AMDGPU::VReg_320_Align2RegClass;
3654 return &AMDGPU::VReg_352_Align2RegClass;
3656 return &AMDGPU::VReg_384_Align2RegClass;
3658 return &AMDGPU::VReg_512_Align2RegClass;
3660 return &AMDGPU::VReg_1024_Align2RegClass;
3668 return &AMDGPU::VReg_1RegClass;
3670 return &AMDGPU::VGPR_16RegClass;
3672 return &AMDGPU::VGPR_32RegClass;
3680 return &AMDGPU::VGPR_32_Lo256RegClass;
3682 return &AMDGPU::VReg_64_Lo256_Align2RegClass;
3684 return &AMDGPU::VReg_96_Lo256_Align2RegClass;
3686 return &AMDGPU::VReg_128_Lo256_Align2RegClass;
3688 return &AMDGPU::VReg_160_Lo256_Align2RegClass;
3690 return &AMDGPU::VReg_192_Lo256_Align2RegClass;
3692 return &AMDGPU::VReg_224_Lo256_Align2RegClass;
3694 return &AMDGPU::VReg_256_Lo256_Align2RegClass;
3696 return &AMDGPU::VReg_288_Lo256_Align2RegClass;
3698 return &AMDGPU::VReg_320_Lo256_Align2RegClass;
3700 return &AMDGPU::VReg_352_Lo256_Align2RegClass;
3702 return &AMDGPU::VReg_384_Lo256_Align2RegClass;
3704 return &AMDGPU::VReg_512_Lo256_Align2RegClass;
3706 return &AMDGPU::VReg_1024_Lo256_Align2RegClass;
3714 return &AMDGPU::AReg_64RegClass;
3716 return &AMDGPU::AReg_96RegClass;
3718 return &AMDGPU::AReg_128RegClass;
3720 return &AMDGPU::AReg_160RegClass;
3722 return &AMDGPU::AReg_192RegClass;
3724 return &AMDGPU::AReg_224RegClass;
3726 return &AMDGPU::AReg_256RegClass;
3728 return &AMDGPU::AReg_288RegClass;
3730 return &AMDGPU::AReg_320RegClass;
3732 return &AMDGPU::AReg_352RegClass;
3734 return &AMDGPU::AReg_384RegClass;
3736 return &AMDGPU::AReg_512RegClass;
3738 return &AMDGPU::AReg_1024RegClass;
3746 return &AMDGPU::AReg_64_Align2RegClass;
3748 return &AMDGPU::AReg_96_Align2RegClass;
3750 return &AMDGPU::AReg_128_Align2RegClass;
3752 return &AMDGPU::AReg_160_Align2RegClass;
3754 return &AMDGPU::AReg_192_Align2RegClass;
3756 return &AMDGPU::AReg_224_Align2RegClass;
3758 return &AMDGPU::AReg_256_Align2RegClass;
3760 return &AMDGPU::AReg_288_Align2RegClass;
3762 return &AMDGPU::AReg_320_Align2RegClass;
3764 return &AMDGPU::AReg_352_Align2RegClass;
3766 return &AMDGPU::AReg_384_Align2RegClass;
3768 return &AMDGPU::AReg_512_Align2RegClass;
3770 return &AMDGPU::AReg_1024_Align2RegClass;
3778 return &AMDGPU::AGPR_LO16RegClass;
3780 return &AMDGPU::AGPR_32RegClass;
3788 return &AMDGPU::AV_64RegClass;
3790 return &AMDGPU::AV_96RegClass;
3792 return &AMDGPU::AV_128RegClass;
3794 return &AMDGPU::AV_160RegClass;
3796 return &AMDGPU::AV_192RegClass;
3798 return &AMDGPU::AV_224RegClass;
3800 return &AMDGPU::AV_256RegClass;
3802 return &AMDGPU::AV_288RegClass;
3804 return &AMDGPU::AV_320RegClass;
3806 return &AMDGPU::AV_352RegClass;
3808 return &AMDGPU::AV_384RegClass;
3810 return &AMDGPU::AV_512RegClass;
3812 return &AMDGPU::AV_1024RegClass;
3820 return &AMDGPU::AV_64_Align2RegClass;
3822 return &AMDGPU::AV_96_Align2RegClass;
3824 return &AMDGPU::AV_128_Align2RegClass;
3826 return &AMDGPU::AV_160_Align2RegClass;
3828 return &AMDGPU::AV_192_Align2RegClass;
3830 return &AMDGPU::AV_224_Align2RegClass;
3832 return &AMDGPU::AV_256_Align2RegClass;
3834 return &AMDGPU::AV_288_Align2RegClass;
3836 return &AMDGPU::AV_320_Align2RegClass;
3838 return &AMDGPU::AV_352_Align2RegClass;
3840 return &AMDGPU::AV_384_Align2RegClass;
3842 return &AMDGPU::AV_512_Align2RegClass;
3844 return &AMDGPU::AV_1024_Align2RegClass;
3852 return &AMDGPU::AV_32RegClass;
3853 return ST.needsAlignedVGPRs()
3872 return &AMDGPU::SReg_32RegClass;
3874 return &AMDGPU::SReg_64RegClass;
3876 return &AMDGPU::SGPR_96RegClass;
3878 return &AMDGPU::SGPR_128RegClass;
3880 return &AMDGPU::SGPR_160RegClass;
3882 return &AMDGPU::SGPR_192RegClass;
3884 return &AMDGPU::SGPR_224RegClass;
3886 return &AMDGPU::SGPR_256RegClass;
3888 return &AMDGPU::SGPR_288RegClass;
3890 return &AMDGPU::SGPR_320RegClass;
3892 return &AMDGPU::SGPR_352RegClass;
3894 return &AMDGPU::SGPR_384RegClass;
3896 return &AMDGPU::SGPR_512RegClass;
3898 return &AMDGPU::SGPR_1024RegClass;
3906 if (Reg.isVirtual())
3909 RC = getPhysRegBaseClass(Reg);
3915 unsigned Size = getRegSizeInBits(*SRC);
3917 switch (SRC->
getID()) {
3920 case AMDGPU::VS_32_Lo256RegClassID:
3921 case AMDGPU::VS_64_Lo256RegClassID:
3927 assert(VRC &&
"Invalid register class size");
3933 unsigned Size = getRegSizeInBits(*SRC);
3935 assert(ARC &&
"Invalid register class size");
3941 unsigned Size = getRegSizeInBits(*SRC);
3943 assert(ARC &&
"Invalid register class size");
3949 unsigned Size = getRegSizeInBits(*VRC);
3951 return &AMDGPU::SGPR_32RegClass;
3953 assert(SRC &&
"Invalid register class size");
3960 unsigned SubIdx)
const {
3963 getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
3964 return MatchRC && MatchRC->
hasSubClassEq(SuperRC) ? MatchRC :
nullptr;
3970 return !ST.hasMFMAInlineLiteralBug();
3991 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::VCC_HI;
3994 if (ReserveHighestRegister) {
4017 unsigned EltSize)
const {
4019 assert(RegBitWidth >= 32 && RegBitWidth <= 1024 && EltSize >= 2);
4021 const unsigned RegHalves = RegBitWidth / 16;
4022 const unsigned EltHalves = EltSize / 2;
4023 assert(RegSplitParts.size() + 1 >= EltHalves);
4025 const std::vector<int16_t> &Parts = RegSplitParts[EltHalves - 1];
4026 const unsigned NumParts = RegHalves / EltHalves;
4028 return ArrayRef(Parts.data(), NumParts);
4034 return Reg.isVirtual() ? MRI.
getRegClass(Reg) : getPhysRegBaseClass(Reg);
4041 return getSubRegisterClass(SrcRC, MO.
getSubReg());
4061 unsigned MinOcc = ST.getOccupancyWithWorkGroupSizes(MF).first;
4062 switch (RC->
getID()) {
4064 return AMDGPUGenRegisterInfo::getRegPressureLimit(RC, MF);
4065 case AMDGPU::VGPR_32RegClassID:
4070 ST.getMaxNumVGPRs(MF));
4071 case AMDGPU::SGPR_32RegClassID:
4072 case AMDGPU::SGPR_LO16RegClassID:
4073 return std::min(ST.getMaxNumSGPRs(MinOcc,
true), ST.getMaxNumSGPRs(MF));
4078 unsigned Idx)
const {
4079 switch (
static_cast<AMDGPU::RegisterPressureSets
>(Idx)) {
4080 case AMDGPU::RegisterPressureSets::VGPR_32:
4081 case AMDGPU::RegisterPressureSets::AGPR_32:
4084 case AMDGPU::RegisterPressureSets::SReg_32:
4093 static const int Empty[] = { -1 };
4095 if (RegPressureIgnoredUnits[
static_cast<unsigned>(RegUnit)])
4098 return AMDGPUGenRegisterInfo::getRegUnitPressureSets(RegUnit);
4113 switch (Hint.first) {
4120 getMatchingSuperReg(Paired, AMDGPU::lo16, &AMDGPU::VGPR_32RegClass);
4121 }
else if (VRM && VRM->
hasPhys(Paired)) {
4122 PairedPhys = getMatchingSuperReg(VRM->
getPhys(Paired), AMDGPU::lo16,
4123 &AMDGPU::VGPR_32RegClass);
4138 PairedPhys =
TRI->getSubReg(Paired, AMDGPU::lo16);
4139 }
else if (VRM && VRM->
hasPhys(Paired)) {
4140 PairedPhys =
TRI->getSubReg(VRM->
getPhys(Paired), AMDGPU::lo16);
4155 if (AMDGPU::VGPR_16RegClass.
contains(PhysReg) &&
4170 return AMDGPU::SGPR30_SGPR31;
4176 switch (RB.
getID()) {
4177 case AMDGPU::VGPRRegBankID:
4179 std::max(ST.useRealTrue16Insts() ? 16u : 32u,
Size));
4180 case AMDGPU::VCCRegBankID:
4183 case AMDGPU::SGPRRegBankID:
4185 case AMDGPU::AGPRRegBankID:
4200 return getAllocatableClass(RC);
4206 return isWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC;
4210 return isWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
4215 return ST.needsAlignedVGPRs() ? &AMDGPU::VReg_64_Align2RegClass
4216 : &AMDGPU::VReg_64RegClass;
4228 if (Reg.isVirtual()) {
4232 LaneBitmask SubLanes = SubReg ? getSubRegIndexLaneMask(SubReg)
4237 if ((S.LaneMask & SubLanes) == SubLanes) {
4238 V = S.getVNInfoAt(UseIdx);
4250 for (MCRegUnit Unit : regunits(Reg.asMCReg())) {
4265 if (!Def || !MDT.dominates(Def, &
Use))
4268 assert(Def->modifiesRegister(Reg,
this));
4274 assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
4277 {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
4278 &AMDGPU::AGPR_32RegClass}) {
4279 if (
MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
4282 if (
MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::hi16,
4283 &AMDGPU::VGPR_32RegClass)) {
4287 return AMDGPU::NoRegister;
4291 if (!ST.needsAlignedVGPRs())
4302 assert(&RC != &AMDGPU::VS_64RegClass);
4309 return ArrayRef(AMDGPU::SGPR_128RegClass.begin(), ST.getMaxNumSGPRs(MF) / 4);
4314 return ArrayRef(AMDGPU::SGPR_64RegClass.begin(), ST.getMaxNumSGPRs(MF) / 2);
4319 return ArrayRef(AMDGPU::SGPR_32RegClass.begin(), ST.getMaxNumSGPRs(MF));
4324 unsigned SubReg)
const {
4327 return std::min(128u, getSubRegIdxSize(SubReg));
4331 return std::min(32u, getSubRegIdxSize(SubReg));
4340 bool IncludeCalls)
const {
4341 unsigned NumArchVGPRs = ST.getAddressableNumArchVGPRs();
4343 (RC.
getID() == AMDGPU::VGPR_32RegClassID)
4347 if (Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file declares the machine register scavenger class.
SI Pre allocate WWM Registers
static MachineInstrBuilder spillVGPRtoAGPR(const GCNSubtarget &ST, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, int Index, unsigned Lane, unsigned ValueReg, bool IsKill, bool NeedsCFI)
static int getOffenMUBUFStore(unsigned Opc)
static const TargetRegisterClass * getAnyAGPRClassForBitWidth(unsigned BitWidth)
static int getOffsetMUBUFLoad(unsigned Opc)
static const std::array< unsigned, 17 > SubRegFromChannelTableWidthMap
static unsigned getNumSubRegsForSpillOp(const MachineInstr &MI, const SIInstrInfo *TII)
static void emitUnsupportedError(const Function &Fn, const MachineInstr &MI, const Twine &ErrMsg)
static const TargetRegisterClass * getAlignedAGPRClassForBitWidth(unsigned BitWidth)
static bool buildMUBUFOffsetLoadStore(const GCNSubtarget &ST, MachineFrameInfo &MFI, MachineBasicBlock::iterator MI, int Index, int64_t Offset)
static cl::opt< bool > EnableSpillCFISavedRegs("amdgpu-spill-cfi-saved-regs", cl::desc("Enable spilling the registers required for CFI emission"), cl::ReallyHidden, cl::init(false), cl::ZeroOrMore)
static unsigned getFlatScratchSpillOpcode(const SIInstrInfo *TII, unsigned LoadStoreOp, unsigned EltSize)
static const TargetRegisterClass * getAlignedVGPRClassForBitWidth(unsigned BitWidth)
static int getOffsetMUBUFStore(unsigned Opc)
static const TargetRegisterClass * getAnyVGPRClassForBitWidth(unsigned BitWidth)
static cl::opt< unsigned > StressSGPRLimit("amdgpu-stress-sgpr", cl::Hidden, cl::init(0), cl::desc("Limit SGPRs to N registers by reserving the rest"))
static cl::opt< bool > EnableSpillSGPRToVGPR("amdgpu-spill-sgpr-to-vgpr", cl::desc("Enable spilling SGPRs to VGPRs"), cl::ReallyHidden, cl::init(true))
static const TargetRegisterClass * getAlignedVectorSuperClassForBitWidth(unsigned BitWidth)
static const TargetRegisterClass * getAnyVectorSuperClassForBitWidth(unsigned BitWidth)
static cl::opt< unsigned > StressAGPRLimit("amdgpu-stress-agpr", cl::Hidden, cl::init(0), cl::desc("Limit AGPRs to N registers by reserving the rest"))
static cl::opt< unsigned > StressVGPRLimit("amdgpu-stress-vgpr", cl::Hidden, cl::init(0), cl::desc("Limit VGPRs to N registers by reserving the rest"))
static bool isFIPlusImmOrVGPR(const SIRegisterInfo &TRI, const MachineInstr &MI)
static int getOffenMUBUFLoad(unsigned Opc)
Interface definition for SIRegisterInfo.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static const char * getRegisterName(MCRegister Reg)
bool isBottomOfStack() const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
bool empty() const
Returns whether there are no bits in this bitvector.
Diagnostic information for unsupported feature in backend.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
bool hasInterval(Register Reg) const
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
MachineDominatorTree & getDomTree()
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
This class represents the liveness of a register, stack slot, etc.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
unsigned getID() const
getID() - Return the register class ID number.
ArrayRef< MCPhysReg > getRegisters() const
const uint8_t TSFlags
Configurable target specific flags.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Generic base class for all target subtargets.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasCalls() const
Return true if the current function has any function calls.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
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
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void setAsmPrinterFlag(AsmPrinterFlagTy Flag)
Set a flag for the AsmPrinter.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
void setImm(int64_t immVal)
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
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.
void setIsKill(bool Val=true)
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.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
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.
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
std::pair< unsigned, Register > getRegAllocationHint(Register VReg) const
getRegAllocationHint - Return the register allocation hint for the specified virtual register.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Holds all the information related to register banks.
virtual bool isDivergentRegBank(const RegisterBank *RB) const
Returns true if the register bank is considered divergent.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
MachineInstr * buildCFIForSGPRToVMEMSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister SGPR, int64_t Offset) const
Create a CFI index describing a spill of a SGPR to VMEM and build a MachineInstr around it.
MachineInstr * buildCFIForVRegToVRegSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCRegister Reg, const MCRegister RegCopy) const
Create a CFI index describing a spill of the VGPR/AGPR Reg to another VGPR/AGPR RegCopy and build a M...
MachineInstr * buildCFIForVGPRToVMEMSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister VGPR, int64_t Offset) const
Create a CFI index describing a spill of a VGPR to VMEM and build a MachineInstr around it.
MachineInstr * buildCFIForSGPRToVGPRSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCRegister SGPR, const MCRegister VGPR, const int Lane) const
Create a CFI index describing a spill of an SGPR to a single lane of a VGPR and build a MachineInstr ...
static bool isFLATScratch(const MachineInstr &MI)
static bool isMUBUF(const MachineInstr &MI)
static bool isVOP3(const MCInstrDesc &Desc)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
MCPhysReg getVGPRToAGPRSpill(int FrameIndex, unsigned Lane) const
Register getLongBranchReservedReg() const
unsigned getDynamicVGPRBlockSize() const
Register getStackPtrOffsetReg() const
Register getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses.
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToVirtualVGPRLanes(int FrameIndex) const
uint32_t getMaskForVGPRBlockOps(Register RegisterBlock) const
Register getSGPRForEXECCopy() const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToPhysicalVGPRLanes(int FrameIndex) const
Register getVGPRForAGPRCopy() const
Register getFrameOffsetReg() const
BitVector getNonWWMRegMask() const
bool checkFlag(Register Reg, uint8_t Flag) const
void addToSpilledVGPRs(unsigned num)
const ReservedRegSet & getWWMReservedRegs() const
void addToSpilledSGPRs(unsigned num)
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
int64_t getScratchInstrOffset(const MachineInstr *MI) const
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
const TargetRegisterClass * getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, const TargetRegisterClass *SubRC, unsigned SubIdx) const
Returns a register class which is compatible with SuperRC, such that a subregister exists with class ...
ArrayRef< MCPhysReg > getAllSGPR64(const MachineFunction &MF) const
Return all SGPR64 which satisfy the waves per execution unit requirement of the subtarget.
MCRegister findUnusedRegister(const MachineRegisterInfo &MRI, const TargetRegisterClass *RC, const MachineFunction &MF, bool ReserveHighestVGPR=false) const
Returns a lowest register that is not used at any point in the function.
static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs=1)
MCPhysReg get32BitRegister(MCPhysReg Reg) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
void buildSpillLoadStore(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned LoadStoreOp, int Index, Register ValueReg, bool ValueIsKill, MCRegister ScratchOffsetReg, int64_t InstrOffset, MachineMemOperand *MMO, RegScavenger *RS, LiveRegUnits *LiveUnits=nullptr, bool NeedsCFI=false) const
bool requiresFrameIndexReplacementScavenging(const MachineFunction &MF) const override
bool shouldRealignStack(const MachineFunction &MF) const override
bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool OnlyToVGPR=false, bool SpillToPhysVGPRLane=false) const
bool isProperlyAlignedRC(const TargetRegisterClass &RC) const
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
Register getFrameRegister(const MachineFunction &MF) const override
LLVM_READONLY const TargetRegisterClass * getVectorSuperClassForBitWidth(unsigned BitWidth) const
bool spillEmergencySGPR(MachineBasicBlock::iterator MI, MachineBasicBlock &RestoreMBB, Register SGPR, RegScavenger *RS) const
SIRegisterInfo(const GCNSubtarget &ST)
const uint32_t * getAllVGPRRegMask() const
MCRegister getReturnAddressReg(const MachineFunction &MF) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
bool hasBasePointer(const MachineFunction &MF) const
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
Returns a legal register class to copy a register in the specified class to or from.
ArrayRef< int16_t > getRegSplitParts(const TargetRegisterClass *RC, unsigned EltSize) const
ArrayRef< MCPhysReg > getAllSGPR32(const MachineFunction &MF) const
Return all SGPR32 which satisfy the waves per execution unit requirement of the subtarget.
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const
Return the end register initially reserved for the scratch buffer in case spilling is needed.
bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool SpillToPhysVGPRLane=false) const
Special case of eliminateFrameIndex.
bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
LLVM_READONLY const TargetRegisterClass * getAGPRClassForBitWidth(unsigned BitWidth) const
static bool isChainScratchRegister(Register VGPR)
bool requiresRegisterScavenging(const MachineFunction &Fn) const override
bool opCanUseInlineConstant(unsigned OpType) const
const TargetRegisterClass * getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const
const TargetRegisterClass * getConstrainedRegClassForOperand(const MachineOperand &MO, const MachineRegisterInfo &MRI) const override
bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI, Register Reg) const override
const uint32_t * getNoPreservedMask() const override
StringRef getRegAsmName(MCRegister Reg) const override
const uint32_t * getAllAllocatableSRegMask() const
MCRegister getAlignedHighSGPRForRC(const MachineFunction &MF, const unsigned Align, const TargetRegisterClass *RC) const
Return the largest available SGPR aligned to Align for the register class RC.
void buildCFIForBlockCSRStore(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register BlockReg, int64_t Offset) const
const TargetRegisterClass * getRegClassForReg(const MachineRegisterInfo &MRI, Register Reg) const
unsigned getHWRegIndex(MCRegister Reg) const
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
const uint32_t * getAllVectorRegMask() const
const TargetRegisterClass * getEquivalentAGPRClass(const TargetRegisterClass *SRC) const
static LLVM_READONLY const TargetRegisterClass * getSGPRClassForBitWidth(unsigned BitWidth)
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
const TargetRegisterClass * getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const
bool opCanUseLiteralConstant(unsigned OpType) const
Register getBaseRegister() const
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
LLVM_READONLY const TargetRegisterClass * getAlignedLo256VGPRClassForBitWidth(unsigned BitWidth) const
LLVM_READONLY const TargetRegisterClass * getVGPRClassForBitWidth(unsigned BitWidth) const
const TargetRegisterClass * getEquivalentAVClass(const TargetRegisterClass *SRC) const
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
static bool isVGPRClass(const TargetRegisterClass *RC)
MachineInstr * findReachingDef(Register Reg, unsigned SubReg, MachineInstr &Use, MachineRegisterInfo &MRI, LiveIntervals *LIS) const
bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const
const TargetRegisterClass * getEquivalentSGPRClass(const TargetRegisterClass *VRC) const
SmallVector< StringLiteral > getVRegFlagsOfReg(Register Reg, const MachineFunction &MF) const override
LLVM_READONLY const TargetRegisterClass * getDefaultVectorSuperClassForBitWidth(unsigned BitWidth) const
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
ArrayRef< MCPhysReg > getAllSGPR128(const MachineFunction &MF) const
Return all SGPR128 which satisfy the waves per execution unit requirement of the subtarget.
unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
const TargetRegisterClass * getRegClassForOperandReg(const MachineRegisterInfo &MRI, const MachineOperand &MO) const
void addImplicitUsesForBlockCSRLoad(MachineInstrBuilder &MIB, Register BlockReg) const
unsigned getNumUsedPhysRegs(const MachineRegisterInfo &MRI, const TargetRegisterClass &RC, bool IncludeCalls=true) const
const uint32_t * getAllAGPRRegMask() const
const int * getRegUnitPressureSets(MCRegUnit RegUnit) const override
bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool OnlyToVGPR=false, bool SpillToPhysVGPRLane=false, bool NeedsCFI=false) const
If OnlyToVGPR is true, this will only succeed if this manages to find a free VGPR lane to spill.
MCRegister getExec() const
MCRegister getVCC() const
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
bool isVectorSuperClass(const TargetRegisterClass *RC) const
const TargetRegisterClass * getWaveMaskRegClass() const
unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC, unsigned SubReg) const
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override
const TargetRegisterClass * getVGPR64Class() const
void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset, bool IsLoad, bool IsKill=true) const
bool isCFISavedRegsSpillEnabled() const
static bool isSGPRClass(const TargetRegisterClass *RC)
static bool isAGPRClass(const TargetRegisterClass *RC)
SlotIndex - An opaque wrapper around machine indexes.
bool isValid() const
Returns true if this is a valid index.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
SlotIndex replaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in maps used by register allocat...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const
Returns the largest super class of RC that is legal to use in the current sub-target and has the same...
virtual bool shouldRealignStack(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
VNInfo - Value Number Information.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ PRIVATE_ADDRESS
Address space for private memory.
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
@ OPERAND_REG_INLINE_AC_FIRST
@ OPERAND_REG_INLINE_AC_LAST
LLVM_READONLY int32_t getFlatScratchInstSVfromSVS(uint32_t Opcode)
LLVM_READONLY int32_t getFlatScratchInstSVfromSS(uint32_t Opcode)
LLVM_READONLY int32_t getFlatScratchInstSTfromSS(uint32_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
@ Renamable
Register that may be renamed.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
auto reverse(ContainerTy &&C)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr bool hasRegState(RegState Value, RegState Test)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
void call_once(once_flag &flag, Function &&F, Args &&... ArgList)
Execute the function specified as a parameter once.
constexpr unsigned BitWidth
static const MachineMemOperand::Flags MOLastUse
Mark the MMO of a load as the last use.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
static const MachineMemOperand::Flags MOThreadPrivate
Mark the MMO of accesses to memory locations that are never written to by other threads.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
void setMI(MachineBasicBlock *NewMBB, MachineBasicBlock::iterator NewMI)
ArrayRef< int16_t > SplitParts
SIMachineFunctionInfo & MFI
SGPRSpillBuilder(const SIRegisterInfo &TRI, const SIInstrInfo &TII, bool IsWave32, MachineBasicBlock::iterator MI, int Index, RegScavenger *RS)
SGPRSpillBuilder(const SIRegisterInfo &TRI, const SIInstrInfo &TII, bool IsWave32, MachineBasicBlock::iterator MI, Register Reg, bool IsKill, int Index, RegScavenger *RS)
PerVGPRData getPerVGPRData()
MachineBasicBlock::iterator MI
void readWriteTmpVGPR(unsigned Offset, bool IsLoad)
const SIRegisterInfo & TRI
The llvm::once_flag structure.