26#define GET_REGINFO_TARGET_DESC
27#include "AMDGPUGenRegisterInfo.inc"
30 "amdgpu-spill-sgpr-to-vgpr",
31 cl::desc(
"Enable spilling SGPRs to VGPRs"),
36 "amdgpu-spill-cfi-saved-regs",
37 cl::desc(
"Enable spilling the registers required for CFI emission"),
42 cl::desc(
"Limit VGPRs to N registers by reserving the rest"));
46 cl::desc(
"Limit AGPRs to N registers by reserving the rest"));
50 cl::desc(
"Limit SGPRs to N registers by reserving the rest"));
52std::array<std::vector<int16_t>, 32> SIRegisterInfo::RegSplitParts;
53std::array<std::array<uint16_t, 32>, 9> SIRegisterInfo::SubRegFromChannelTable;
60 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 9};
63 const Twine &ErrMsg) {
136 MI->getOperand(0).isKill(),
Index,
RS) {}
151 MovOpc = AMDGPU::S_MOV_B32;
152 NotOpc = AMDGPU::S_NOT_B32;
155 MovOpc = AMDGPU::S_MOV_B64;
156 NotOpc = AMDGPU::S_NOT_B64;
161 SuperReg != AMDGPU::EXEC &&
"exec should never spill");
192 assert(
RS &&
"Cannot spill SGPR to memory without RegScavenger");
193 TmpVGPR =
RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false,
221 IsWave32 ? AMDGPU::SGPR_32RegClass : AMDGPU::SGPR_64RegClass;
241 if (
RS->isRegUsed(AMDGPU::SCC))
243 "unhandled SGPR spill to memory");
253 I->getOperand(2).setIsDead();
288 I->getOperand(2).setIsDead();
317 if (
RS->isRegUsed(AMDGPU::SCC))
319 "unhandled SGPR spill to memory");
344 ST.getAMDGPUDwarfFlavour(),
349 assert(getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() == 3 &&
350 getSubRegIndexLaneMask(AMDGPU::sub31).getAsInteger() == (3ULL << 62) &&
351 (getSubRegIndexLaneMask(AMDGPU::lo16) |
352 getSubRegIndexLaneMask(AMDGPU::hi16)).getAsInteger() ==
353 getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() &&
354 "getNumCoveredRegs() will not work with generated subreg masks!");
356 RegPressureIgnoredUnits.resize(getNumRegUnits());
357 RegPressureIgnoredUnits.set(
359 for (
auto Reg : AMDGPU::VGPR_16RegClass) {
361 RegPressureIgnoredUnits.set(
362 static_cast<unsigned>(*regunits(Reg).begin()));
368 static auto InitializeRegSplitPartsOnce = [
this]() {
369 for (
unsigned Idx = 1, E = getNumSubRegIndices() - 1; Idx < E; ++Idx) {
370 unsigned Size = getSubRegIdxSize(Idx);
373 std::vector<int16_t> &Vec = RegSplitParts[
Size / 16 - 1];
374 unsigned Pos = getSubRegIdxOffset(Idx);
379 unsigned MaxNumParts = 1024 /
Size;
380 Vec.resize(MaxNumParts);
388 static auto InitializeSubRegFromChannelTableOnce = [
this]() {
389 for (
auto &Row : SubRegFromChannelTable)
390 Row.fill(AMDGPU::NoSubRegister);
391 for (
unsigned Idx = 1; Idx < getNumSubRegIndices(); ++Idx) {
392 unsigned Width = getSubRegIdxSize(Idx) / 32;
393 unsigned Offset = getSubRegIdxOffset(Idx) / 32;
398 unsigned TableIdx = Width - 1;
399 assert(TableIdx < SubRegFromChannelTable.size());
401 SubRegFromChannelTable[TableIdx][
Offset] = Idx;
405 llvm::call_once(InitializeRegSplitPartsFlag, InitializeRegSplitPartsOnce);
407 InitializeSubRegFromChannelTableOnce);
424 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_SaveList
425 : CSR_AMDGPU_SaveList;
428 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_SaveList
429 : CSR_AMDGPU_SI_Gfx_SaveList;
431 return CSR_AMDGPU_CS_ChainPreserve_SaveList;
434 static const MCPhysReg NoCalleeSavedReg = AMDGPU::NoRegister;
435 return &NoCalleeSavedReg;
451 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_RegMask
452 : CSR_AMDGPU_RegMask;
455 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_RegMask
456 : CSR_AMDGPU_SI_Gfx_RegMask;
461 return AMDGPU_AllVGPRs_RegMask;
468 return CSR_AMDGPU_NoRegs_RegMask;
472 return VGPR >= AMDGPU::VGPR0 && VGPR < AMDGPU::VGPR8;
483 if (RC == &AMDGPU::VGPR_32RegClass || RC == &AMDGPU::AGPR_32RegClass)
484 return &AMDGPU::AV_32RegClass;
485 if (RC == &AMDGPU::VReg_64RegClass || RC == &AMDGPU::AReg_64RegClass)
486 return &AMDGPU::AV_64RegClass;
487 if (RC == &AMDGPU::VReg_64_Align2RegClass ||
488 RC == &AMDGPU::AReg_64_Align2RegClass)
489 return &AMDGPU::AV_64_Align2RegClass;
490 if (RC == &AMDGPU::VReg_96RegClass || RC == &AMDGPU::AReg_96RegClass)
491 return &AMDGPU::AV_96RegClass;
492 if (RC == &AMDGPU::VReg_96_Align2RegClass ||
493 RC == &AMDGPU::AReg_96_Align2RegClass)
494 return &AMDGPU::AV_96_Align2RegClass;
495 if (RC == &AMDGPU::VReg_128RegClass || RC == &AMDGPU::AReg_128RegClass)
496 return &AMDGPU::AV_128RegClass;
497 if (RC == &AMDGPU::VReg_128_Align2RegClass ||
498 RC == &AMDGPU::AReg_128_Align2RegClass)
499 return &AMDGPU::AV_128_Align2RegClass;
500 if (RC == &AMDGPU::VReg_160RegClass || RC == &AMDGPU::AReg_160RegClass)
501 return &AMDGPU::AV_160RegClass;
502 if (RC == &AMDGPU::VReg_160_Align2RegClass ||
503 RC == &AMDGPU::AReg_160_Align2RegClass)
504 return &AMDGPU::AV_160_Align2RegClass;
505 if (RC == &AMDGPU::VReg_192RegClass || RC == &AMDGPU::AReg_192RegClass)
506 return &AMDGPU::AV_192RegClass;
507 if (RC == &AMDGPU::VReg_192_Align2RegClass ||
508 RC == &AMDGPU::AReg_192_Align2RegClass)
509 return &AMDGPU::AV_192_Align2RegClass;
510 if (RC == &AMDGPU::VReg_256RegClass || RC == &AMDGPU::AReg_256RegClass)
511 return &AMDGPU::AV_256RegClass;
512 if (RC == &AMDGPU::VReg_256_Align2RegClass ||
513 RC == &AMDGPU::AReg_256_Align2RegClass)
514 return &AMDGPU::AV_256_Align2RegClass;
515 if (RC == &AMDGPU::VReg_512RegClass || RC == &AMDGPU::AReg_512RegClass)
516 return &AMDGPU::AV_512RegClass;
517 if (RC == &AMDGPU::VReg_512_Align2RegClass ||
518 RC == &AMDGPU::AReg_512_Align2RegClass)
519 return &AMDGPU::AV_512_Align2RegClass;
520 if (RC == &AMDGPU::VReg_1024RegClass || RC == &AMDGPU::AReg_1024RegClass)
521 return &AMDGPU::AV_1024RegClass;
522 if (RC == &AMDGPU::VReg_1024_Align2RegClass ||
523 RC == &AMDGPU::AReg_1024_Align2RegClass)
524 return &AMDGPU::AV_1024_Align2RegClass;
554 return AMDGPU_AllVGPRs_RegMask;
558 return AMDGPU_AllAGPRs_RegMask;
562 return AMDGPU_AllVectorRegs_RegMask;
566 return AMDGPU_AllAllocatableSRegs_RegMask;
573 assert(NumRegIndex &&
"Not implemented");
574 assert(Channel < SubRegFromChannelTable[NumRegIndex - 1].
size());
575 return SubRegFromChannelTable[NumRegIndex - 1][Channel];
584 const unsigned Align,
587 MCRegister BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx));
588 return getMatchingSuperReg(BaseReg, AMDGPU::sub0, RC);
606 reserveRegisterTuples(
Reserved, AMDGPU::EXEC);
607 reserveRegisterTuples(
Reserved, AMDGPU::FLAT_SCR);
610 reserveRegisterTuples(
Reserved, AMDGPU::M0);
613 reserveRegisterTuples(
Reserved, AMDGPU::SRC_VCCZ);
614 reserveRegisterTuples(
Reserved, AMDGPU::SRC_EXECZ);
615 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SCC);
618 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_BASE);
619 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_LIMIT);
620 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_BASE);
621 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_LIMIT);
622 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_LO);
623 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_HI);
626 reserveRegisterTuples(
Reserved, AMDGPU::ASYNCcnt);
627 reserveRegisterTuples(
Reserved, AMDGPU::TENSORcnt);
630 reserveRegisterTuples(
Reserved, AMDGPU::SRC_POPS_EXITING_WAVE_ID);
633 reserveRegisterTuples(
Reserved, AMDGPU::XNACK_MASK);
636 reserveRegisterTuples(
Reserved, AMDGPU::LDS_DIRECT);
639 reserveRegisterTuples(
Reserved, AMDGPU::TBA);
640 reserveRegisterTuples(
Reserved, AMDGPU::TMA);
641 reserveRegisterTuples(
Reserved, AMDGPU::TTMP0_TTMP1);
642 reserveRegisterTuples(
Reserved, AMDGPU::TTMP2_TTMP3);
643 reserveRegisterTuples(
Reserved, AMDGPU::TTMP4_TTMP5);
644 reserveRegisterTuples(
Reserved, AMDGPU::TTMP6_TTMP7);
645 reserveRegisterTuples(
Reserved, AMDGPU::TTMP8_TTMP9);
646 reserveRegisterTuples(
Reserved, AMDGPU::TTMP10_TTMP11);
647 reserveRegisterTuples(
Reserved, AMDGPU::TTMP12_TTMP13);
648 reserveRegisterTuples(
Reserved, AMDGPU::TTMP14_TTMP15);
651 reserveRegisterTuples(
Reserved, AMDGPU::SGPR_NULL64);
655 unsigned MaxNumSGPRs = ST.getMaxNumSGPRs(MF);
658 unsigned TotalNumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
661 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
664 if (Index + NumRegs > MaxNumSGPRs && Index < TotalNumSGPRs &&
665 Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
673 if (ScratchRSrcReg != AMDGPU::NoRegister) {
677 reserveRegisterTuples(
Reserved, ScratchRSrcReg);
681 if (LongBranchReservedReg)
682 reserveRegisterTuples(
Reserved, LongBranchReservedReg);
689 reserveRegisterTuples(
Reserved, StackPtrReg);
690 assert(!isSubRegister(ScratchRSrcReg, StackPtrReg));
695 reserveRegisterTuples(
Reserved, FrameReg);
696 assert(!isSubRegister(ScratchRSrcReg, FrameReg));
701 reserveRegisterTuples(
Reserved, BasePtrReg);
702 assert(!isSubRegister(ScratchRSrcReg, BasePtrReg));
709 reserveRegisterTuples(
Reserved, ExecCopyReg);
713 auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.
getFunction());
723 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
726 if (Index + NumRegs > MaxNumVGPRs)
733 if (!ST.hasMAIInsts())
737 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
740 if (Index + NumRegs > MaxNumAGPRs)
748 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
756 if (!PerLaneVGPRMask.
empty()) {
757 for (
unsigned RegI = AMDGPU::VGPR0, RegE = AMDGPU::VGPR0 + MaxNumVGPRs;
758 RegI < RegE; ++RegI) {
759 if (PerLaneVGPRMask.
test(RegI))
760 reserveRegisterTuples(
Reserved, RegI);
765 reserveRegisterTuples(
Reserved, Reg);
769 reserveRegisterTuples(
Reserved, Reg);
772 reserveRegisterTuples(
Reserved, Reg);
789 if (Info->isBottomOfStack())
797 if (Info->isEntryFunction()) {
830 int OffIdx = AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
831 AMDGPU::OpName::offset);
832 return MI->getOperand(OffIdx).getImm();
837 switch (
MI->getOpcode()) {
838 case AMDGPU::V_ADD_U32_e32:
839 case AMDGPU::V_ADD_U32_e64:
840 case AMDGPU::V_ADD_CO_U32_e32: {
841 int OtherIdx = Idx == 1 ? 2 : 1;
845 case AMDGPU::V_ADD_CO_U32_e64: {
846 int OtherIdx = Idx == 2 ? 3 : 2;
857 assert((Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
858 AMDGPU::OpName::vaddr) ||
859 (Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
860 AMDGPU::OpName::saddr))) &&
861 "Should never see frame index on non-address operand");
873 return Src1.
isImm() || (Src1.
isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
878 return Src0.
isImm() || (Src0.
isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
887 switch (
MI->getOpcode()) {
888 case AMDGPU::V_ADD_U32_e32: {
891 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e32) < 2 &&
896 case AMDGPU::V_ADD_U32_e64:
906 return !ST.hasFlatScratchEnabled();
907 case AMDGPU::V_ADD_CO_U32_e32:
908 if (ST.getConstantBusLimit(AMDGPU::V_ADD_CO_U32_e32) < 2 &&
913 return MI->getOperand(3).isDead();
914 case AMDGPU::V_ADD_CO_U32_e64:
916 return MI->getOperand(1).isDead();
928 return !
TII->isLegalMUBUFImmOffset(FullOffset);
940 if (Ins !=
MBB->end())
941 DL = Ins->getDebugLoc();
947 ST.hasFlatScratchEnabled() ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
950 ST.hasFlatScratchEnabled() ? &AMDGPU::SReg_32_XEXEC_HIRegClass
951 : &AMDGPU::VGPR_32RegClass);
962 ? &AMDGPU::SReg_32_XM0RegClass
963 : &AMDGPU::VGPR_32RegClass);
970 if (ST.hasFlatScratchEnabled()) {
979 TII->getAddNoCarry(*
MBB, Ins,
DL, BaseReg)
991 switch (
MI.getOpcode()) {
992 case AMDGPU::V_ADD_U32_e32:
993 case AMDGPU::V_ADD_CO_U32_e32: {
999 if (!ImmOp->
isImm()) {
1002 TII->legalizeOperandsVOP2(
MI.getMF()->getRegInfo(),
MI);
1007 if (TotalOffset == 0) {
1008 MI.setDesc(
TII->get(AMDGPU::COPY));
1009 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
1010 MI.removeOperand(
I);
1012 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
1016 ImmOp->
setImm(TotalOffset);
1031 MI.getOperand(2).ChangeToRegister(BaseRegVGPR,
false);
1033 MI.getOperand(2).ChangeToRegister(BaseReg,
false);
1037 case AMDGPU::V_ADD_U32_e64:
1038 case AMDGPU::V_ADD_CO_U32_e64: {
1039 int Src0Idx =
MI.getNumExplicitDefs();
1045 if (!ImmOp->
isImm()) {
1047 TII->legalizeOperandsVOP3(
MI.getMF()->getRegInfo(),
MI);
1052 if (TotalOffset == 0) {
1053 MI.setDesc(
TII->get(AMDGPU::COPY));
1055 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
1056 MI.removeOperand(
I);
1058 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
1061 ImmOp->
setImm(TotalOffset);
1070 bool IsFlat =
TII->isFLATScratch(
MI);
1074 bool SeenFI =
false;
1086 TII->getNamedOperand(
MI, IsFlat ? AMDGPU::OpName::saddr
1087 : AMDGPU::OpName::vaddr);
1092 assert(FIOp && FIOp->
isFI() &&
"frame index must be address operand");
1098 "offset should be legal");
1109 assert(
TII->isLegalMUBUFImmOffset(NewOffset) &&
"offset should be legal");
1119 switch (
MI->getOpcode()) {
1120 case AMDGPU::V_ADD_U32_e32:
1121 case AMDGPU::V_ADD_CO_U32_e32:
1123 case AMDGPU::V_ADD_U32_e64:
1124 case AMDGPU::V_ADD_CO_U32_e64:
1137 return TII->isLegalMUBUFImmOffset(NewOffset);
1145 return RC == &AMDGPU::SCC_CLASSRegClass ? &AMDGPU::SReg_32RegClass : RC;
1151 unsigned Op =
MI.getOpcode();
1153 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
1154 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
1155 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE:
1160 (
uint64_t)
TII->getNamedOperand(
MI, AMDGPU::OpName::mask)->getImm());
1161 case AMDGPU::SI_SPILL_S1024_SAVE:
1162 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
1163 case AMDGPU::SI_SPILL_S1024_RESTORE:
1164 case AMDGPU::SI_SPILL_V1024_SAVE:
1165 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
1166 case AMDGPU::SI_SPILL_V1024_RESTORE:
1167 case AMDGPU::SI_SPILL_A1024_SAVE:
1168 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
1169 case AMDGPU::SI_SPILL_A1024_RESTORE:
1170 case AMDGPU::SI_SPILL_AV1024_SAVE:
1171 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
1172 case AMDGPU::SI_SPILL_AV1024_RESTORE:
1174 case AMDGPU::SI_SPILL_S512_SAVE:
1175 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
1176 case AMDGPU::SI_SPILL_S512_RESTORE:
1177 case AMDGPU::SI_SPILL_V512_SAVE:
1178 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
1179 case AMDGPU::SI_SPILL_V512_RESTORE:
1180 case AMDGPU::SI_SPILL_A512_SAVE:
1181 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
1182 case AMDGPU::SI_SPILL_A512_RESTORE:
1183 case AMDGPU::SI_SPILL_AV512_SAVE:
1184 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
1185 case AMDGPU::SI_SPILL_AV512_RESTORE:
1187 case AMDGPU::SI_SPILL_S384_SAVE:
1188 case AMDGPU::SI_SPILL_S384_RESTORE:
1189 case AMDGPU::SI_SPILL_V384_SAVE:
1190 case AMDGPU::SI_SPILL_V384_RESTORE:
1191 case AMDGPU::SI_SPILL_A384_SAVE:
1192 case AMDGPU::SI_SPILL_A384_RESTORE:
1193 case AMDGPU::SI_SPILL_AV384_SAVE:
1194 case AMDGPU::SI_SPILL_AV384_RESTORE:
1196 case AMDGPU::SI_SPILL_S352_SAVE:
1197 case AMDGPU::SI_SPILL_S352_RESTORE:
1198 case AMDGPU::SI_SPILL_V352_SAVE:
1199 case AMDGPU::SI_SPILL_V352_RESTORE:
1200 case AMDGPU::SI_SPILL_A352_SAVE:
1201 case AMDGPU::SI_SPILL_A352_RESTORE:
1202 case AMDGPU::SI_SPILL_AV352_SAVE:
1203 case AMDGPU::SI_SPILL_AV352_RESTORE:
1205 case AMDGPU::SI_SPILL_S320_SAVE:
1206 case AMDGPU::SI_SPILL_S320_RESTORE:
1207 case AMDGPU::SI_SPILL_V320_SAVE:
1208 case AMDGPU::SI_SPILL_V320_RESTORE:
1209 case AMDGPU::SI_SPILL_A320_SAVE:
1210 case AMDGPU::SI_SPILL_A320_RESTORE:
1211 case AMDGPU::SI_SPILL_AV320_SAVE:
1212 case AMDGPU::SI_SPILL_AV320_RESTORE:
1214 case AMDGPU::SI_SPILL_S288_SAVE:
1215 case AMDGPU::SI_SPILL_S288_RESTORE:
1216 case AMDGPU::SI_SPILL_V288_SAVE:
1217 case AMDGPU::SI_SPILL_V288_RESTORE:
1218 case AMDGPU::SI_SPILL_A288_SAVE:
1219 case AMDGPU::SI_SPILL_A288_RESTORE:
1220 case AMDGPU::SI_SPILL_AV288_SAVE:
1221 case AMDGPU::SI_SPILL_AV288_RESTORE:
1223 case AMDGPU::SI_SPILL_S256_SAVE:
1224 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
1225 case AMDGPU::SI_SPILL_S256_RESTORE:
1226 case AMDGPU::SI_SPILL_V256_SAVE:
1227 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
1228 case AMDGPU::SI_SPILL_V256_RESTORE:
1229 case AMDGPU::SI_SPILL_A256_SAVE:
1230 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
1231 case AMDGPU::SI_SPILL_A256_RESTORE:
1232 case AMDGPU::SI_SPILL_AV256_SAVE:
1233 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
1234 case AMDGPU::SI_SPILL_AV256_RESTORE:
1236 case AMDGPU::SI_SPILL_S224_SAVE:
1237 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
1238 case AMDGPU::SI_SPILL_S224_RESTORE:
1239 case AMDGPU::SI_SPILL_V224_SAVE:
1240 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
1241 case AMDGPU::SI_SPILL_V224_RESTORE:
1242 case AMDGPU::SI_SPILL_A224_SAVE:
1243 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
1244 case AMDGPU::SI_SPILL_A224_RESTORE:
1245 case AMDGPU::SI_SPILL_AV224_SAVE:
1246 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
1247 case AMDGPU::SI_SPILL_AV224_RESTORE:
1249 case AMDGPU::SI_SPILL_S192_SAVE:
1250 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
1251 case AMDGPU::SI_SPILL_S192_RESTORE:
1252 case AMDGPU::SI_SPILL_V192_SAVE:
1253 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
1254 case AMDGPU::SI_SPILL_V192_RESTORE:
1255 case AMDGPU::SI_SPILL_A192_SAVE:
1256 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
1257 case AMDGPU::SI_SPILL_A192_RESTORE:
1258 case AMDGPU::SI_SPILL_AV192_SAVE:
1259 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
1260 case AMDGPU::SI_SPILL_AV192_RESTORE:
1262 case AMDGPU::SI_SPILL_S160_SAVE:
1263 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
1264 case AMDGPU::SI_SPILL_S160_RESTORE:
1265 case AMDGPU::SI_SPILL_V160_SAVE:
1266 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
1267 case AMDGPU::SI_SPILL_V160_RESTORE:
1268 case AMDGPU::SI_SPILL_A160_SAVE:
1269 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
1270 case AMDGPU::SI_SPILL_A160_RESTORE:
1271 case AMDGPU::SI_SPILL_AV160_SAVE:
1272 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
1273 case AMDGPU::SI_SPILL_AV160_RESTORE:
1275 case AMDGPU::SI_SPILL_S128_SAVE:
1276 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
1277 case AMDGPU::SI_SPILL_S128_RESTORE:
1278 case AMDGPU::SI_SPILL_V128_SAVE:
1279 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
1280 case AMDGPU::SI_SPILL_V128_RESTORE:
1281 case AMDGPU::SI_SPILL_A128_SAVE:
1282 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
1283 case AMDGPU::SI_SPILL_A128_RESTORE:
1284 case AMDGPU::SI_SPILL_AV128_SAVE:
1285 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
1286 case AMDGPU::SI_SPILL_AV128_RESTORE:
1288 case AMDGPU::SI_SPILL_S96_SAVE:
1289 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
1290 case AMDGPU::SI_SPILL_S96_RESTORE:
1291 case AMDGPU::SI_SPILL_V96_SAVE:
1292 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
1293 case AMDGPU::SI_SPILL_V96_RESTORE:
1294 case AMDGPU::SI_SPILL_A96_SAVE:
1295 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
1296 case AMDGPU::SI_SPILL_A96_RESTORE:
1297 case AMDGPU::SI_SPILL_AV96_SAVE:
1298 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
1299 case AMDGPU::SI_SPILL_AV96_RESTORE:
1301 case AMDGPU::SI_SPILL_S64_SAVE:
1302 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
1303 case AMDGPU::SI_SPILL_S64_RESTORE:
1304 case AMDGPU::SI_SPILL_V64_SAVE:
1305 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
1306 case AMDGPU::SI_SPILL_V64_RESTORE:
1307 case AMDGPU::SI_SPILL_A64_SAVE:
1308 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
1309 case AMDGPU::SI_SPILL_A64_RESTORE:
1310 case AMDGPU::SI_SPILL_AV64_SAVE:
1311 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
1312 case AMDGPU::SI_SPILL_AV64_RESTORE:
1314 case AMDGPU::SI_SPILL_S32_SAVE:
1315 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
1316 case AMDGPU::SI_SPILL_S32_RESTORE:
1317 case AMDGPU::SI_SPILL_V32_SAVE:
1318 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
1319 case AMDGPU::SI_SPILL_V32_RESTORE:
1320 case AMDGPU::SI_SPILL_A32_SAVE:
1321 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
1322 case AMDGPU::SI_SPILL_A32_RESTORE:
1323 case AMDGPU::SI_SPILL_AV32_SAVE:
1324 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
1325 case AMDGPU::SI_SPILL_AV32_RESTORE:
1326 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
1327 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1328 case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1329 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
1330 case AMDGPU::SI_SPILL_V16_SAVE:
1331 case AMDGPU::SI_SPILL_V16_RESTORE:
1339 case AMDGPU::BUFFER_STORE_DWORD_OFFEN:
1340 return AMDGPU::BUFFER_STORE_DWORD_OFFSET;
1341 case AMDGPU::BUFFER_STORE_BYTE_OFFEN:
1342 return AMDGPU::BUFFER_STORE_BYTE_OFFSET;
1343 case AMDGPU::BUFFER_STORE_SHORT_OFFEN:
1344 return AMDGPU::BUFFER_STORE_SHORT_OFFSET;
1345 case AMDGPU::BUFFER_STORE_DWORDX2_OFFEN:
1346 return AMDGPU::BUFFER_STORE_DWORDX2_OFFSET;
1347 case AMDGPU::BUFFER_STORE_DWORDX3_OFFEN:
1348 return AMDGPU::BUFFER_STORE_DWORDX3_OFFSET;
1349 case AMDGPU::BUFFER_STORE_DWORDX4_OFFEN:
1350 return AMDGPU::BUFFER_STORE_DWORDX4_OFFSET;
1351 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN:
1352 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET;
1353 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN:
1354 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET;
1362 case AMDGPU::BUFFER_LOAD_DWORD_OFFEN:
1363 return AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
1364 case AMDGPU::BUFFER_LOAD_UBYTE_OFFEN:
1365 return AMDGPU::BUFFER_LOAD_UBYTE_OFFSET;
1366 case AMDGPU::BUFFER_LOAD_SBYTE_OFFEN:
1367 return AMDGPU::BUFFER_LOAD_SBYTE_OFFSET;
1368 case AMDGPU::BUFFER_LOAD_USHORT_OFFEN:
1369 return AMDGPU::BUFFER_LOAD_USHORT_OFFSET;
1370 case AMDGPU::BUFFER_LOAD_SSHORT_OFFEN:
1371 return AMDGPU::BUFFER_LOAD_SSHORT_OFFSET;
1372 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN:
1373 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET;
1374 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN:
1375 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET;
1376 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN:
1377 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET;
1378 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN:
1379 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET;
1380 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN:
1381 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET;
1382 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN:
1383 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET;
1384 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN:
1385 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET;
1386 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN:
1387 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET;
1388 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN:
1389 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET;
1397 case AMDGPU::BUFFER_STORE_DWORD_OFFSET:
1398 return AMDGPU::BUFFER_STORE_DWORD_OFFEN;
1399 case AMDGPU::BUFFER_STORE_BYTE_OFFSET:
1400 return AMDGPU::BUFFER_STORE_BYTE_OFFEN;
1401 case AMDGPU::BUFFER_STORE_SHORT_OFFSET:
1402 return AMDGPU::BUFFER_STORE_SHORT_OFFEN;
1403 case AMDGPU::BUFFER_STORE_DWORDX2_OFFSET:
1404 return AMDGPU::BUFFER_STORE_DWORDX2_OFFEN;
1405 case AMDGPU::BUFFER_STORE_DWORDX3_OFFSET:
1406 return AMDGPU::BUFFER_STORE_DWORDX3_OFFEN;
1407 case AMDGPU::BUFFER_STORE_DWORDX4_OFFSET:
1408 return AMDGPU::BUFFER_STORE_DWORDX4_OFFEN;
1409 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET:
1410 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN;
1411 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET:
1412 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN;
1420 case AMDGPU::BUFFER_LOAD_DWORD_OFFSET:
1421 return AMDGPU::BUFFER_LOAD_DWORD_OFFEN;
1422 case AMDGPU::BUFFER_LOAD_UBYTE_OFFSET:
1423 return AMDGPU::BUFFER_LOAD_UBYTE_OFFEN;
1424 case AMDGPU::BUFFER_LOAD_SBYTE_OFFSET:
1425 return AMDGPU::BUFFER_LOAD_SBYTE_OFFEN;
1426 case AMDGPU::BUFFER_LOAD_USHORT_OFFSET:
1427 return AMDGPU::BUFFER_LOAD_USHORT_OFFEN;
1428 case AMDGPU::BUFFER_LOAD_SSHORT_OFFSET:
1429 return AMDGPU::BUFFER_LOAD_SSHORT_OFFEN;
1430 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET:
1431 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN;
1432 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET:
1433 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN;
1434 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET:
1435 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN;
1436 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET:
1437 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN;
1438 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET:
1439 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN;
1440 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET:
1441 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN;
1442 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET:
1443 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN;
1444 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET:
1445 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN;
1446 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET:
1447 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN;
1456 unsigned ValueReg,
bool IsKill,
bool NeedsCFI) {
1464 if (
Reg == AMDGPU::NoRegister)
1467 bool IsStore =
MI->mayStore();
1471 unsigned Dst = IsStore ?
Reg : ValueReg;
1472 unsigned Src = IsStore ? ValueReg :
Reg;
1473 bool IsVGPR =
TRI->isVGPR(MRI,
Reg);
1475 if (IsVGPR ==
TRI->isVGPR(MRI, ValueReg)) {
1487 unsigned Opc = (IsStore ^ IsVGPR) ? AMDGPU::V_ACCVGPR_WRITE_B32_e64
1488 : AMDGPU::V_ACCVGPR_READ_B32_e64;
1508 bool IsStore =
MI->mayStore();
1510 unsigned Opc =
MI->getOpcode();
1511 int LoadStoreOp = IsStore ?
1513 if (LoadStoreOp == -1)
1524 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::srsrc))
1525 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset))
1532 AMDGPU::OpName::vdata_in);
1534 NewMI.
add(*VDataIn);
1539 unsigned LoadStoreOp,
1541 bool IsStore =
TII->get(LoadStoreOp).mayStore();
1547 if (
TII->isBlockLoadStore(LoadStoreOp))
1552 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
1553 : AMDGPU::SCRATCH_LOAD_DWORD_SADDR;
1556 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX2_SADDR
1557 : AMDGPU::SCRATCH_LOAD_DWORDX2_SADDR;
1560 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX3_SADDR
1561 : AMDGPU::SCRATCH_LOAD_DWORDX3_SADDR;
1564 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX4_SADDR
1565 : AMDGPU::SCRATCH_LOAD_DWORDX4_SADDR;
1581 unsigned LoadStoreOp,
int Index,
Register ValueReg,
bool IsKill,
1584 assert((!RS || !LiveUnits) &&
"Only RS or LiveUnits can be set but not both");
1593 bool IsStore =
Desc->mayStore();
1594 bool IsFlat =
TII->isFLATScratch(LoadStoreOp);
1595 bool IsBlock =
TII->isBlockLoadStore(LoadStoreOp);
1597 bool CanClobberSCC =
false;
1598 bool Scavenged =
false;
1603 const bool IsAGPR = !ST.hasGFX90AInsts() &&
isAGPRClass(RC);
1614 bool IsRegMisaligned =
false;
1615 if (!IsBlock && !IsAGPR && RegWidth > 4 && IsFlat) {
1616 unsigned SpillOpcode =
1619 IsStore ? AMDGPU::getNamedOperandIdx(SpillOpcode, AMDGPU::OpName::vdata)
1622 TII->getRegClass(
TII->get(SpillOpcode), VDataIdx);
1623 if (!ExpectedRC->
contains(ValueReg)) {
1627 getMatchingSuperRegClass(RC, ExpectedRC, SubIdx);
1628 if (!MatchRC || !MatchRC->
contains(ValueReg))
1629 IsRegMisaligned =
true;
1633 if (IsRegMisaligned)
1638 unsigned EltSize = IsBlock ? RegWidth
1639 : (IsFlat && !IsAGPR) ? std::min(RegWidth, 16u)
1641 unsigned NumSubRegs = RegWidth / EltSize;
1642 unsigned Size = NumSubRegs * EltSize;
1643 unsigned RemSize = RegWidth -
Size;
1644 unsigned NumRemSubRegs = RemSize ? 1 : 0;
1646 if (IsRegMisaligned)
1649 int64_t MaterializedOffset =
Offset;
1654 int64_t MaxOffset =
Offset +
Size - (RemSize ? 0 : EltSize);
1655 int64_t ScratchOffsetRegDelta = 0;
1656 int64_t AdditionalCFIOffset = 0;
1658 if (IsFlat && EltSize > 4) {
1660 Desc = &
TII->get(LoadStoreOp);
1667 "unexpected VGPR spill offset");
1674 bool UseVGPROffset =
false;
1681 if (IsFlat && SGPRBase) {
1686 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) >= 2) {
1705 bool IsOffsetLegal =
1708 :
TII->isLegalMUBUFImmOffset(MaxOffset);
1709 if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
1717 SOffset = RS->scavengeRegisterBackwards(AMDGPU::SGPR_32RegClass,
MI,
false, 0,
false);
1720 CanClobberSCC = !RS->isRegUsed(AMDGPU::SCC);
1721 }
else if (LiveUnits) {
1722 CanClobberSCC = LiveUnits->
available(AMDGPU::SCC);
1723 for (
MCRegister Reg : AMDGPU::SGPR_32RegClass) {
1731 if (ScratchOffsetReg != AMDGPU::NoRegister && !CanClobberSCC)
1735 UseVGPROffset =
true;
1738 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1741 for (
MCRegister Reg : AMDGPU::VGPR_32RegClass) {
1743 TmpOffsetVGPR = Reg;
1750 }
else if (!SOffset && CanClobberSCC) {
1761 if (!ScratchOffsetReg)
1763 SOffset = ScratchOffsetReg;
1764 ScratchOffsetRegDelta =
Offset;
1769 AdditionalCFIOffset =
Offset;
1773 if (!IsFlat && !UseVGPROffset)
1774 Offset *= ST.getWavefrontSize();
1776 if (!UseVGPROffset && !SOffset)
1779 if (UseVGPROffset) {
1781 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR,
Offset);
1782 }
else if (ScratchOffsetReg == AMDGPU::NoRegister) {
1787 .
addReg(ScratchOffsetReg)
1789 Add->getOperand(3).setIsDead();
1795 if (IsFlat && SOffset == AMDGPU::NoRegister) {
1796 assert(AMDGPU::getNamedOperandIdx(LoadStoreOp, AMDGPU::OpName::vaddr) < 0
1797 &&
"Unexpected vaddr for flat scratch with a FI operand");
1799 if (UseVGPROffset) {
1802 assert(ST.hasFlatScratchSTMode());
1803 assert(!
TII->isBlockLoadStore(LoadStoreOp) &&
"Block ops don't have ST");
1807 Desc = &
TII->get(LoadStoreOp);
1812 unsigned OrigEltSize = EltSize;
1813 for (
unsigned i = 0, e = NumSubRegs + NumRemSubRegs, RegOffset = 0; i != e;
1814 ++i, RegOffset += EltSize) {
1815 if (IsRegMisaligned) {
1823 IsRegMisaligned =
false;
1824 EltSize = OrigEltSize;
1828 if (i == NumSubRegs) {
1832 Desc = &
TII->get(LoadStoreOp);
1834 if (!IsFlat && UseVGPROffset) {
1837 Desc = &
TII->get(NewLoadStoreOp);
1840 if (UseVGPROffset && TmpOffsetVGPR == TmpIntermediateVGPR) {
1847 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, MaterializedOffset);
1850 unsigned NumRegs = EltSize / 4;
1858 const bool IsLastSubReg = i + 1 == e;
1859 const bool IsFirstSubReg = i == 0;
1868 bool NeedSuperRegDef = e > 1 && IsStore && IsFirstSubReg;
1869 bool NeedSuperRegImpOperand = e > 1;
1873 unsigned RemEltSize = EltSize;
1881 for (
int LaneS = (RegOffset + EltSize) / 4 - 1, Lane = LaneS,
1882 LaneE = RegOffset / 4;
1883 Lane >= LaneE; --Lane) {
1884 bool IsSubReg = e > 1 || EltSize > 4;
1890 if (!MIB.getInstr())
1892 if (NeedSuperRegDef || (IsSubReg && IsStore && Lane == LaneS && IsFirstSubReg)) {
1894 NeedSuperRegDef =
false;
1896 if ((IsSubReg || NeedSuperRegImpOperand) && (IsFirstSubReg || IsLastSubReg)) {
1897 NeedSuperRegImpOperand =
true;
1899 if (!IsLastSubReg || (Lane != LaneE))
1901 if (!IsFirstSubReg || (Lane != LaneS))
1911 if (RemEltSize != EltSize) {
1912 assert(IsFlat && EltSize > 4);
1914 unsigned NumRegs = RemEltSize / 4;
1915 SubReg =
Register(getSubReg(ValueReg,
1921 unsigned FinalReg = SubReg;
1926 if (!TmpIntermediateVGPR) {
1932 TII->get(AMDGPU::V_ACCVGPR_READ_B32_e64),
1933 TmpIntermediateVGPR)
1935 if (NeedSuperRegDef)
1937 if (NeedSuperRegImpOperand && (IsFirstSubReg || IsLastSubReg))
1941 SubReg = TmpIntermediateVGPR;
1942 }
else if (UseVGPROffset) {
1943 if (!TmpOffsetVGPR) {
1944 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
1946 RS->setRegUsed(TmpOffsetVGPR);
1951 if (LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_SADDR ||
1952 LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_ST) {
1956 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1972 if (UseVGPROffset) {
1981 if (SOffset == AMDGPU::NoRegister) {
1983 if (UseVGPROffset && ScratchOffsetReg) {
1984 MIB.addReg(ScratchOffsetReg);
1991 MIB.addReg(SOffset, SOffsetRegState);
2001 MIB.addMemOperand(NewMMO);
2003 if (FinalValueReg != ValueReg) {
2005 ValueReg = getSubReg(ValueReg, AMDGPU::lo16);
2011 ValueReg = FinalValueReg;
2014 if (IsStore && NeedsCFI) {
2015 if (
TII->isBlockLoadStore(LoadStoreOp)) {
2017 "expected whole register block to be treated as single element");
2022 (
Offset + RegOffset) * ST.getWavefrontSize() + AdditionalCFIOffset);
2026 if (!IsAGPR && NeedSuperRegDef)
2029 if (!IsStore && IsAGPR && TmpIntermediateVGPR != AMDGPU::NoRegister) {
2037 bool PartialReloadCopy = (RemEltSize != EltSize) && !IsStore;
2038 if (NeedSuperRegImpOperand &&
2039 (IsFirstSubReg || (IsLastSubReg && !IsSrcDstDef))) {
2041 if (PartialReloadCopy)
2066 if (!IsStore &&
MI !=
MBB.end() &&
MI->isReturn() &&
2067 MI->readsRegister(SubReg,
this)) {
2069 MIB->tieOperands(0, MIB->getNumOperands() - 1);
2077 if (!IsStore &&
TII->isBlockLoadStore(LoadStoreOp))
2081 if (ScratchOffsetRegDelta != 0) {
2085 .
addImm(-ScratchOffsetRegDelta);
2094 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2095 for (
unsigned RegOffset = 1; RegOffset < 32; ++RegOffset)
2096 if (!(Mask & (1 << RegOffset)) &&
2097 isCalleeSavedPhysReg(BaseVGPR + RegOffset, *MF))
2108 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2109 for (
unsigned RegOffset = 0; RegOffset < 32; ++RegOffset) {
2110 Register VGPR = BaseVGPR + RegOffset;
2111 if (Mask & (1 << RegOffset)) {
2112 assert(isCalleeSavedPhysReg(VGPR, *MF));
2113 ST.getFrameLowering()->buildCFIForVGPRToVMEMSpill(
2115 (
Offset + RegOffset) * ST.getWavefrontSize());
2116 }
else if (isCalleeSavedPhysReg(VGPR, *MF)) {
2121 BaseVGPR + RegOffset);
2128 bool IsKill)
const {
2138 Align Alignment = FrameInfo.getObjectAlign(Index);
2145 unsigned Opc = ST.hasFlatScratchEnabled()
2146 ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2147 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2151 unsigned Opc = ST.hasFlatScratchEnabled()
2152 ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2153 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2164 bool SpillToPhysVGPRLane,
bool NeedsCFI)
const {
2165 assert(!
MI->getOperand(0).isUndef() &&
2166 "undef spill should have been deleted earlier");
2173 bool SpillToVGPR = !VGPRSpills.
empty();
2174 if (OnlyToVGPR && !SpillToVGPR)
2189 "Num of SGPRs spilled should be less than or equal to num of "
2192 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2199 bool IsFirstSubreg = i == 0;
2201 bool UseKill = SB.
IsKill && IsLastSubreg;
2207 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), Spill.VGPR)
2217 AMDGPU::PC_REG, VGPRSpills);
2220 Spill.VGPR, Spill.Lane);
2240 if (SB.
NumSubRegs > 1 && (IsFirstSubreg || IsLastSubreg))
2260 for (
unsigned i =
Offset * PVD.PerVGPR,
2270 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), SB.
TmpVGPR)
2271 .
addReg(SubReg, SubKillState)
2302 ST.getWavefrontSize();
2304 AMDGPU::PC_REG, CFIOffset);
2313 MI->eraseFromParent();
2325 bool SpillToPhysVGPRLane)
const {
2331 bool SpillToVGPR = !VGPRSpills.
empty();
2332 if (OnlyToVGPR && !SpillToVGPR)
2336 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2344 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2367 for (
unsigned i =
Offset * PVD.PerVGPR,
2375 bool LastSubReg = (i + 1 == e);
2377 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2394 MI->eraseFromParent();
2414 for (
unsigned i =
Offset * PVD.PerVGPR,
2425 .
addReg(SubReg, SubKillState)
2443 MI = RestoreMBB.
end();
2449 for (
unsigned i =
Offset * PVD.PerVGPR,
2458 bool LastSubReg = (i + 1 == e);
2479 bool NeedsCFI =
false;
2480 switch (
MI->getOpcode()) {
2481 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2482 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2483 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2484 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2485 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2486 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2487 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2488 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2489 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2490 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
2493 case AMDGPU::SI_SPILL_S1024_SAVE:
2494 case AMDGPU::SI_SPILL_S512_SAVE:
2495 case AMDGPU::SI_SPILL_S384_SAVE:
2496 case AMDGPU::SI_SPILL_S352_SAVE:
2497 case AMDGPU::SI_SPILL_S320_SAVE:
2498 case AMDGPU::SI_SPILL_S288_SAVE:
2499 case AMDGPU::SI_SPILL_S256_SAVE:
2500 case AMDGPU::SI_SPILL_S224_SAVE:
2501 case AMDGPU::SI_SPILL_S192_SAVE:
2502 case AMDGPU::SI_SPILL_S160_SAVE:
2503 case AMDGPU::SI_SPILL_S128_SAVE:
2504 case AMDGPU::SI_SPILL_S96_SAVE:
2505 case AMDGPU::SI_SPILL_S64_SAVE:
2506 case AMDGPU::SI_SPILL_S32_SAVE:
2507 return spillSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane,
2509 case AMDGPU::SI_SPILL_S1024_RESTORE:
2510 case AMDGPU::SI_SPILL_S512_RESTORE:
2511 case AMDGPU::SI_SPILL_S384_RESTORE:
2512 case AMDGPU::SI_SPILL_S352_RESTORE:
2513 case AMDGPU::SI_SPILL_S320_RESTORE:
2514 case AMDGPU::SI_SPILL_S288_RESTORE:
2515 case AMDGPU::SI_SPILL_S256_RESTORE:
2516 case AMDGPU::SI_SPILL_S224_RESTORE:
2517 case AMDGPU::SI_SPILL_S192_RESTORE:
2518 case AMDGPU::SI_SPILL_S160_RESTORE:
2519 case AMDGPU::SI_SPILL_S128_RESTORE:
2520 case AMDGPU::SI_SPILL_S96_RESTORE:
2521 case AMDGPU::SI_SPILL_S64_RESTORE:
2522 case AMDGPU::SI_SPILL_S32_RESTORE:
2523 return restoreSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane);
2545 int SPAdj,
unsigned FIOperandNum,
2554 assert(SPAdj == 0 &&
"unhandled SP adjustment in call sequence?");
2557 "unreserved scratch RSRC register");
2560 int Index =
MI->getOperand(FIOperandNum).getIndex();
2566 bool NeedsCFI =
false;
2568 switch (
MI->getOpcode()) {
2570 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2571 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2572 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2573 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2574 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2575 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2576 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2577 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2578 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2579 case AMDGPU::SI_SPILL_S32_CFI_SAVE: {
2583 case AMDGPU::SI_SPILL_S1024_SAVE:
2584 case AMDGPU::SI_SPILL_S512_SAVE:
2585 case AMDGPU::SI_SPILL_S384_SAVE:
2586 case AMDGPU::SI_SPILL_S352_SAVE:
2587 case AMDGPU::SI_SPILL_S320_SAVE:
2588 case AMDGPU::SI_SPILL_S288_SAVE:
2589 case AMDGPU::SI_SPILL_S256_SAVE:
2590 case AMDGPU::SI_SPILL_S224_SAVE:
2591 case AMDGPU::SI_SPILL_S192_SAVE:
2592 case AMDGPU::SI_SPILL_S160_SAVE:
2593 case AMDGPU::SI_SPILL_S128_SAVE:
2594 case AMDGPU::SI_SPILL_S96_SAVE:
2595 case AMDGPU::SI_SPILL_S64_SAVE:
2596 case AMDGPU::SI_SPILL_S32_SAVE: {
2603 case AMDGPU::SI_SPILL_S1024_RESTORE:
2604 case AMDGPU::SI_SPILL_S512_RESTORE:
2605 case AMDGPU::SI_SPILL_S384_RESTORE:
2606 case AMDGPU::SI_SPILL_S352_RESTORE:
2607 case AMDGPU::SI_SPILL_S320_RESTORE:
2608 case AMDGPU::SI_SPILL_S288_RESTORE:
2609 case AMDGPU::SI_SPILL_S256_RESTORE:
2610 case AMDGPU::SI_SPILL_S224_RESTORE:
2611 case AMDGPU::SI_SPILL_S192_RESTORE:
2612 case AMDGPU::SI_SPILL_S160_RESTORE:
2613 case AMDGPU::SI_SPILL_S128_RESTORE:
2614 case AMDGPU::SI_SPILL_S96_RESTORE:
2615 case AMDGPU::SI_SPILL_S64_RESTORE:
2616 case AMDGPU::SI_SPILL_S32_RESTORE: {
2618 FrameInfo.getStackID(Index) ==
2623 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
2624 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
2625 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
2626 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
2627 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
2628 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
2629 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
2630 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
2631 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
2632 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
2633 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
2634 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
2635 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
2636 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
2637 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
2638 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
2639 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
2640 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
2641 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
2642 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
2643 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
2644 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
2645 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
2646 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
2647 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
2648 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
2649 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
2650 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
2651 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
2652 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
2653 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
2656 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
2657 case AMDGPU::SI_SPILL_V1024_SAVE:
2658 case AMDGPU::SI_SPILL_V512_SAVE:
2659 case AMDGPU::SI_SPILL_V384_SAVE:
2660 case AMDGPU::SI_SPILL_V352_SAVE:
2661 case AMDGPU::SI_SPILL_V320_SAVE:
2662 case AMDGPU::SI_SPILL_V288_SAVE:
2663 case AMDGPU::SI_SPILL_V256_SAVE:
2664 case AMDGPU::SI_SPILL_V224_SAVE:
2665 case AMDGPU::SI_SPILL_V192_SAVE:
2666 case AMDGPU::SI_SPILL_V160_SAVE:
2667 case AMDGPU::SI_SPILL_V128_SAVE:
2668 case AMDGPU::SI_SPILL_V96_SAVE:
2669 case AMDGPU::SI_SPILL_V64_SAVE:
2670 case AMDGPU::SI_SPILL_V32_SAVE:
2671 case AMDGPU::SI_SPILL_V16_SAVE:
2672 case AMDGPU::SI_SPILL_A1024_SAVE:
2673 case AMDGPU::SI_SPILL_A512_SAVE:
2674 case AMDGPU::SI_SPILL_A384_SAVE:
2675 case AMDGPU::SI_SPILL_A352_SAVE:
2676 case AMDGPU::SI_SPILL_A320_SAVE:
2677 case AMDGPU::SI_SPILL_A288_SAVE:
2678 case AMDGPU::SI_SPILL_A256_SAVE:
2679 case AMDGPU::SI_SPILL_A224_SAVE:
2680 case AMDGPU::SI_SPILL_A192_SAVE:
2681 case AMDGPU::SI_SPILL_A160_SAVE:
2682 case AMDGPU::SI_SPILL_A128_SAVE:
2683 case AMDGPU::SI_SPILL_A96_SAVE:
2684 case AMDGPU::SI_SPILL_A64_SAVE:
2685 case AMDGPU::SI_SPILL_A32_SAVE:
2686 case AMDGPU::SI_SPILL_AV1024_SAVE:
2687 case AMDGPU::SI_SPILL_AV512_SAVE:
2688 case AMDGPU::SI_SPILL_AV384_SAVE:
2689 case AMDGPU::SI_SPILL_AV352_SAVE:
2690 case AMDGPU::SI_SPILL_AV320_SAVE:
2691 case AMDGPU::SI_SPILL_AV288_SAVE:
2692 case AMDGPU::SI_SPILL_AV256_SAVE:
2693 case AMDGPU::SI_SPILL_AV224_SAVE:
2694 case AMDGPU::SI_SPILL_AV192_SAVE:
2695 case AMDGPU::SI_SPILL_AV160_SAVE:
2696 case AMDGPU::SI_SPILL_AV128_SAVE:
2697 case AMDGPU::SI_SPILL_AV96_SAVE:
2698 case AMDGPU::SI_SPILL_AV64_SAVE:
2699 case AMDGPU::SI_SPILL_AV32_SAVE:
2700 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2701 case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
2703 MI->getOpcode() != AMDGPU::SI_BLOCK_SPILL_V1024_SAVE &&
2704 "block spill does not currenty support spilling non-CSR registers");
2706 if (
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE)
2710 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2713 AMDGPU::OpName::vdata);
2715 MI->eraseFromParent();
2719 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2723 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_SAVE) {
2724 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2725 Opc = AMDGPU::SCRATCH_STORE_SHORT_SADDR_t16;
2727 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE
2728 ? AMDGPU::SCRATCH_STORE_BLOCK_SADDR
2729 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2730 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2733 auto *
MBB =
MI->getParent();
2734 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2735 if (IsWWMRegSpill) {
2737 RS->isRegUsed(AMDGPU::SCC));
2741 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2742 *
MI->memoperands_begin(), RS,
nullptr, NeedsCFI);
2747 MI->eraseFromParent();
2750 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE: {
2754 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2757 case AMDGPU::SI_SPILL_V16_RESTORE:
2758 case AMDGPU::SI_SPILL_V32_RESTORE:
2759 case AMDGPU::SI_SPILL_V64_RESTORE:
2760 case AMDGPU::SI_SPILL_V96_RESTORE:
2761 case AMDGPU::SI_SPILL_V128_RESTORE:
2762 case AMDGPU::SI_SPILL_V160_RESTORE:
2763 case AMDGPU::SI_SPILL_V192_RESTORE:
2764 case AMDGPU::SI_SPILL_V224_RESTORE:
2765 case AMDGPU::SI_SPILL_V256_RESTORE:
2766 case AMDGPU::SI_SPILL_V288_RESTORE:
2767 case AMDGPU::SI_SPILL_V320_RESTORE:
2768 case AMDGPU::SI_SPILL_V352_RESTORE:
2769 case AMDGPU::SI_SPILL_V384_RESTORE:
2770 case AMDGPU::SI_SPILL_V512_RESTORE:
2771 case AMDGPU::SI_SPILL_V1024_RESTORE:
2772 case AMDGPU::SI_SPILL_A32_RESTORE:
2773 case AMDGPU::SI_SPILL_A64_RESTORE:
2774 case AMDGPU::SI_SPILL_A96_RESTORE:
2775 case AMDGPU::SI_SPILL_A128_RESTORE:
2776 case AMDGPU::SI_SPILL_A160_RESTORE:
2777 case AMDGPU::SI_SPILL_A192_RESTORE:
2778 case AMDGPU::SI_SPILL_A224_RESTORE:
2779 case AMDGPU::SI_SPILL_A256_RESTORE:
2780 case AMDGPU::SI_SPILL_A288_RESTORE:
2781 case AMDGPU::SI_SPILL_A320_RESTORE:
2782 case AMDGPU::SI_SPILL_A352_RESTORE:
2783 case AMDGPU::SI_SPILL_A384_RESTORE:
2784 case AMDGPU::SI_SPILL_A512_RESTORE:
2785 case AMDGPU::SI_SPILL_A1024_RESTORE:
2786 case AMDGPU::SI_SPILL_AV32_RESTORE:
2787 case AMDGPU::SI_SPILL_AV64_RESTORE:
2788 case AMDGPU::SI_SPILL_AV96_RESTORE:
2789 case AMDGPU::SI_SPILL_AV128_RESTORE:
2790 case AMDGPU::SI_SPILL_AV160_RESTORE:
2791 case AMDGPU::SI_SPILL_AV192_RESTORE:
2792 case AMDGPU::SI_SPILL_AV224_RESTORE:
2793 case AMDGPU::SI_SPILL_AV256_RESTORE:
2794 case AMDGPU::SI_SPILL_AV288_RESTORE:
2795 case AMDGPU::SI_SPILL_AV320_RESTORE:
2796 case AMDGPU::SI_SPILL_AV352_RESTORE:
2797 case AMDGPU::SI_SPILL_AV384_RESTORE:
2798 case AMDGPU::SI_SPILL_AV512_RESTORE:
2799 case AMDGPU::SI_SPILL_AV1024_RESTORE:
2800 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2801 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
2803 AMDGPU::OpName::vdata);
2804 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2808 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_RESTORE) {
2809 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2810 Opc = ST.d16PreservesUnusedBits()
2811 ? AMDGPU::SCRATCH_LOAD_SHORT_D16_SADDR_t16
2812 : AMDGPU::SCRATCH_LOAD_USHORT_SADDR;
2814 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE
2815 ? AMDGPU::SCRATCH_LOAD_BLOCK_SADDR
2816 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2817 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2820 auto *
MBB =
MI->getParent();
2821 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2822 if (IsWWMRegSpill) {
2824 RS->isRegUsed(AMDGPU::SCC));
2829 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2830 *
MI->memoperands_begin(), RS);
2835 MI->eraseFromParent();
2838 case AMDGPU::V_ADD_U32_e32:
2839 case AMDGPU::V_ADD_U32_e64:
2840 case AMDGPU::V_ADD_CO_U32_e32:
2841 case AMDGPU::V_ADD_CO_U32_e64: {
2843 unsigned NumDefs =
MI->getNumExplicitDefs();
2844 unsigned Src0Idx = NumDefs;
2846 bool HasClamp =
false;
2849 switch (
MI->getOpcode()) {
2850 case AMDGPU::V_ADD_U32_e32:
2852 case AMDGPU::V_ADD_U32_e64:
2853 HasClamp =
MI->getOperand(3).getImm();
2855 case AMDGPU::V_ADD_CO_U32_e32:
2856 VCCOp = &
MI->getOperand(3);
2858 case AMDGPU::V_ADD_CO_U32_e64:
2859 VCCOp = &
MI->getOperand(1);
2860 HasClamp =
MI->getOperand(4).getImm();
2865 bool DeadVCC = !VCCOp || VCCOp->
isDead();
2869 unsigned OtherOpIdx =
2870 FIOperandNum == Src0Idx ? FIOperandNum + 1 : Src0Idx;
2873 unsigned Src1Idx = Src0Idx + 1;
2874 Register MaterializedReg = FrameReg;
2877 int64_t
Offset = FrameInfo.getObjectOffset(Index);
2881 if ((!DeadVCC || HasClamp) &&
2888 if (OtherOp->
isImm()) {
2899 OtherOp->
setImm(TotalOffset);
2903 if (FrameReg && !ST.hasFlatScratchEnabled()) {
2911 ScavengedVGPR = RS->scavengeRegisterBackwards(
2912 AMDGPU::VGPR_32RegClass,
MI,
false, 0);
2918 .
addImm(ST.getWavefrontSizeLog2())
2920 MaterializedReg = ScavengedVGPR;
2923 if ((!OtherOp->
isImm() || OtherOp->
getImm() != 0) && MaterializedReg) {
2924 if (OtherOp->
isImm()) {
2926 FIOp->
setIsKill(MaterializedReg != FrameReg);
2928 if (ST.hasFlatScratchEnabled() &&
2929 !
TII->isOperandLegal(*
MI, Src1Idx, OtherOp)) {
2937 if (!ScavengedVGPR) {
2938 ScavengedVGPR = RS->scavengeRegisterBackwards(
2939 AMDGPU::VGPR_32RegClass,
MI,
false,
2943 assert(ScavengedVGPR != DstReg);
2949 MaterializedReg = ScavengedVGPR;
2958 AddI32.
add(
MI->getOperand(1));
2963 if (
isVGPRClass(getPhysRegBaseClass(MaterializedReg))) {
2966 AddI32.add(*OtherOp).addReg(MaterializedReg, MaterializedRegFlags);
2970 AddI32.addReg(MaterializedReg, MaterializedRegFlags).add(*OtherOp);
2973 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
2974 MI->getOpcode() == AMDGPU::V_ADD_U32_e64)
2977 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e32)
2978 AddI32.setOperandDead(3);
2980 MaterializedReg = DstReg;
2987 }
else if (
Offset != 0) {
2988 assert(!MaterializedReg);
2992 if (DeadVCC && !HasClamp) {
2997 if (OtherOp->
isReg() && OtherOp->
getReg() == DstReg) {
2999 MI->eraseFromParent();
3004 MI->setDesc(
TII->get(AMDGPU::V_MOV_B32_e32));
3005 MI->removeOperand(FIOperandNum);
3007 unsigned NumOps =
MI->getNumOperands();
3008 for (
unsigned I =
NumOps - 2;
I >= NumDefs + 1; --
I)
3009 MI->removeOperand(
I);
3012 MI->removeOperand(1);
3024 if (!
TII->isOperandLegal(*
MI, Src1Idx) &&
TII->commuteInstruction(*
MI)) {
3032 for (
unsigned SrcIdx : {FIOperandNum, OtherOpIdx}) {
3033 if (!
TII->isOperandLegal(*
MI, SrcIdx)) {
3037 if (!ScavengedVGPR) {
3038 ScavengedVGPR = RS->scavengeRegisterBackwards(
3039 AMDGPU::VGPR_32RegClass,
MI,
false,
3043 assert(ScavengedVGPR != DstReg);
3049 Src.ChangeToRegister(ScavengedVGPR,
false);
3050 Src.setIsKill(
true);
3056 if (FIOp->
isImm() && FIOp->
getImm() == 0 && DeadVCC && !HasClamp) {
3057 if (OtherOp->
isReg() && OtherOp->
getReg() != DstReg) {
3061 MI->eraseFromParent();
3066 case AMDGPU::S_ADD_I32:
3067 case AMDGPU::S_ADD_U32: {
3069 unsigned OtherOpIdx = FIOperandNum == 1 ? 2 : 1;
3076 Register MaterializedReg = FrameReg;
3078 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3081 bool DeadSCC =
MI->getOperand(3).isDead();
3092 if (FrameReg && !ST.hasFlatScratchEnabled()) {
3097 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3104 .
addImm(ST.getWavefrontSizeLog2())
3107 MaterializedReg = TmpReg;
3113 if (OtherOp.
isImm()) {
3117 if (MaterializedReg)
3121 }
else if (MaterializedReg) {
3125 if (!TmpReg && MaterializedReg == FrameReg) {
3126 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3140 MaterializedReg = DstReg;
3153 if (DeadSCC && OtherOp.
isImm() && OtherOp.
getImm() == 0) {
3155 MI->removeOperand(3);
3156 MI->removeOperand(OtherOpIdx);
3158 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3159 }
else if (DeadSCC && FIOp->
isImm() && FIOp->
getImm() == 0) {
3161 MI->removeOperand(3);
3162 MI->removeOperand(FIOperandNum);
3164 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3175 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3176 if (ST.hasFlatScratchEnabled()) {
3177 if (
TII->isFLATScratch(*
MI)) {
3179 (int16_t)FIOperandNum ==
3180 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::saddr));
3187 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset);
3198 unsigned Opc =
MI->getOpcode();
3202 }
else if (ST.hasFlatScratchSTMode()) {
3212 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
3213 bool TiedVDst = VDstIn != -1 &&
MI->getOperand(VDstIn).isReg() &&
3214 MI->getOperand(VDstIn).isTied();
3216 MI->untieRegOperand(VDstIn);
3219 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::saddr));
3223 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
3225 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
3226 assert(NewVDst != -1 && NewVDstIn != -1 &&
"Must be tied!");
3227 MI->tieOperands(NewVDst, NewVDstIn);
3229 MI->setDesc(
TII->get(NewOpc));
3237 if (
TII->isOperandLegal(*
MI, FIOperandNum, FIOp))
3244 bool UseSGPR =
TII->isOperandLegal(*
MI, FIOperandNum, FIOp);
3246 if (!
Offset && FrameReg && UseSGPR) {
3252 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3255 RS->scavengeRegisterBackwards(*RC,
MI,
false, 0, !UseSGPR);
3259 if ((!FrameReg || !
Offset) && TmpReg) {
3260 unsigned Opc = UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
3263 MIB.addReg(FrameReg);
3270 bool NeedSaveSCC = (RS->isRegUsed(AMDGPU::SCC) &&
3271 !
MI->definesRegister(AMDGPU::SCC,
nullptr)) ||
3272 MI->readsRegister(AMDGPU::SCC,
nullptr);
3276 : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3277 MI,
false, 0, !UseSGPR);
3283 if ((!TmpSReg && !FrameReg) || (!TmpReg && !UseSGPR)) {
3284 int SVfromSSOpcode =
3286 int SVfromSVSOpcode =
3288 int SVOpcode = SVfromSSOpcode != -1 ? SVfromSSOpcode : SVfromSVSOpcode;
3289 if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
3296 "SV-form fallback cannot encode a frame register");
3302 int64_t FullOffset =
3304 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3305 auto [ImmOffset, RemainderOffset] =
3311 TII->getNamedOperand(*
MI, AMDGPU::OpName::vaddr)) {
3313 TII->getNamedOperand(*
MI, AMDGPU::OpName::vdata);
3317 bool CanReuseVAddr = VAddr->isKill() &&
3318 !(VData && regsOverlap(Src, VData->
getReg()));
3320 : RS->scavengeRegisterBackwards(
3321 AMDGPU::VGPR_32RegClass,
MI,
3329 UsedVAddr = RS->scavengeRegisterBackwards(
3330 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3332 .
addImm(RemainderOffset);
3335 .
add(
MI->getOperand(0))
3338 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::cpol));
3339 MI->eraseFromParent();
3353 assert(!(
Offset & 0x1) &&
"Flat scratch offset must be aligned!");
3373 if (TmpSReg == FrameReg) {
3376 !
MI->registerDefIsDead(AMDGPU::SCC,
nullptr)) {
3400 bool IsMUBUF =
TII->isMUBUF(*
MI);
3406 bool LiveSCC = RS->isRegUsed(AMDGPU::SCC) &&
3407 !
MI->definesRegister(AMDGPU::SCC,
nullptr);
3409 ? &AMDGPU::SReg_32RegClass
3410 : &AMDGPU::VGPR_32RegClass;
3411 bool IsCopy =
MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
3412 MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
3413 MI->getOpcode() == AMDGPU::S_MOV_B32;
3415 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3420 bool CanUseFrameRegAsScratch = IsSALU && !LiveSCC && FrameReg &&
3421 !
MI->readsRegister(FrameReg,
this) &&
3422 !
MI->modifiesRegister(FrameReg,
this);
3424 bool RestoreFrameReg =
false;
3427 ResultReg =
MI->getOperand(0).getReg();
3429 ResultReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0,
3432 if (CanUseFrameRegAsScratch) {
3435 ResultReg = FrameReg;
3436 RestoreFrameReg =
true;
3438 ResultReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0);
3447 isWave32 ?
Add.getReg(1)
3448 :
Register(getSubReg(
Add.getReg(1), AMDGPU::sub0));
3451 return ConstOffsetReg;
3456 IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
3458 if (IsSALU && LiveSCC) {
3459 TmpResultReg = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
3464 if (OpCode == AMDGPU::V_LSHRREV_B32_e64)
3467 Shift.addImm(ST.getWavefrontSizeLog2()).addReg(FrameReg);
3469 Shift.addReg(FrameReg).addImm(ST.getWavefrontSizeLog2());
3470 if (IsSALU && !LiveSCC)
3471 Shift.getInstr()->getOperand(3).setIsDead();
3472 if (IsSALU && LiveSCC) {
3476 NewDest = ResultReg;
3478 NewDest = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3483 ResultReg = NewDest;
3488 if ((MIB =
TII->getAddNoCarry(*
MBB,
MI,
DL, ResultReg, *RS)) !=
3495 .
addImm(ST.getWavefrontSizeLog2())
3498 const bool IsVOP2 = MIB->
getOpcode() == AMDGPU::V_ADD_U32_e32;
3510 "Need to reuse carry out register");
3518 if (!MIB || IsSALU) {
3525 Register TmpScaledReg = IsCopy && IsSALU
3527 : RS->scavengeRegisterBackwards(
3528 AMDGPU::SReg_32_XM0RegClass,
MI,
3534 ScaledReg = IsSALU ? ResultReg : FrameReg;
3540 .
addImm(ST.getWavefrontSizeLog2());
3545 TmpResultReg = RS->scavengeRegisterBackwards(
3546 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3549 if ((
Add =
TII->getAddNoCarry(*
MBB,
MI,
DL, TmpResultReg, *RS))) {
3552 .
addImm(ST.getWavefrontSizeLog2())
3554 if (
Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
3562 "offset is unsafe for v_mad_u32_u24");
3571 bool IsInlinableLiteral =
3573 if (!IsInlinableLiteral) {
3582 if (!IsInlinableLiteral) {
3588 Add.addImm(ST.getWavefrontSize()).addReg(FrameReg).addImm(0);
3591 .
addImm(ST.getWavefrontSizeLog2())
3597 NewDest = ResultReg;
3599 NewDest = RS->scavengeRegisterBackwards(
3600 AMDGPU::SReg_32_XM0RegClass, *
Add,
false, 0,
3607 ResultReg = NewDest;
3615 if (!TmpScaledReg.
isValid()) {
3621 .
addImm(ST.getWavefrontSizeLog2());
3627 if (RestoreFrameReg) {
3636 .
addImm(ST.getWavefrontSize());
3639 int64_t ScaledOffset = -
Offset * ST.getWavefrontSize();
3640 bool SCCLiveAfterMI =
MI->definesRegister(AMDGPU::SCC,
this) &&
3641 !
MI->registerDefIsDead(AMDGPU::SCC,
this);
3642 if (!SCCLiveAfterMI) {
3662 MI->eraseFromParent();
3673 static_cast<int>(FIOperandNum) ==
3674 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::vaddr));
3676 auto &SOffset = *
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset);
3677 assert((SOffset.isImm() && SOffset.getImm() == 0));
3679 if (FrameReg != AMDGPU::NoRegister)
3680 SOffset.ChangeToRegister(FrameReg,
false);
3682 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3684 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3685 int64_t NewOffset = OldImm +
Offset;
3687 if (
TII->isLegalMUBUFImmOffset(NewOffset) &&
3689 MI->eraseFromParent();
3700 if (!
TII->isOperandLegal(*
MI, FIOperandNum, FIOp)) {
3702 TII->getRegClass(
MI->getDesc(), FIOperandNum);
3706 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3707 Register TmpReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0);
3709 TII->get(UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32),
3729 return &AMDGPU::VReg_64RegClass;
3731 return &AMDGPU::VReg_96RegClass;
3733 return &AMDGPU::VReg_128RegClass;
3735 return &AMDGPU::VReg_160RegClass;
3737 return &AMDGPU::VReg_192RegClass;
3739 return &AMDGPU::VReg_224RegClass;
3741 return &AMDGPU::VReg_256RegClass;
3743 return &AMDGPU::VReg_288RegClass;
3745 return &AMDGPU::VReg_320RegClass;
3747 return &AMDGPU::VReg_352RegClass;
3749 return &AMDGPU::VReg_384RegClass;
3751 return &AMDGPU::VReg_512RegClass;
3753 return &AMDGPU::VReg_1024RegClass;
3761 return &AMDGPU::VReg_64_Align2RegClass;
3763 return &AMDGPU::VReg_96_Align2RegClass;
3765 return &AMDGPU::VReg_128_Align2RegClass;
3767 return &AMDGPU::VReg_160_Align2RegClass;
3769 return &AMDGPU::VReg_192_Align2RegClass;
3771 return &AMDGPU::VReg_224_Align2RegClass;
3773 return &AMDGPU::VReg_256_Align2RegClass;
3775 return &AMDGPU::VReg_288_Align2RegClass;
3777 return &AMDGPU::VReg_320_Align2RegClass;
3779 return &AMDGPU::VReg_352_Align2RegClass;
3781 return &AMDGPU::VReg_384_Align2RegClass;
3783 return &AMDGPU::VReg_512_Align2RegClass;
3785 return &AMDGPU::VReg_1024_Align2RegClass;
3793 return &AMDGPU::VReg_1RegClass;
3795 return &AMDGPU::VGPR_16RegClass;
3797 return &AMDGPU::VGPR_32RegClass;
3805 return &AMDGPU::VGPR_32_Lo256RegClass;
3807 return &AMDGPU::VReg_64_Lo256_Align2RegClass;
3809 return &AMDGPU::VReg_96_Lo256_Align2RegClass;
3811 return &AMDGPU::VReg_128_Lo256_Align2RegClass;
3813 return &AMDGPU::VReg_160_Lo256_Align2RegClass;
3815 return &AMDGPU::VReg_192_Lo256_Align2RegClass;
3817 return &AMDGPU::VReg_224_Lo256_Align2RegClass;
3819 return &AMDGPU::VReg_256_Lo256_Align2RegClass;
3821 return &AMDGPU::VReg_288_Lo256_Align2RegClass;
3823 return &AMDGPU::VReg_320_Lo256_Align2RegClass;
3825 return &AMDGPU::VReg_352_Lo256_Align2RegClass;
3827 return &AMDGPU::VReg_384_Lo256_Align2RegClass;
3829 return &AMDGPU::VReg_512_Lo256_Align2RegClass;
3831 return &AMDGPU::VReg_1024_Lo256_Align2RegClass;
3839 return &AMDGPU::AReg_64RegClass;
3841 return &AMDGPU::AReg_96RegClass;
3843 return &AMDGPU::AReg_128RegClass;
3845 return &AMDGPU::AReg_160RegClass;
3847 return &AMDGPU::AReg_192RegClass;
3849 return &AMDGPU::AReg_224RegClass;
3851 return &AMDGPU::AReg_256RegClass;
3853 return &AMDGPU::AReg_288RegClass;
3855 return &AMDGPU::AReg_320RegClass;
3857 return &AMDGPU::AReg_352RegClass;
3859 return &AMDGPU::AReg_384RegClass;
3861 return &AMDGPU::AReg_512RegClass;
3863 return &AMDGPU::AReg_1024RegClass;
3871 return &AMDGPU::AReg_64_Align2RegClass;
3873 return &AMDGPU::AReg_96_Align2RegClass;
3875 return &AMDGPU::AReg_128_Align2RegClass;
3877 return &AMDGPU::AReg_160_Align2RegClass;
3879 return &AMDGPU::AReg_192_Align2RegClass;
3881 return &AMDGPU::AReg_224_Align2RegClass;
3883 return &AMDGPU::AReg_256_Align2RegClass;
3885 return &AMDGPU::AReg_288_Align2RegClass;
3887 return &AMDGPU::AReg_320_Align2RegClass;
3889 return &AMDGPU::AReg_352_Align2RegClass;
3891 return &AMDGPU::AReg_384_Align2RegClass;
3893 return &AMDGPU::AReg_512_Align2RegClass;
3895 return &AMDGPU::AReg_1024_Align2RegClass;
3903 return &AMDGPU::AGPR_LO16RegClass;
3905 return &AMDGPU::AGPR_32RegClass;
3913 return &AMDGPU::AV_64RegClass;
3915 return &AMDGPU::AV_96RegClass;
3917 return &AMDGPU::AV_128RegClass;
3919 return &AMDGPU::AV_160RegClass;
3921 return &AMDGPU::AV_192RegClass;
3923 return &AMDGPU::AV_224RegClass;
3925 return &AMDGPU::AV_256RegClass;
3927 return &AMDGPU::AV_288RegClass;
3929 return &AMDGPU::AV_320RegClass;
3931 return &AMDGPU::AV_352RegClass;
3933 return &AMDGPU::AV_384RegClass;
3935 return &AMDGPU::AV_512RegClass;
3937 return &AMDGPU::AV_1024RegClass;
3945 return &AMDGPU::AV_64_Align2RegClass;
3947 return &AMDGPU::AV_96_Align2RegClass;
3949 return &AMDGPU::AV_128_Align2RegClass;
3951 return &AMDGPU::AV_160_Align2RegClass;
3953 return &AMDGPU::AV_192_Align2RegClass;
3955 return &AMDGPU::AV_224_Align2RegClass;
3957 return &AMDGPU::AV_256_Align2RegClass;
3959 return &AMDGPU::AV_288_Align2RegClass;
3961 return &AMDGPU::AV_320_Align2RegClass;
3963 return &AMDGPU::AV_352_Align2RegClass;
3965 return &AMDGPU::AV_384_Align2RegClass;
3967 return &AMDGPU::AV_512_Align2RegClass;
3969 return &AMDGPU::AV_1024_Align2RegClass;
3977 return &AMDGPU::AV_32RegClass;
3978 return ST.needsAlignedVGPRs()
3997 return &AMDGPU::SReg_32RegClass;
3999 return &AMDGPU::SReg_64RegClass;
4001 return &AMDGPU::SGPR_96RegClass;
4003 return &AMDGPU::SGPR_128RegClass;
4005 return &AMDGPU::SGPR_160RegClass;
4007 return &AMDGPU::SGPR_192RegClass;
4009 return &AMDGPU::SGPR_224RegClass;
4011 return &AMDGPU::SGPR_256RegClass;
4013 return &AMDGPU::SGPR_288RegClass;
4015 return &AMDGPU::SGPR_320RegClass;
4017 return &AMDGPU::SGPR_352RegClass;
4019 return &AMDGPU::SGPR_384RegClass;
4021 return &AMDGPU::SGPR_512RegClass;
4023 return &AMDGPU::SGPR_1024RegClass;
4031 if (Reg.isVirtual())
4034 RC = getPhysRegBaseClass(Reg);
4040 unsigned Size = getRegSizeInBits(*SRC);
4042 switch (SRC->
getID()) {
4045 case AMDGPU::VS_16_Lo128RegClassID:
4046 return getAllocatableClass(&AMDGPU::VGPR_16_Lo128RegClass);
4047 case AMDGPU::VS_32_Lo128RegClassID:
4048 return getAllocatableClass(&AMDGPU::VGPR_32_Lo128RegClass);
4049 case AMDGPU::VS_32_Lo256RegClassID:
4050 case AMDGPU::VS_64_Lo256RegClassID:
4056 assert(VRC &&
"Invalid register class size");
4062 unsigned Size = getRegSizeInBits(*SRC);
4064 assert(ARC &&
"Invalid register class size");
4070 unsigned Size = getRegSizeInBits(*SRC);
4072 assert(ARC &&
"Invalid register class size");
4078 unsigned Size = getRegSizeInBits(*VRC);
4080 return &AMDGPU::SGPR_32RegClass;
4082 assert(SRC &&
"Invalid register class size");
4089 unsigned SubIdx)
const {
4092 getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
4093 return MatchRC && MatchRC->
hasSubClassEq(SuperRC) ? MatchRC :
nullptr;
4099 return !ST.hasMFMAInlineLiteralBug();
4120 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::VCC_HI;
4123 if (ReserveHighestRegister) {
4146 unsigned EltSize)
const {
4148 assert(RegBitWidth >= 32 && RegBitWidth <= 1024 && EltSize >= 2);
4150 const unsigned RegHalves = RegBitWidth / 16;
4151 const unsigned EltHalves = EltSize / 2;
4152 assert(RegSplitParts.size() + 1 >= EltHalves);
4154 const std::vector<int16_t> &Parts = RegSplitParts[EltHalves - 1];
4155 const unsigned NumParts = RegHalves / EltHalves;
4157 return ArrayRef(Parts.data(), NumParts);
4163 return Reg.isVirtual() ? MRI.
getRegClass(Reg) : getPhysRegBaseClass(Reg);
4170 return getSubRegisterClass(SrcRC, MO.
getSubReg());
4190 unsigned MinOcc = ST.getOccupancyWithWorkGroupSizes(MF).first;
4191 switch (RC->
getID()) {
4193 return AMDGPUGenRegisterInfo::getRegPressureLimit(RC, MF);
4194 case AMDGPU::VGPR_32RegClassID:
4199 ST.getMaxNumVGPRs(MF));
4200 case AMDGPU::SGPR_32RegClassID:
4201 case AMDGPU::SGPR_LO16RegClassID:
4202 return std::min(ST.getMaxNumSGPRs(MinOcc,
true), ST.getMaxNumSGPRs(MF));
4207 unsigned Idx)
const {
4208 switch (
static_cast<AMDGPU::RegisterPressureSets
>(Idx)) {
4209 case AMDGPU::RegisterPressureSets::VGPR_32:
4210 case AMDGPU::RegisterPressureSets::AGPR_32:
4213 case AMDGPU::RegisterPressureSets::SReg_32:
4222 static const int Empty[] = { -1 };
4224 if (RegPressureIgnoredUnits[
static_cast<unsigned>(RegUnit)])
4227 return AMDGPUGenRegisterInfo::getRegUnitPressureSets(RegUnit);
4242 switch (Hint.first) {
4249 getMatchingSuperReg(Paired, AMDGPU::lo16, &AMDGPU::VGPR_32RegClass);
4250 }
else if (VRM && VRM->
hasPhys(Paired)) {
4251 PairedPhys = getMatchingSuperReg(VRM->
getPhys(Paired), AMDGPU::lo16,
4252 &AMDGPU::VGPR_32RegClass);
4267 PairedPhys =
TRI->getSubReg(Paired, AMDGPU::lo16);
4268 }
else if (VRM && VRM->
hasPhys(Paired)) {
4269 PairedPhys =
TRI->getSubReg(VRM->
getPhys(Paired), AMDGPU::lo16);
4284 if (AMDGPU::VGPR_16RegClass.
contains(PhysReg) &&
4299 return AMDGPU::SGPR30_SGPR31;
4305 switch (RB.
getID()) {
4306 case AMDGPU::VGPRRegBankID:
4308 std::max(ST.useRealTrue16Insts() ? 16u : 32u,
Size));
4309 case AMDGPU::VCCRegBankID:
4312 case AMDGPU::SGPRRegBankID:
4314 case AMDGPU::AGPRRegBankID:
4328 return getAllocatableClass(RC);
4334 return isWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC;
4338 return isWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
4343 return ST.needsAlignedVGPRs() ? &AMDGPU::VReg_64_Align2RegClass
4344 : &AMDGPU::VReg_64RegClass;
4356 if (Reg.isVirtual()) {
4360 LaneBitmask SubLanes = SubReg ? getSubRegIndexLaneMask(SubReg)
4365 if ((S.LaneMask & SubLanes) == SubLanes) {
4366 V = S.getVNInfoAt(UseIdx);
4378 for (MCRegUnit Unit : regunits(Reg.asMCReg())) {
4393 if (!Def || !MDT.dominates(Def, &
Use))
4396 assert(Def->modifiesRegister(Reg,
this));
4402 assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
4405 {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
4406 &AMDGPU::AGPR_32RegClass}) {
4407 if (
MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
4410 if (
MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::hi16,
4411 &AMDGPU::VGPR_32RegClass)) {
4415 return AMDGPU::NoRegister;
4419 if (!ST.needsAlignedVGPRs())
4430 assert(&RC != &AMDGPU::VS_64RegClass);
4437 return ArrayRef(AMDGPU::SGPR_128RegClass.begin(), ST.getMaxNumSGPRs(MF) / 4);
4442 return ArrayRef(AMDGPU::SGPR_64RegClass.begin(), ST.getMaxNumSGPRs(MF) / 2);
4447 return ArrayRef(AMDGPU::SGPR_32RegClass.begin(), ST.getMaxNumSGPRs(MF));
4452 unsigned SubReg)
const {
4455 return std::min(128u, getSubRegIdxSize(SubReg));
4459 return std::min(32u, getSubRegIdxSize(SubReg));
4468 bool IncludeCalls)
const {
4469 unsigned NumArchVGPRs = ST.getAddressableNumArchVGPRs();
4471 (RC.
getID() == AMDGPU::VGPR_32RegClassID)
4475 if (Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
AMDGPU Reserve WWM Registers
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.
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 bool wrapsAround32(int64_t LHS, int64_t RHS)
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 foldingOffsetChangesCarry(const MachineOperand &OtherOp, int64_t Offset, Register FrameReg)
static bool isFIPlusImmOrVGPR(const SIRegisterInfo &TRI, const MachineInstr &MI)
static int getOffenMUBUFLoad(unsigned Opc)
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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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 getPerLaneVGPRMask() 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
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 * 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)
const TargetRegisterClass * getConstrainedRegClassForReg(Register Reg, const MachineRegisterInfo &MRI) const override
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.