27#define DEBUG_TYPE "amdgpu-si-register-info"
31#define GET_REGINFO_TARGET_DESC
32#include "AMDGPUGenRegisterInfo.inc"
34std::array<std::vector<int16_t>, 32> SIRegisterInfo::RegSplitParts;
35std::array<std::array<uint16_t, 32>, 9> SIRegisterInfo::SubRegFromChannelTable;
42 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 9};
45 const Twine &ErrMsg) {
118 MI->getOperand(0).isKill(),
Index,
RS) {}
133 MovOpc = AMDGPU::S_MOV_B32;
134 NotOpc = AMDGPU::S_NOT_B32;
137 MovOpc = AMDGPU::S_MOV_B64;
138 NotOpc = AMDGPU::S_NOT_B64;
143 SuperReg != AMDGPU::EXEC &&
"exec should never spill");
174 assert(
RS &&
"Cannot spill SGPR to memory without RegScavenger");
175 TmpVGPR =
RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false,
203 IsWave32 ? AMDGPU::SGPR_32RegClass : AMDGPU::SGPR_64RegClass;
223 if (
RS->isRegUsed(AMDGPU::SCC))
225 "unhandled SGPR spill to memory");
235 I->getOperand(2).setIsDead();
270 I->getOperand(2).setIsDead();
299 if (
RS->isRegUsed(AMDGPU::SCC))
301 "unhandled SGPR spill to memory");
326 ST.getAMDGPUDwarfFlavour(),
329 ST(ST), SpillSGPRToVGPR(ST.getCLOpts().spill_sgpr_to_vgpr),
330 isWave32(ST.isWave32()) {
332 assert(getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() == 3 &&
333 getSubRegIndexLaneMask(AMDGPU::sub31).getAsInteger() == (3ULL << 62) &&
334 (getSubRegIndexLaneMask(AMDGPU::lo16) |
335 getSubRegIndexLaneMask(AMDGPU::hi16)).getAsInteger() ==
336 getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() &&
337 "getNumCoveredRegs() will not work with generated subreg masks!");
339 RegPressureIgnoredUnits.resize(getNumRegUnits());
340 RegPressureIgnoredUnits.set(
342 for (
auto Reg : AMDGPU::VGPR_16RegClass) {
344 RegPressureIgnoredUnits.set(
345 static_cast<unsigned>(*regunits(Reg).begin()));
351 static auto InitializeRegSplitPartsOnce = [
this]() {
352 for (
unsigned Idx = 1, E = getNumSubRegIndices() - 1; Idx < E; ++Idx) {
353 unsigned Size = getSubRegIdxSize(Idx);
356 std::vector<int16_t> &Vec = RegSplitParts[
Size / 16 - 1];
357 unsigned Pos = getSubRegIdxOffset(Idx);
362 unsigned MaxNumParts = 1024 /
Size;
363 Vec.resize(MaxNumParts);
371 static auto InitializeSubRegFromChannelTableOnce = [
this]() {
372 for (
auto &Row : SubRegFromChannelTable)
373 Row.fill(AMDGPU::NoSubRegister);
374 for (
unsigned Idx = 1; Idx < getNumSubRegIndices(); ++Idx) {
375 unsigned Width = getSubRegIdxSize(Idx) / 32;
376 unsigned Offset = getSubRegIdxOffset(Idx) / 32;
381 unsigned TableIdx = Width - 1;
382 assert(TableIdx < SubRegFromChannelTable.size());
384 SubRegFromChannelTable[TableIdx][
Offset] = Idx;
388 llvm::call_once(InitializeRegSplitPartsFlag, InitializeRegSplitPartsOnce);
390 InitializeSubRegFromChannelTableOnce);
407 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_SaveList
408 : CSR_AMDGPU_SaveList;
411 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_SaveList
412 : CSR_AMDGPU_SI_Gfx_SaveList;
414 return CSR_AMDGPU_CS_ChainPreserve_SaveList;
417 static const MCPhysReg NoCalleeSavedReg = AMDGPU::NoRegister;
418 return &NoCalleeSavedReg;
434 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_RegMask
435 : CSR_AMDGPU_RegMask;
438 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_RegMask
439 : CSR_AMDGPU_SI_Gfx_RegMask;
444 return AMDGPU_AllVGPRs_RegMask;
451 return CSR_AMDGPU_NoRegs_RegMask;
455 return VGPR >= AMDGPU::VGPR0 && VGPR < AMDGPU::VGPR8;
466 if (RC == &AMDGPU::VGPR_32RegClass || RC == &AMDGPU::AGPR_32RegClass)
467 return &AMDGPU::AV_32RegClass;
468 if (RC == &AMDGPU::VReg_64RegClass || RC == &AMDGPU::AReg_64RegClass)
469 return &AMDGPU::AV_64RegClass;
470 if (RC == &AMDGPU::VReg_64_Align2RegClass ||
471 RC == &AMDGPU::AReg_64_Align2RegClass)
472 return &AMDGPU::AV_64_Align2RegClass;
473 if (RC == &AMDGPU::VReg_96RegClass || RC == &AMDGPU::AReg_96RegClass)
474 return &AMDGPU::AV_96RegClass;
475 if (RC == &AMDGPU::VReg_96_Align2RegClass ||
476 RC == &AMDGPU::AReg_96_Align2RegClass)
477 return &AMDGPU::AV_96_Align2RegClass;
478 if (RC == &AMDGPU::VReg_128RegClass || RC == &AMDGPU::AReg_128RegClass)
479 return &AMDGPU::AV_128RegClass;
480 if (RC == &AMDGPU::VReg_128_Align2RegClass ||
481 RC == &AMDGPU::AReg_128_Align2RegClass)
482 return &AMDGPU::AV_128_Align2RegClass;
483 if (RC == &AMDGPU::VReg_160RegClass || RC == &AMDGPU::AReg_160RegClass)
484 return &AMDGPU::AV_160RegClass;
485 if (RC == &AMDGPU::VReg_160_Align2RegClass ||
486 RC == &AMDGPU::AReg_160_Align2RegClass)
487 return &AMDGPU::AV_160_Align2RegClass;
488 if (RC == &AMDGPU::VReg_192RegClass || RC == &AMDGPU::AReg_192RegClass)
489 return &AMDGPU::AV_192RegClass;
490 if (RC == &AMDGPU::VReg_192_Align2RegClass ||
491 RC == &AMDGPU::AReg_192_Align2RegClass)
492 return &AMDGPU::AV_192_Align2RegClass;
493 if (RC == &AMDGPU::VReg_256RegClass || RC == &AMDGPU::AReg_256RegClass)
494 return &AMDGPU::AV_256RegClass;
495 if (RC == &AMDGPU::VReg_256_Align2RegClass ||
496 RC == &AMDGPU::AReg_256_Align2RegClass)
497 return &AMDGPU::AV_256_Align2RegClass;
498 if (RC == &AMDGPU::VReg_512RegClass || RC == &AMDGPU::AReg_512RegClass)
499 return &AMDGPU::AV_512RegClass;
500 if (RC == &AMDGPU::VReg_512_Align2RegClass ||
501 RC == &AMDGPU::AReg_512_Align2RegClass)
502 return &AMDGPU::AV_512_Align2RegClass;
503 if (RC == &AMDGPU::VReg_1024RegClass || RC == &AMDGPU::AReg_1024RegClass)
504 return &AMDGPU::AV_1024RegClass;
505 if (RC == &AMDGPU::VReg_1024_Align2RegClass ||
506 RC == &AMDGPU::AReg_1024_Align2RegClass)
507 return &AMDGPU::AV_1024_Align2RegClass;
537 return AMDGPU_AllVGPRs_RegMask;
541 return AMDGPU_AllAGPRs_RegMask;
545 return AMDGPU_AllVectorRegs_RegMask;
552 assert(NumRegIndex &&
"Not implemented");
553 assert(Channel < SubRegFromChannelTable[NumRegIndex - 1].
size());
554 return SubRegFromChannelTable[NumRegIndex - 1][Channel];
558 return ST.getCLOpts().spill_cfi_saved_regs;
563 const unsigned Align,
566 MCRegister BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx));
567 return getMatchingSuperReg(BaseReg, AMDGPU::sub0, RC);
585 reserveRegisterTuples(
Reserved, AMDGPU::EXEC);
586 reserveRegisterTuples(
Reserved, AMDGPU::FLAT_SCR);
589 reserveRegisterTuples(
Reserved, AMDGPU::M0);
592 reserveRegisterTuples(
Reserved, AMDGPU::SRC_VCCZ);
593 reserveRegisterTuples(
Reserved, AMDGPU::SRC_EXECZ);
594 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SCC);
597 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_BASE);
598 reserveRegisterTuples(
Reserved, AMDGPU::SRC_SHARED_LIMIT);
599 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_BASE);
600 reserveRegisterTuples(
Reserved, AMDGPU::SRC_PRIVATE_LIMIT);
601 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_LO);
602 reserveRegisterTuples(
Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_HI);
605 reserveRegisterTuples(
Reserved, AMDGPU::ASYNCcnt);
606 reserveRegisterTuples(
Reserved, AMDGPU::TENSORcnt);
609 reserveRegisterTuples(
Reserved, AMDGPU::SRC_POPS_EXITING_WAVE_ID);
612 reserveRegisterTuples(
Reserved, AMDGPU::XNACK_MASK);
615 reserveRegisterTuples(
Reserved, AMDGPU::LDS_DIRECT);
618 reserveRegisterTuples(
Reserved, AMDGPU::TBA);
619 reserveRegisterTuples(
Reserved, AMDGPU::TMA);
620 reserveRegisterTuples(
Reserved, AMDGPU::TTMP0_TTMP1);
621 reserveRegisterTuples(
Reserved, AMDGPU::TTMP2_TTMP3);
622 reserveRegisterTuples(
Reserved, AMDGPU::TTMP4_TTMP5);
623 reserveRegisterTuples(
Reserved, AMDGPU::TTMP6_TTMP7);
624 reserveRegisterTuples(
Reserved, AMDGPU::TTMP8_TTMP9);
625 reserveRegisterTuples(
Reserved, AMDGPU::TTMP10_TTMP11);
626 reserveRegisterTuples(
Reserved, AMDGPU::TTMP12_TTMP13);
627 reserveRegisterTuples(
Reserved, AMDGPU::TTMP14_TTMP15);
630 reserveRegisterTuples(
Reserved, AMDGPU::SGPR_NULL64);
634 unsigned MaxNumSGPRs = ST.getMaxNumSGPRs(MF);
635 if (
auto Limit = ST.getCLOpts().stress_sgpr; Limit && *Limit < MaxNumSGPRs)
636 MaxNumSGPRs = *Limit;
637 unsigned TotalNumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
640 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
643 if (Index + NumRegs > MaxNumSGPRs && Index < TotalNumSGPRs &&
644 Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
652 if (ScratchRSrcReg != AMDGPU::NoRegister) {
656 reserveRegisterTuples(
Reserved, ScratchRSrcReg);
660 if (LongBranchReservedReg)
661 reserveRegisterTuples(
Reserved, LongBranchReservedReg);
668 reserveRegisterTuples(
Reserved, StackPtrReg);
669 assert(!isSubRegister(ScratchRSrcReg, StackPtrReg));
674 reserveRegisterTuples(
Reserved, FrameReg);
675 assert(!isSubRegister(ScratchRSrcReg, FrameReg));
680 reserveRegisterTuples(
Reserved, BasePtrReg);
681 assert(!isSubRegister(ScratchRSrcReg, BasePtrReg));
688 reserveRegisterTuples(
Reserved, ExecCopyReg);
692 auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.
getFunction());
695 if (
auto Limit = ST.getCLOpts().stress_vgpr; Limit && *Limit < MaxNumVGPRs)
696 MaxNumVGPRs = *Limit;
697 if (
auto Limit = ST.getCLOpts().stress_agpr; Limit && *Limit < MaxNumAGPRs)
698 MaxNumAGPRs = *Limit;
702 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
705 if (Index + NumRegs > MaxNumVGPRs)
712 if (!ST.hasMAIInsts())
716 unsigned NumRegs =
divideCeil(getRegSizeInBits(RC), 32);
719 if (Index + NumRegs > MaxNumAGPRs)
727 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
735 if (!PerLaneVGPRMask.
empty()) {
736 for (
unsigned RegI = AMDGPU::VGPR0, RegE = AMDGPU::VGPR0 + MaxNumVGPRs;
737 RegI < RegE; ++RegI) {
738 if (PerLaneVGPRMask.
test(RegI))
739 reserveRegisterTuples(
Reserved, RegI);
744 reserveRegisterTuples(
Reserved, Reg);
748 reserveRegisterTuples(
Reserved, Reg);
751 reserveRegisterTuples(
Reserved, Reg);
768 if (Info->isBottomOfStack())
776 if (Info->isEntryFunction()) {
809 int OffIdx = AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
810 AMDGPU::OpName::offset);
811 return MI->getOperand(OffIdx).getImm();
816 switch (
MI->getOpcode()) {
817 case AMDGPU::V_ADD_U32_e32:
818 case AMDGPU::V_ADD_U32_e64:
819 case AMDGPU::V_ADD_CO_U32_e32: {
820 int OtherIdx = Idx == 1 ? 2 : 1;
824 case AMDGPU::V_ADD_CO_U32_e64: {
825 int OtherIdx = Idx == 2 ? 3 : 2;
836 assert((Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
837 AMDGPU::OpName::vaddr) ||
838 (Idx == AMDGPU::getNamedOperandIdx(
MI->getOpcode(),
839 AMDGPU::OpName::saddr))) &&
840 "Should never see frame index on non-address operand");
852 return Src1.isImm() || (Src1.isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
857 return Src0.isImm() || (Src0.isReg() &&
TRI.isVGPR(
MI.getMF()->getRegInfo(),
866 switch (
MI->getOpcode()) {
867 case AMDGPU::V_ADD_U32_e32: {
870 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e32) < 2 &&
875 case AMDGPU::V_ADD_U32_e64:
885 return !ST.hasFlatScratchEnabled();
886 case AMDGPU::V_ADD_CO_U32_e32:
887 if (ST.getConstantBusLimit(AMDGPU::V_ADD_CO_U32_e32) < 2 &&
892 return MI->getOperand(3).isDead();
893 case AMDGPU::V_ADD_CO_U32_e64:
895 return MI->getOperand(1).isDead();
907 return !
TII->isLegalMUBUFImmOffset(FullOffset);
919 if (Ins !=
MBB->end())
920 DL = Ins->getDebugLoc();
926 ST.hasFlatScratchEnabled() ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
929 ST.hasFlatScratchEnabled() ? &AMDGPU::SReg_32_XEXEC_HIRegClass
930 : &AMDGPU::VGPR_32RegClass);
938 Register OffsetReg =
MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
940 Register FIReg =
MRI.createVirtualRegister(ST.hasFlatScratchEnabled()
941 ? &AMDGPU::SReg_32_XM0RegClass
942 : &AMDGPU::VGPR_32RegClass);
949 if (ST.hasFlatScratchEnabled()) {
958 TII->getAddNoCarry(*
MBB, Ins,
DL, BaseReg)
970 switch (
MI.getOpcode()) {
971 case AMDGPU::V_ADD_U32_e32:
972 case AMDGPU::V_ADD_CO_U32_e32: {
978 if (!ImmOp->
isImm()) {
981 TII->legalizeOperandsVOP2(
MI.getMF()->getRegInfo(),
MI);
986 if (TotalOffset == 0) {
987 MI.setDesc(
TII->get(AMDGPU::COPY));
988 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
991 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
995 ImmOp->
setImm(TotalOffset);
1007 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1010 MI.getOperand(2).ChangeToRegister(BaseRegVGPR,
false);
1012 MI.getOperand(2).ChangeToRegister(BaseReg,
false);
1016 case AMDGPU::V_ADD_U32_e64:
1017 case AMDGPU::V_ADD_CO_U32_e64: {
1018 int Src0Idx =
MI.getNumExplicitDefs();
1024 if (!ImmOp->
isImm()) {
1026 TII->legalizeOperandsVOP3(
MI.getMF()->getRegInfo(),
MI);
1031 if (TotalOffset == 0) {
1032 MI.setDesc(
TII->get(AMDGPU::COPY));
1034 for (
unsigned I =
MI.getNumOperands() - 1;
I != 1; --
I)
1035 MI.removeOperand(
I);
1037 MI.getOperand(1).ChangeToRegister(BaseReg,
false);
1040 ImmOp->
setImm(TotalOffset);
1049 bool IsFlat =
TII->isFLATScratch(
MI);
1053 bool SeenFI =
false;
1065 TII->getNamedOperand(
MI, IsFlat ? AMDGPU::OpName::saddr
1066 : AMDGPU::OpName::vaddr);
1071 assert(FIOp && FIOp->
isFI() &&
"frame index must be address operand");
1077 "offset should be legal");
1088 assert(
TII->isLegalMUBUFImmOffset(NewOffset) &&
"offset should be legal");
1098 switch (
MI->getOpcode()) {
1099 case AMDGPU::V_ADD_U32_e32:
1100 case AMDGPU::V_ADD_CO_U32_e32:
1102 case AMDGPU::V_ADD_U32_e64:
1103 case AMDGPU::V_ADD_CO_U32_e64:
1116 return TII->isLegalMUBUFImmOffset(NewOffset);
1124 return RC == &AMDGPU::SCC_CLASSRegClass ? &AMDGPU::SReg_32RegClass : RC;
1130 unsigned Op =
MI.getOpcode();
1132 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
1133 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
1134 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE:
1139 (
uint64_t)
TII->getNamedOperand(
MI, AMDGPU::OpName::mask)->getImm());
1140 case AMDGPU::SI_SPILL_S1024_SAVE:
1141 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
1142 case AMDGPU::SI_SPILL_S1024_RESTORE:
1143 case AMDGPU::SI_SPILL_V1024_SAVE:
1144 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
1145 case AMDGPU::SI_SPILL_V1024_RESTORE:
1146 case AMDGPU::SI_SPILL_A1024_SAVE:
1147 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
1148 case AMDGPU::SI_SPILL_A1024_RESTORE:
1149 case AMDGPU::SI_SPILL_AV1024_SAVE:
1150 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
1151 case AMDGPU::SI_SPILL_AV1024_RESTORE:
1153 case AMDGPU::SI_SPILL_S512_SAVE:
1154 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
1155 case AMDGPU::SI_SPILL_S512_RESTORE:
1156 case AMDGPU::SI_SPILL_V512_SAVE:
1157 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
1158 case AMDGPU::SI_SPILL_V512_RESTORE:
1159 case AMDGPU::SI_SPILL_A512_SAVE:
1160 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
1161 case AMDGPU::SI_SPILL_A512_RESTORE:
1162 case AMDGPU::SI_SPILL_AV512_SAVE:
1163 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
1164 case AMDGPU::SI_SPILL_AV512_RESTORE:
1166 case AMDGPU::SI_SPILL_S384_SAVE:
1167 case AMDGPU::SI_SPILL_S384_RESTORE:
1168 case AMDGPU::SI_SPILL_V384_SAVE:
1169 case AMDGPU::SI_SPILL_V384_RESTORE:
1170 case AMDGPU::SI_SPILL_A384_SAVE:
1171 case AMDGPU::SI_SPILL_A384_RESTORE:
1172 case AMDGPU::SI_SPILL_AV384_SAVE:
1173 case AMDGPU::SI_SPILL_AV384_RESTORE:
1175 case AMDGPU::SI_SPILL_S352_SAVE:
1176 case AMDGPU::SI_SPILL_S352_RESTORE:
1177 case AMDGPU::SI_SPILL_V352_SAVE:
1178 case AMDGPU::SI_SPILL_V352_RESTORE:
1179 case AMDGPU::SI_SPILL_A352_SAVE:
1180 case AMDGPU::SI_SPILL_A352_RESTORE:
1181 case AMDGPU::SI_SPILL_AV352_SAVE:
1182 case AMDGPU::SI_SPILL_AV352_RESTORE:
1184 case AMDGPU::SI_SPILL_S320_SAVE:
1185 case AMDGPU::SI_SPILL_S320_RESTORE:
1186 case AMDGPU::SI_SPILL_V320_SAVE:
1187 case AMDGPU::SI_SPILL_V320_RESTORE:
1188 case AMDGPU::SI_SPILL_A320_SAVE:
1189 case AMDGPU::SI_SPILL_A320_RESTORE:
1190 case AMDGPU::SI_SPILL_AV320_SAVE:
1191 case AMDGPU::SI_SPILL_AV320_RESTORE:
1193 case AMDGPU::SI_SPILL_S288_SAVE:
1194 case AMDGPU::SI_SPILL_S288_RESTORE:
1195 case AMDGPU::SI_SPILL_V288_SAVE:
1196 case AMDGPU::SI_SPILL_V288_RESTORE:
1197 case AMDGPU::SI_SPILL_A288_SAVE:
1198 case AMDGPU::SI_SPILL_A288_RESTORE:
1199 case AMDGPU::SI_SPILL_AV288_SAVE:
1200 case AMDGPU::SI_SPILL_AV288_RESTORE:
1202 case AMDGPU::SI_SPILL_S256_SAVE:
1203 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
1204 case AMDGPU::SI_SPILL_S256_RESTORE:
1205 case AMDGPU::SI_SPILL_V256_SAVE:
1206 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
1207 case AMDGPU::SI_SPILL_V256_RESTORE:
1208 case AMDGPU::SI_SPILL_A256_SAVE:
1209 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
1210 case AMDGPU::SI_SPILL_A256_RESTORE:
1211 case AMDGPU::SI_SPILL_AV256_SAVE:
1212 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
1213 case AMDGPU::SI_SPILL_AV256_RESTORE:
1215 case AMDGPU::SI_SPILL_S224_SAVE:
1216 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
1217 case AMDGPU::SI_SPILL_S224_RESTORE:
1218 case AMDGPU::SI_SPILL_V224_SAVE:
1219 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
1220 case AMDGPU::SI_SPILL_V224_RESTORE:
1221 case AMDGPU::SI_SPILL_A224_SAVE:
1222 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
1223 case AMDGPU::SI_SPILL_A224_RESTORE:
1224 case AMDGPU::SI_SPILL_AV224_SAVE:
1225 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
1226 case AMDGPU::SI_SPILL_AV224_RESTORE:
1228 case AMDGPU::SI_SPILL_S192_SAVE:
1229 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
1230 case AMDGPU::SI_SPILL_S192_RESTORE:
1231 case AMDGPU::SI_SPILL_V192_SAVE:
1232 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
1233 case AMDGPU::SI_SPILL_V192_RESTORE:
1234 case AMDGPU::SI_SPILL_A192_SAVE:
1235 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
1236 case AMDGPU::SI_SPILL_A192_RESTORE:
1237 case AMDGPU::SI_SPILL_AV192_SAVE:
1238 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
1239 case AMDGPU::SI_SPILL_AV192_RESTORE:
1241 case AMDGPU::SI_SPILL_S160_SAVE:
1242 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
1243 case AMDGPU::SI_SPILL_S160_RESTORE:
1244 case AMDGPU::SI_SPILL_V160_SAVE:
1245 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
1246 case AMDGPU::SI_SPILL_V160_RESTORE:
1247 case AMDGPU::SI_SPILL_A160_SAVE:
1248 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
1249 case AMDGPU::SI_SPILL_A160_RESTORE:
1250 case AMDGPU::SI_SPILL_AV160_SAVE:
1251 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
1252 case AMDGPU::SI_SPILL_AV160_RESTORE:
1254 case AMDGPU::SI_SPILL_S128_SAVE:
1255 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
1256 case AMDGPU::SI_SPILL_S128_RESTORE:
1257 case AMDGPU::SI_SPILL_V128_SAVE:
1258 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
1259 case AMDGPU::SI_SPILL_V128_RESTORE:
1260 case AMDGPU::SI_SPILL_A128_SAVE:
1261 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
1262 case AMDGPU::SI_SPILL_A128_RESTORE:
1263 case AMDGPU::SI_SPILL_AV128_SAVE:
1264 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
1265 case AMDGPU::SI_SPILL_AV128_RESTORE:
1267 case AMDGPU::SI_SPILL_S96_SAVE:
1268 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
1269 case AMDGPU::SI_SPILL_S96_RESTORE:
1270 case AMDGPU::SI_SPILL_V96_SAVE:
1271 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
1272 case AMDGPU::SI_SPILL_V96_RESTORE:
1273 case AMDGPU::SI_SPILL_A96_SAVE:
1274 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
1275 case AMDGPU::SI_SPILL_A96_RESTORE:
1276 case AMDGPU::SI_SPILL_AV96_SAVE:
1277 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
1278 case AMDGPU::SI_SPILL_AV96_RESTORE:
1280 case AMDGPU::SI_SPILL_S64_SAVE:
1281 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
1282 case AMDGPU::SI_SPILL_S64_RESTORE:
1283 case AMDGPU::SI_SPILL_V64_SAVE:
1284 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
1285 case AMDGPU::SI_SPILL_V64_RESTORE:
1286 case AMDGPU::SI_SPILL_A64_SAVE:
1287 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
1288 case AMDGPU::SI_SPILL_A64_RESTORE:
1289 case AMDGPU::SI_SPILL_AV64_SAVE:
1290 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
1291 case AMDGPU::SI_SPILL_AV64_RESTORE:
1293 case AMDGPU::SI_SPILL_S32_SAVE:
1294 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
1295 case AMDGPU::SI_SPILL_S32_RESTORE:
1296 case AMDGPU::SI_SPILL_V32_SAVE:
1297 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
1298 case AMDGPU::SI_SPILL_V32_RESTORE:
1299 case AMDGPU::SI_SPILL_A32_SAVE:
1300 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
1301 case AMDGPU::SI_SPILL_A32_RESTORE:
1302 case AMDGPU::SI_SPILL_AV32_SAVE:
1303 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
1304 case AMDGPU::SI_SPILL_AV32_RESTORE:
1305 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
1306 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1307 case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1308 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
1309 case AMDGPU::SI_SPILL_V16_SAVE:
1310 case AMDGPU::SI_SPILL_V16_RESTORE:
1318 case AMDGPU::BUFFER_STORE_DWORD_OFFEN:
1319 return AMDGPU::BUFFER_STORE_DWORD_OFFSET;
1320 case AMDGPU::BUFFER_STORE_BYTE_OFFEN:
1321 return AMDGPU::BUFFER_STORE_BYTE_OFFSET;
1322 case AMDGPU::BUFFER_STORE_SHORT_OFFEN:
1323 return AMDGPU::BUFFER_STORE_SHORT_OFFSET;
1324 case AMDGPU::BUFFER_STORE_DWORDX2_OFFEN:
1325 return AMDGPU::BUFFER_STORE_DWORDX2_OFFSET;
1326 case AMDGPU::BUFFER_STORE_DWORDX3_OFFEN:
1327 return AMDGPU::BUFFER_STORE_DWORDX3_OFFSET;
1328 case AMDGPU::BUFFER_STORE_DWORDX4_OFFEN:
1329 return AMDGPU::BUFFER_STORE_DWORDX4_OFFSET;
1330 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN:
1331 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET;
1332 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN:
1333 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET;
1341 case AMDGPU::BUFFER_LOAD_DWORD_OFFEN:
1342 return AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
1343 case AMDGPU::BUFFER_LOAD_UBYTE_OFFEN:
1344 return AMDGPU::BUFFER_LOAD_UBYTE_OFFSET;
1345 case AMDGPU::BUFFER_LOAD_SBYTE_OFFEN:
1346 return AMDGPU::BUFFER_LOAD_SBYTE_OFFSET;
1347 case AMDGPU::BUFFER_LOAD_USHORT_OFFEN:
1348 return AMDGPU::BUFFER_LOAD_USHORT_OFFSET;
1349 case AMDGPU::BUFFER_LOAD_SSHORT_OFFEN:
1350 return AMDGPU::BUFFER_LOAD_SSHORT_OFFSET;
1351 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN:
1352 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET;
1353 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN:
1354 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET;
1355 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN:
1356 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET;
1357 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN:
1358 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET;
1359 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN:
1360 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET;
1361 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN:
1362 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET;
1363 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN:
1364 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET;
1365 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN:
1366 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET;
1367 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN:
1368 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET;
1376 case AMDGPU::BUFFER_STORE_DWORD_OFFSET:
1377 return AMDGPU::BUFFER_STORE_DWORD_OFFEN;
1378 case AMDGPU::BUFFER_STORE_BYTE_OFFSET:
1379 return AMDGPU::BUFFER_STORE_BYTE_OFFEN;
1380 case AMDGPU::BUFFER_STORE_SHORT_OFFSET:
1381 return AMDGPU::BUFFER_STORE_SHORT_OFFEN;
1382 case AMDGPU::BUFFER_STORE_DWORDX2_OFFSET:
1383 return AMDGPU::BUFFER_STORE_DWORDX2_OFFEN;
1384 case AMDGPU::BUFFER_STORE_DWORDX3_OFFSET:
1385 return AMDGPU::BUFFER_STORE_DWORDX3_OFFEN;
1386 case AMDGPU::BUFFER_STORE_DWORDX4_OFFSET:
1387 return AMDGPU::BUFFER_STORE_DWORDX4_OFFEN;
1388 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET:
1389 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN;
1390 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET:
1391 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN;
1399 case AMDGPU::BUFFER_LOAD_DWORD_OFFSET:
1400 return AMDGPU::BUFFER_LOAD_DWORD_OFFEN;
1401 case AMDGPU::BUFFER_LOAD_UBYTE_OFFSET:
1402 return AMDGPU::BUFFER_LOAD_UBYTE_OFFEN;
1403 case AMDGPU::BUFFER_LOAD_SBYTE_OFFSET:
1404 return AMDGPU::BUFFER_LOAD_SBYTE_OFFEN;
1405 case AMDGPU::BUFFER_LOAD_USHORT_OFFSET:
1406 return AMDGPU::BUFFER_LOAD_USHORT_OFFEN;
1407 case AMDGPU::BUFFER_LOAD_SSHORT_OFFSET:
1408 return AMDGPU::BUFFER_LOAD_SSHORT_OFFEN;
1409 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET:
1410 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN;
1411 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET:
1412 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN;
1413 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET:
1414 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN;
1415 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET:
1416 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN;
1417 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET:
1418 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN;
1419 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET:
1420 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN;
1421 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET:
1422 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN;
1423 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET:
1424 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN;
1425 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET:
1426 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN;
1435 unsigned ValueReg,
bool IsKill,
bool NeedsCFI) {
1443 if (
Reg == AMDGPU::NoRegister)
1446 bool IsStore =
MI->mayStore();
1450 unsigned Dst = IsStore ?
Reg : ValueReg;
1451 unsigned Src = IsStore ? ValueReg :
Reg;
1454 if (IsVGPR ==
TRI->isVGPR(
MRI, ValueReg)) {
1466 unsigned Opc = (IsStore ^ IsVGPR) ? AMDGPU::V_ACCVGPR_WRITE_B32_e64
1467 : AMDGPU::V_ACCVGPR_READ_B32_e64;
1487 bool IsStore =
MI->mayStore();
1489 unsigned Opc =
MI->getOpcode();
1490 int LoadStoreOp = IsStore ?
1492 if (LoadStoreOp == -1)
1503 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::srsrc))
1504 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset))
1511 AMDGPU::OpName::vdata_in);
1513 NewMI.
add(*VDataIn);
1518 unsigned LoadStoreOp,
1520 bool IsStore =
TII->get(LoadStoreOp).mayStore();
1526 if (
TII->isBlockLoadStore(LoadStoreOp))
1531 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
1532 : AMDGPU::SCRATCH_LOAD_DWORD_SADDR;
1535 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX2_SADDR
1536 : AMDGPU::SCRATCH_LOAD_DWORDX2_SADDR;
1539 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX3_SADDR
1540 : AMDGPU::SCRATCH_LOAD_DWORDX3_SADDR;
1543 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX4_SADDR
1544 : AMDGPU::SCRATCH_LOAD_DWORDX4_SADDR;
1560 unsigned LoadStoreOp,
int Index,
Register ValueReg,
bool IsKill,
1563 assert((!RS || !LiveUnits) &&
"Only RS or LiveUnits can be set but not both");
1572 bool IsStore =
Desc->mayStore();
1573 bool IsFlat =
TII->isFLATScratch(LoadStoreOp);
1574 bool IsBlock =
TII->isBlockLoadStore(LoadStoreOp);
1576 bool CanClobberSCC =
false;
1577 bool Scavenged =
false;
1582 const bool IsAGPR = !ST.hasGFX90AInsts() &&
isAGPRClass(RC);
1593 bool IsRegMisaligned =
false;
1594 if (!IsBlock && !IsAGPR && RegWidth > 4 && IsFlat) {
1595 unsigned SpillOpcode =
1598 IsStore ? AMDGPU::getNamedOperandIdx(SpillOpcode, AMDGPU::OpName::vdata)
1601 TII->getRegClass(
TII->get(SpillOpcode), VDataIdx);
1602 if (!ExpectedRC->
contains(ValueReg)) {
1606 getMatchingSuperRegClass(RC, ExpectedRC, SubIdx);
1607 if (!MatchRC || !MatchRC->
contains(ValueReg))
1608 IsRegMisaligned =
true;
1612 if (IsRegMisaligned)
1617 unsigned EltSize = IsBlock ? RegWidth
1618 : (IsFlat && !IsAGPR) ? std::min(RegWidth, 16u)
1620 unsigned NumSubRegs = RegWidth / EltSize;
1621 unsigned Size = NumSubRegs * EltSize;
1622 unsigned RemSize = RegWidth -
Size;
1623 unsigned NumRemSubRegs = RemSize ? 1 : 0;
1625 if (IsRegMisaligned)
1628 int64_t MaterializedOffset =
Offset;
1633 int64_t MaxOffset =
Offset +
Size - (RemSize ? 0 : EltSize);
1634 int64_t ScratchOffsetRegDelta = 0;
1635 int64_t AdditionalCFIOffset = 0;
1637 if (IsFlat && EltSize > 4) {
1639 Desc = &
TII->get(LoadStoreOp);
1646 "unexpected VGPR spill offset");
1653 bool UseVGPROffset =
false;
1660 if (IsFlat && SGPRBase) {
1665 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) >= 2) {
1684 bool IsOffsetLegal =
1687 :
TII->isLegalMUBUFImmOffset(MaxOffset);
1688 if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
1696 SOffset = RS->scavengeRegisterBackwards(AMDGPU::SGPR_32RegClass,
MI,
false, 0,
false);
1699 CanClobberSCC = !RS->isRegUsed(AMDGPU::SCC);
1700 }
else if (LiveUnits) {
1701 CanClobberSCC = LiveUnits->
available(AMDGPU::SCC);
1702 for (
MCRegister Reg : AMDGPU::SGPR_32RegClass) {
1710 if (ScratchOffsetReg != AMDGPU::NoRegister && !CanClobberSCC)
1714 UseVGPROffset =
true;
1717 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1720 for (
MCRegister Reg : AMDGPU::VGPR_32RegClass) {
1722 TmpOffsetVGPR = Reg;
1729 }
else if (!SOffset && CanClobberSCC) {
1740 if (!ScratchOffsetReg)
1742 SOffset = ScratchOffsetReg;
1743 ScratchOffsetRegDelta =
Offset;
1748 AdditionalCFIOffset =
Offset;
1752 if (!IsFlat && !UseVGPROffset)
1753 Offset *= ST.getWavefrontSize();
1755 if (!UseVGPROffset && !SOffset)
1758 if (UseVGPROffset) {
1760 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR,
Offset);
1761 }
else if (ScratchOffsetReg == AMDGPU::NoRegister) {
1766 .
addReg(ScratchOffsetReg)
1768 Add->getOperand(3).setIsDead();
1774 if (IsFlat && SOffset == AMDGPU::NoRegister) {
1775 assert(AMDGPU::getNamedOperandIdx(LoadStoreOp, AMDGPU::OpName::vaddr) < 0
1776 &&
"Unexpected vaddr for flat scratch with a FI operand");
1778 if (UseVGPROffset) {
1781 assert(ST.hasFlatScratchSTMode());
1782 assert(!
TII->isBlockLoadStore(LoadStoreOp) &&
"Block ops don't have ST");
1786 Desc = &
TII->get(LoadStoreOp);
1791 unsigned OrigEltSize = EltSize;
1792 for (
unsigned i = 0, e = NumSubRegs + NumRemSubRegs, RegOffset = 0; i != e;
1793 ++i, RegOffset += EltSize) {
1794 if (IsRegMisaligned) {
1802 IsRegMisaligned =
false;
1803 EltSize = OrigEltSize;
1807 if (i == NumSubRegs) {
1811 Desc = &
TII->get(LoadStoreOp);
1813 if (!IsFlat && UseVGPROffset) {
1816 Desc = &
TII->get(NewLoadStoreOp);
1819 if (UseVGPROffset && TmpOffsetVGPR == TmpIntermediateVGPR) {
1826 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, MaterializedOffset);
1829 unsigned NumRegs = EltSize / 4;
1837 const bool IsLastSubReg = i + 1 == e;
1838 const bool IsFirstSubReg = i == 0;
1847 bool NeedSuperRegDef = e > 1 && IsStore && IsFirstSubReg;
1848 bool NeedSuperRegImpOperand = e > 1;
1852 unsigned RemEltSize = EltSize;
1860 for (
int LaneS = (RegOffset + EltSize) / 4 - 1, Lane = LaneS,
1861 LaneE = RegOffset / 4;
1862 Lane >= LaneE; --Lane) {
1863 bool IsSubReg = e > 1 || EltSize > 4;
1869 if (!MIB.getInstr())
1871 if (NeedSuperRegDef || (IsSubReg && IsStore && Lane == LaneS && IsFirstSubReg)) {
1873 NeedSuperRegDef =
false;
1875 if ((IsSubReg || NeedSuperRegImpOperand) && (IsFirstSubReg || IsLastSubReg)) {
1876 NeedSuperRegImpOperand =
true;
1878 if (!IsLastSubReg || (Lane != LaneE))
1880 if (!IsFirstSubReg || (Lane != LaneS))
1890 if (RemEltSize != EltSize) {
1891 assert(IsFlat && EltSize > 4);
1893 unsigned NumRegs = RemEltSize / 4;
1894 SubReg =
Register(getSubReg(ValueReg,
1900 unsigned FinalReg = SubReg;
1905 if (!TmpIntermediateVGPR) {
1911 TII->get(AMDGPU::V_ACCVGPR_READ_B32_e64),
1912 TmpIntermediateVGPR)
1914 if (NeedSuperRegDef)
1916 if (NeedSuperRegImpOperand && (IsFirstSubReg || IsLastSubReg))
1920 SubReg = TmpIntermediateVGPR;
1921 }
else if (UseVGPROffset) {
1922 if (!TmpOffsetVGPR) {
1923 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
1925 RS->setRegUsed(TmpOffsetVGPR);
1930 if (LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_SADDR ||
1931 LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_ST) {
1935 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
MI,
false, 0);
1951 if (UseVGPROffset) {
1960 if (SOffset == AMDGPU::NoRegister) {
1962 if (UseVGPROffset && ScratchOffsetReg) {
1963 MIB.addReg(ScratchOffsetReg);
1970 MIB.addReg(SOffset, SOffsetRegState);
1980 MIB.addMemOperand(NewMMO);
1982 if (FinalValueReg != ValueReg) {
1984 ValueReg = getSubReg(ValueReg, AMDGPU::lo16);
1990 ValueReg = FinalValueReg;
1993 if (IsStore && NeedsCFI) {
1994 if (
TII->isBlockLoadStore(LoadStoreOp)) {
1996 "expected whole register block to be treated as single element");
2001 (
Offset + RegOffset) * ST.getWavefrontSize() + AdditionalCFIOffset);
2005 if (!IsAGPR && NeedSuperRegDef)
2008 if (!IsStore && IsAGPR && TmpIntermediateVGPR != AMDGPU::NoRegister) {
2016 bool PartialReloadCopy = (RemEltSize != EltSize) && !IsStore;
2017 if (NeedSuperRegImpOperand &&
2018 (IsFirstSubReg || (IsLastSubReg && !IsSrcDstDef))) {
2020 if (PartialReloadCopy)
2045 if (!IsStore &&
MI !=
MBB.end() &&
MI->isReturn() &&
2046 MI->readsRegister(SubReg,
this)) {
2048 MIB->tieOperands(0, MIB->getNumOperands() - 1);
2056 if (!IsStore &&
TII->isBlockLoadStore(LoadStoreOp))
2060 if (ScratchOffsetRegDelta != 0) {
2064 .
addImm(-ScratchOffsetRegDelta);
2073 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2074 for (
unsigned RegOffset = 1; RegOffset < 32; ++RegOffset)
2075 if (!(Mask & (1 << RegOffset)) &&
2076 isCalleeSavedPhysReg(BaseVGPR + RegOffset, *MF))
2087 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2088 for (
unsigned RegOffset = 0; RegOffset < 32; ++RegOffset) {
2089 Register VGPR = BaseVGPR + RegOffset;
2090 if (Mask & (1 << RegOffset)) {
2091 assert(isCalleeSavedPhysReg(VGPR, *MF));
2092 ST.getFrameLowering()->buildCFIForVGPRToVMEMSpill(
2094 (
Offset + RegOffset) * ST.getWavefrontSize());
2095 }
else if (isCalleeSavedPhysReg(VGPR, *MF)) {
2100 BaseVGPR + RegOffset);
2107 bool IsKill)
const {
2117 Align Alignment = FrameInfo.getObjectAlign(Index);
2124 unsigned Opc = ST.hasFlatScratchEnabled()
2125 ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2126 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2130 unsigned Opc = ST.hasFlatScratchEnabled()
2131 ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2132 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2143 bool SpillToPhysVGPRLane,
bool NeedsCFI)
const {
2144 assert(!
MI->getOperand(0).isUndef() &&
2145 "undef spill should have been deleted earlier");
2152 bool SpillToVGPR = !VGPRSpills.
empty();
2153 if (OnlyToVGPR && !SpillToVGPR)
2168 "Num of SGPRs spilled should be less than or equal to num of "
2171 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2178 bool IsFirstSubreg = i == 0;
2180 bool UseKill = SB.
IsKill && IsLastSubreg;
2186 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), Spill.VGPR)
2196 AMDGPU::PC_REG, VGPRSpills);
2199 Spill.VGPR, Spill.Lane);
2219 if (SB.
NumSubRegs > 1 && (IsFirstSubreg || IsLastSubreg))
2239 for (
unsigned i =
Offset * PVD.PerVGPR,
2249 SB.
TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), SB.
TmpVGPR)
2250 .
addReg(SubReg, SubKillState)
2281 ST.getWavefrontSize();
2283 AMDGPU::PC_REG, CFIOffset);
2292 MI->eraseFromParent();
2304 bool SpillToPhysVGPRLane)
const {
2310 bool SpillToVGPR = !VGPRSpills.
empty();
2311 if (OnlyToVGPR && !SpillToVGPR)
2315 for (
unsigned i = 0, e = SB.
NumSubRegs; i < e; ++i) {
2323 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2346 for (
unsigned i =
Offset * PVD.PerVGPR,
2354 bool LastSubReg = (i + 1 == e);
2356 SB.
TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2373 MI->eraseFromParent();
2393 for (
unsigned i =
Offset * PVD.PerVGPR,
2404 .
addReg(SubReg, SubKillState)
2422 MI = RestoreMBB.
end();
2428 for (
unsigned i =
Offset * PVD.PerVGPR,
2437 bool LastSubReg = (i + 1 == e);
2458 bool NeedsCFI =
false;
2459 switch (
MI->getOpcode()) {
2460 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2461 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2462 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2463 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2464 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2465 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2466 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2467 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2468 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2469 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
2472 case AMDGPU::SI_SPILL_S1024_SAVE:
2473 case AMDGPU::SI_SPILL_S512_SAVE:
2474 case AMDGPU::SI_SPILL_S384_SAVE:
2475 case AMDGPU::SI_SPILL_S352_SAVE:
2476 case AMDGPU::SI_SPILL_S320_SAVE:
2477 case AMDGPU::SI_SPILL_S288_SAVE:
2478 case AMDGPU::SI_SPILL_S256_SAVE:
2479 case AMDGPU::SI_SPILL_S224_SAVE:
2480 case AMDGPU::SI_SPILL_S192_SAVE:
2481 case AMDGPU::SI_SPILL_S160_SAVE:
2482 case AMDGPU::SI_SPILL_S128_SAVE:
2483 case AMDGPU::SI_SPILL_S96_SAVE:
2484 case AMDGPU::SI_SPILL_S64_SAVE:
2485 case AMDGPU::SI_SPILL_S32_SAVE:
2486 return spillSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane,
2488 case AMDGPU::SI_SPILL_S1024_RESTORE:
2489 case AMDGPU::SI_SPILL_S512_RESTORE:
2490 case AMDGPU::SI_SPILL_S384_RESTORE:
2491 case AMDGPU::SI_SPILL_S352_RESTORE:
2492 case AMDGPU::SI_SPILL_S320_RESTORE:
2493 case AMDGPU::SI_SPILL_S288_RESTORE:
2494 case AMDGPU::SI_SPILL_S256_RESTORE:
2495 case AMDGPU::SI_SPILL_S224_RESTORE:
2496 case AMDGPU::SI_SPILL_S192_RESTORE:
2497 case AMDGPU::SI_SPILL_S160_RESTORE:
2498 case AMDGPU::SI_SPILL_S128_RESTORE:
2499 case AMDGPU::SI_SPILL_S96_RESTORE:
2500 case AMDGPU::SI_SPILL_S64_RESTORE:
2501 case AMDGPU::SI_SPILL_S32_RESTORE:
2502 return restoreSGPR(
MI, FI, RS, Indexes, LIS,
true, SpillToPhysVGPRLane);
2525 return (RS.isRegUsed(AMDGPU::SCC) &&
2526 !
MI.definesRegister(AMDGPU::SCC,
nullptr)) ||
2527 MI.readsRegister(AMDGPU::SCC,
nullptr);
2531 int SPAdj,
unsigned FIOperandNum,
2540 assert(SPAdj == 0 &&
"unhandled SP adjustment in call sequence?");
2543 "unreserved scratch RSRC register");
2546 int Index =
MI->getOperand(FIOperandNum).getIndex();
2552 bool NeedsCFI =
false;
2554 switch (
MI->getOpcode()) {
2556 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2557 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2558 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2559 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2560 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2561 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2562 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2563 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2564 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2565 case AMDGPU::SI_SPILL_S32_CFI_SAVE: {
2569 case AMDGPU::SI_SPILL_S1024_SAVE:
2570 case AMDGPU::SI_SPILL_S512_SAVE:
2571 case AMDGPU::SI_SPILL_S384_SAVE:
2572 case AMDGPU::SI_SPILL_S352_SAVE:
2573 case AMDGPU::SI_SPILL_S320_SAVE:
2574 case AMDGPU::SI_SPILL_S288_SAVE:
2575 case AMDGPU::SI_SPILL_S256_SAVE:
2576 case AMDGPU::SI_SPILL_S224_SAVE:
2577 case AMDGPU::SI_SPILL_S192_SAVE:
2578 case AMDGPU::SI_SPILL_S160_SAVE:
2579 case AMDGPU::SI_SPILL_S128_SAVE:
2580 case AMDGPU::SI_SPILL_S96_SAVE:
2581 case AMDGPU::SI_SPILL_S64_SAVE:
2582 case AMDGPU::SI_SPILL_S32_SAVE: {
2589 case AMDGPU::SI_SPILL_S1024_RESTORE:
2590 case AMDGPU::SI_SPILL_S512_RESTORE:
2591 case AMDGPU::SI_SPILL_S384_RESTORE:
2592 case AMDGPU::SI_SPILL_S352_RESTORE:
2593 case AMDGPU::SI_SPILL_S320_RESTORE:
2594 case AMDGPU::SI_SPILL_S288_RESTORE:
2595 case AMDGPU::SI_SPILL_S256_RESTORE:
2596 case AMDGPU::SI_SPILL_S224_RESTORE:
2597 case AMDGPU::SI_SPILL_S192_RESTORE:
2598 case AMDGPU::SI_SPILL_S160_RESTORE:
2599 case AMDGPU::SI_SPILL_S128_RESTORE:
2600 case AMDGPU::SI_SPILL_S96_RESTORE:
2601 case AMDGPU::SI_SPILL_S64_RESTORE:
2602 case AMDGPU::SI_SPILL_S32_RESTORE: {
2604 FrameInfo.getStackID(Index) ==
2609 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
2610 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
2611 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
2612 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
2613 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
2614 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
2615 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
2616 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
2617 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
2618 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
2619 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
2620 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
2621 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
2622 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
2623 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
2624 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
2625 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
2626 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
2627 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
2628 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
2629 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
2630 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
2631 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
2632 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
2633 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
2634 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
2635 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
2636 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
2637 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
2638 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
2639 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
2642 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
2643 case AMDGPU::SI_SPILL_V1024_SAVE:
2644 case AMDGPU::SI_SPILL_V512_SAVE:
2645 case AMDGPU::SI_SPILL_V384_SAVE:
2646 case AMDGPU::SI_SPILL_V352_SAVE:
2647 case AMDGPU::SI_SPILL_V320_SAVE:
2648 case AMDGPU::SI_SPILL_V288_SAVE:
2649 case AMDGPU::SI_SPILL_V256_SAVE:
2650 case AMDGPU::SI_SPILL_V224_SAVE:
2651 case AMDGPU::SI_SPILL_V192_SAVE:
2652 case AMDGPU::SI_SPILL_V160_SAVE:
2653 case AMDGPU::SI_SPILL_V128_SAVE:
2654 case AMDGPU::SI_SPILL_V96_SAVE:
2655 case AMDGPU::SI_SPILL_V64_SAVE:
2656 case AMDGPU::SI_SPILL_V32_SAVE:
2657 case AMDGPU::SI_SPILL_V16_SAVE:
2658 case AMDGPU::SI_SPILL_A1024_SAVE:
2659 case AMDGPU::SI_SPILL_A512_SAVE:
2660 case AMDGPU::SI_SPILL_A384_SAVE:
2661 case AMDGPU::SI_SPILL_A352_SAVE:
2662 case AMDGPU::SI_SPILL_A320_SAVE:
2663 case AMDGPU::SI_SPILL_A288_SAVE:
2664 case AMDGPU::SI_SPILL_A256_SAVE:
2665 case AMDGPU::SI_SPILL_A224_SAVE:
2666 case AMDGPU::SI_SPILL_A192_SAVE:
2667 case AMDGPU::SI_SPILL_A160_SAVE:
2668 case AMDGPU::SI_SPILL_A128_SAVE:
2669 case AMDGPU::SI_SPILL_A96_SAVE:
2670 case AMDGPU::SI_SPILL_A64_SAVE:
2671 case AMDGPU::SI_SPILL_A32_SAVE:
2672 case AMDGPU::SI_SPILL_AV1024_SAVE:
2673 case AMDGPU::SI_SPILL_AV512_SAVE:
2674 case AMDGPU::SI_SPILL_AV384_SAVE:
2675 case AMDGPU::SI_SPILL_AV352_SAVE:
2676 case AMDGPU::SI_SPILL_AV320_SAVE:
2677 case AMDGPU::SI_SPILL_AV288_SAVE:
2678 case AMDGPU::SI_SPILL_AV256_SAVE:
2679 case AMDGPU::SI_SPILL_AV224_SAVE:
2680 case AMDGPU::SI_SPILL_AV192_SAVE:
2681 case AMDGPU::SI_SPILL_AV160_SAVE:
2682 case AMDGPU::SI_SPILL_AV128_SAVE:
2683 case AMDGPU::SI_SPILL_AV96_SAVE:
2684 case AMDGPU::SI_SPILL_AV64_SAVE:
2685 case AMDGPU::SI_SPILL_AV32_SAVE:
2686 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2687 case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
2689 MI->getOpcode() != AMDGPU::SI_BLOCK_SPILL_V1024_SAVE &&
2690 "block spill does not currenty support spilling non-CSR registers");
2692 if (
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE)
2696 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2699 AMDGPU::OpName::vdata);
2701 MI->eraseFromParent();
2705 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2709 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_SAVE) {
2710 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2711 Opc = AMDGPU::SCRATCH_STORE_SHORT_SADDR_t16;
2713 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE
2714 ? AMDGPU::SCRATCH_STORE_BLOCK_SADDR
2715 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2716 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2719 auto *
MBB =
MI->getParent();
2720 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2721 if (IsWWMRegSpill) {
2723 RS->isRegUsed(AMDGPU::SCC));
2727 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2728 *
MI->memoperands_begin(), RS,
nullptr, NeedsCFI);
2733 MI->eraseFromParent();
2736 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE: {
2740 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::mask));
2743 case AMDGPU::SI_SPILL_V16_RESTORE:
2744 case AMDGPU::SI_SPILL_V32_RESTORE:
2745 case AMDGPU::SI_SPILL_V64_RESTORE:
2746 case AMDGPU::SI_SPILL_V96_RESTORE:
2747 case AMDGPU::SI_SPILL_V128_RESTORE:
2748 case AMDGPU::SI_SPILL_V160_RESTORE:
2749 case AMDGPU::SI_SPILL_V192_RESTORE:
2750 case AMDGPU::SI_SPILL_V224_RESTORE:
2751 case AMDGPU::SI_SPILL_V256_RESTORE:
2752 case AMDGPU::SI_SPILL_V288_RESTORE:
2753 case AMDGPU::SI_SPILL_V320_RESTORE:
2754 case AMDGPU::SI_SPILL_V352_RESTORE:
2755 case AMDGPU::SI_SPILL_V384_RESTORE:
2756 case AMDGPU::SI_SPILL_V512_RESTORE:
2757 case AMDGPU::SI_SPILL_V1024_RESTORE:
2758 case AMDGPU::SI_SPILL_A32_RESTORE:
2759 case AMDGPU::SI_SPILL_A64_RESTORE:
2760 case AMDGPU::SI_SPILL_A96_RESTORE:
2761 case AMDGPU::SI_SPILL_A128_RESTORE:
2762 case AMDGPU::SI_SPILL_A160_RESTORE:
2763 case AMDGPU::SI_SPILL_A192_RESTORE:
2764 case AMDGPU::SI_SPILL_A224_RESTORE:
2765 case AMDGPU::SI_SPILL_A256_RESTORE:
2766 case AMDGPU::SI_SPILL_A288_RESTORE:
2767 case AMDGPU::SI_SPILL_A320_RESTORE:
2768 case AMDGPU::SI_SPILL_A352_RESTORE:
2769 case AMDGPU::SI_SPILL_A384_RESTORE:
2770 case AMDGPU::SI_SPILL_A512_RESTORE:
2771 case AMDGPU::SI_SPILL_A1024_RESTORE:
2772 case AMDGPU::SI_SPILL_AV32_RESTORE:
2773 case AMDGPU::SI_SPILL_AV64_RESTORE:
2774 case AMDGPU::SI_SPILL_AV96_RESTORE:
2775 case AMDGPU::SI_SPILL_AV128_RESTORE:
2776 case AMDGPU::SI_SPILL_AV160_RESTORE:
2777 case AMDGPU::SI_SPILL_AV192_RESTORE:
2778 case AMDGPU::SI_SPILL_AV224_RESTORE:
2779 case AMDGPU::SI_SPILL_AV256_RESTORE:
2780 case AMDGPU::SI_SPILL_AV288_RESTORE:
2781 case AMDGPU::SI_SPILL_AV320_RESTORE:
2782 case AMDGPU::SI_SPILL_AV352_RESTORE:
2783 case AMDGPU::SI_SPILL_AV384_RESTORE:
2784 case AMDGPU::SI_SPILL_AV512_RESTORE:
2785 case AMDGPU::SI_SPILL_AV1024_RESTORE:
2786 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2787 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
2789 AMDGPU::OpName::vdata);
2790 assert(
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset)->getReg() ==
2794 if (
MI->getOpcode() == AMDGPU::SI_SPILL_V16_RESTORE) {
2795 assert(ST.hasFlatScratchEnabled() &&
"Flat Scratch is not enabled!");
2796 Opc = ST.d16PreservesUnusedBits()
2797 ? AMDGPU::SCRATCH_LOAD_SHORT_D16_SADDR_t16
2798 : AMDGPU::SCRATCH_LOAD_USHORT_SADDR;
2800 Opc =
MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE
2801 ? AMDGPU::SCRATCH_LOAD_BLOCK_SADDR
2802 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2803 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2806 auto *
MBB =
MI->getParent();
2807 bool IsWWMRegSpill =
TII->isWWMRegSpillOpcode(
MI->getOpcode());
2808 if (IsWWMRegSpill) {
2810 RS->isRegUsed(AMDGPU::SCC));
2815 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm(),
2816 *
MI->memoperands_begin(), RS);
2821 MI->eraseFromParent();
2824 case AMDGPU::V_ADD_U32_e32:
2825 case AMDGPU::V_ADD_U32_e64:
2826 case AMDGPU::V_ADD_CO_U32_e32:
2827 case AMDGPU::V_ADD_CO_U32_e64: {
2829 unsigned NumDefs =
MI->getNumExplicitDefs();
2830 unsigned Src0Idx = NumDefs;
2832 bool HasClamp =
false;
2835 switch (
MI->getOpcode()) {
2836 case AMDGPU::V_ADD_U32_e32:
2838 case AMDGPU::V_ADD_U32_e64:
2839 HasClamp =
MI->getOperand(3).getImm();
2841 case AMDGPU::V_ADD_CO_U32_e32:
2842 VCCOp = &
MI->getOperand(3);
2844 case AMDGPU::V_ADD_CO_U32_e64:
2845 VCCOp = &
MI->getOperand(1);
2846 HasClamp =
MI->getOperand(4).getImm();
2851 bool DeadVCC = !VCCOp || VCCOp->
isDead();
2855 unsigned OtherOpIdx =
2856 FIOperandNum == Src0Idx ? FIOperandNum + 1 : Src0Idx;
2859 unsigned Src1Idx = Src0Idx + 1;
2860 Register MaterializedReg = FrameReg;
2863 int64_t
Offset = FrameInfo.getObjectOffset(Index);
2867 if ((!DeadVCC || HasClamp) &&
2874 if (OtherOp->
isImm()) {
2885 OtherOp->
setImm(TotalOffset);
2889 if (FrameReg && !ST.hasFlatScratchEnabled()) {
2897 ScavengedVGPR = RS->scavengeRegisterBackwards(
2898 AMDGPU::VGPR_32RegClass,
MI,
false, 0);
2904 .
addImm(ST.getWavefrontSizeLog2())
2906 MaterializedReg = ScavengedVGPR;
2909 if ((!OtherOp->
isImm() || OtherOp->
getImm() != 0) && MaterializedReg) {
2910 if (OtherOp->
isImm()) {
2912 FIOp->
setIsKill(MaterializedReg != FrameReg);
2914 if (ST.hasFlatScratchEnabled() &&
2915 !
TII->isOperandLegal(*
MI, Src1Idx, OtherOp)) {
2923 if (!ScavengedVGPR) {
2924 ScavengedVGPR = RS->scavengeRegisterBackwards(
2925 AMDGPU::VGPR_32RegClass,
MI,
false,
2929 assert(ScavengedVGPR != DstReg);
2935 MaterializedReg = ScavengedVGPR;
2944 AddI32.
add(
MI->getOperand(1));
2949 if (
isVGPRClass(getPhysRegBaseClass(MaterializedReg))) {
2952 AddI32.add(*OtherOp).addReg(MaterializedReg, MaterializedRegFlags);
2956 AddI32.addReg(MaterializedReg, MaterializedRegFlags).add(*OtherOp);
2959 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
2960 MI->getOpcode() == AMDGPU::V_ADD_U32_e64)
2963 if (
MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e32)
2964 AddI32.setOperandDead(3);
2966 MaterializedReg = DstReg;
2973 }
else if (
Offset != 0) {
2974 assert(!MaterializedReg);
2978 if (DeadVCC && !HasClamp) {
2983 if (OtherOp->
isReg() && OtherOp->
getReg() == DstReg) {
2985 MI->eraseFromParent();
2990 MI->setDesc(
TII->get(AMDGPU::V_MOV_B32_e32));
2991 MI->removeOperand(FIOperandNum);
2993 unsigned NumOps =
MI->getNumOperands();
2994 for (
unsigned I =
NumOps - 2;
I >= NumDefs + 1; --
I)
2995 MI->removeOperand(
I);
2998 MI->removeOperand(1);
3010 if (!
TII->isOperandLegal(*
MI, Src1Idx) &&
TII->commuteInstruction(*
MI)) {
3018 for (
unsigned SrcIdx : {FIOperandNum, OtherOpIdx}) {
3019 if (!
TII->isOperandLegal(*
MI, SrcIdx)) {
3023 if (!ScavengedVGPR) {
3024 ScavengedVGPR = RS->scavengeRegisterBackwards(
3025 AMDGPU::VGPR_32RegClass,
MI,
false,
3029 assert(ScavengedVGPR != DstReg);
3035 Src.ChangeToRegister(ScavengedVGPR,
false);
3036 Src.setIsKill(
true);
3042 if (FIOp->
isImm() && FIOp->
getImm() == 0 && DeadVCC && !HasClamp) {
3043 if (OtherOp->
isReg() && OtherOp->
getReg() != DstReg) {
3047 MI->eraseFromParent();
3052 case AMDGPU::S_ADD_I32:
3053 case AMDGPU::S_ADD_U32: {
3055 unsigned OtherOpIdx = FIOperandNum == 1 ? 2 : 1;
3062 Register MaterializedReg = FrameReg;
3064 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3067 bool DeadSCC =
MI->getOperand(3).isDead();
3078 if (FrameReg && !ST.hasFlatScratchEnabled()) {
3083 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3090 .
addImm(ST.getWavefrontSizeLog2())
3093 MaterializedReg = TmpReg;
3099 if (OtherOp.
isImm()) {
3103 if (MaterializedReg)
3107 }
else if (MaterializedReg) {
3111 if (!TmpReg && MaterializedReg == FrameReg) {
3112 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3126 MaterializedReg = DstReg;
3139 if (DeadSCC && OtherOp.
isImm() && OtherOp.
getImm() == 0) {
3141 MI->removeOperand(3);
3142 MI->removeOperand(OtherOpIdx);
3144 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3145 }
else if (DeadSCC && FIOp->
isImm() && FIOp->
getImm() == 0) {
3147 MI->removeOperand(3);
3148 MI->removeOperand(FIOperandNum);
3150 MI->setDesc(
TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3161 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3162 if (ST.hasFlatScratchEnabled()) {
3163 if (
TII->isFLATScratch(*
MI)) {
3165 (int16_t)FIOperandNum ==
3166 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::saddr));
3173 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset);
3184 unsigned Opc =
MI->getOpcode();
3188 }
else if (ST.hasFlatScratchSTMode()) {
3198 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
3199 bool TiedVDst = VDstIn != -1 &&
MI->getOperand(VDstIn).isReg() &&
3200 MI->getOperand(VDstIn).isTied();
3202 MI->untieRegOperand(VDstIn);
3205 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::saddr));
3209 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
3211 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
3212 assert(NewVDst != -1 && NewVDstIn != -1 &&
"Must be tied!");
3213 MI->tieOperands(NewVDst, NewVDstIn);
3215 MI->setDesc(
TII->get(NewOpc));
3223 if (
TII->isOperandLegal(*
MI, FIOperandNum, FIOp))
3230 bool UseSGPR =
TII->isOperandLegal(*
MI, FIOperandNum, FIOp);
3232 if (!
Offset && FrameReg && UseSGPR) {
3238 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3241 RS->scavengeRegisterBackwards(*RC,
MI,
false, 0, !UseSGPR);
3245 if ((!FrameReg || !
Offset) && TmpReg) {
3246 unsigned Opc = UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
3249 MIB.addReg(FrameReg);
3260 : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3261 MI,
false, 0, !UseSGPR);
3267 if ((!TmpSReg && !FrameReg) || (!TmpReg && !UseSGPR)) {
3268 int SVfromSSOpcode =
3270 int SVfromSVSOpcode =
3272 int SVOpcode = SVfromSSOpcode != -1 ? SVfromSSOpcode : SVfromSVSOpcode;
3273 if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
3280 "SV-form fallback cannot encode a frame register");
3286 int64_t FullOffset =
3288 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3289 auto [ImmOffset, RemainderOffset] =
3295 TII->getNamedOperand(*
MI, AMDGPU::OpName::vaddr)) {
3297 TII->getNamedOperand(*
MI, AMDGPU::OpName::vdata);
3301 bool CanReuseVAddr = VAddr->isKill() &&
3302 !(VData && regsOverlap(Src, VData->
getReg()));
3304 : RS->scavengeRegisterBackwards(
3305 AMDGPU::VGPR_32RegClass,
MI,
3313 UsedVAddr = RS->scavengeRegisterBackwards(
3314 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3316 .
addImm(RemainderOffset);
3319 .
add(
MI->getOperand(0))
3322 .
add(*
TII->getNamedOperand(*
MI, AMDGPU::OpName::cpol));
3323 MI->eraseFromParent();
3337 assert(!(
Offset & 0x1) &&
"Flat scratch offset must be aligned!");
3357 if (TmpSReg == FrameReg) {
3360 !
MI->registerDefIsDead(AMDGPU::SCC,
nullptr)) {
3384 bool IsMUBUF =
TII->isMUBUF(*
MI);
3393 bool SCCLiveAfterMI = RS->isRegUsed(AMDGPU::SCC);
3395 ? &AMDGPU::SReg_32RegClass
3396 : &AMDGPU::VGPR_32RegClass;
3397 bool IsCopy =
MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
3398 MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
3399 MI->getOpcode() == AMDGPU::S_MOV_B32;
3401 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3406 bool CanUseFrameRegAsSGPRScratch = IsSALU && FrameReg &&
3407 !
MI->readsRegister(FrameReg,
this) &&
3408 !
MI->modifiesRegister(FrameReg,
this);
3411 bool CanUseFrameRegAsScratch = CanUseFrameRegAsSGPRScratch && !LiveSCC;
3413 bool RestoreFrameReg =
false;
3417 ResultReg =
MI->getOperand(0).getReg();
3419 ResultReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0,
3422 if (CanUseFrameRegAsScratch) {
3425 ResultReg = FrameReg;
3426 RestoreFrameReg =
true;
3428 ResultReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0);
3437 isWave32 ?
Add.getReg(1)
3438 :
Register(getSubReg(
Add.getReg(1), AMDGPU::sub0));
3441 return ConstOffsetReg;
3446 IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
3448 if (IsSALU && LiveSCC) {
3449 TmpResultReg = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
3454 if (OpCode == AMDGPU::V_LSHRREV_B32_e64)
3457 Shift.addImm(ST.getWavefrontSizeLog2()).addReg(FrameReg);
3459 Shift.addReg(FrameReg).addImm(ST.getWavefrontSizeLog2());
3460 if (IsSALU && !LiveSCC)
3461 Shift.getInstr()->getOperand(3).setIsDead();
3462 if (IsSALU && LiveSCC) {
3466 NewDest = ResultReg;
3471 NewDest = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3475 if (CanUseFrameRegAsSGPRScratch) {
3477 RestoreFrameReg =
true;
3482 "unhandled SGPR spill to memory");
3483 NewDest = RS->scavengeRegisterBackwards(
3484 AMDGPU::SReg_32_XM0RegClass, Shift,
false, 0);
3490 ResultReg = NewDest;
3495 if ((MIB =
TII->getAddNoCarry(*
MBB,
MI,
DL, ResultReg, *RS)) !=
3502 .
addImm(ST.getWavefrontSizeLog2())
3505 const bool IsVOP2 = MIB->
getOpcode() == AMDGPU::V_ADD_U32_e32;
3517 "Need to reuse carry out register");
3525 if (!MIB || IsSALU) {
3532 Register TmpScaledReg = IsCopy && IsSALU
3534 : RS->scavengeRegisterBackwards(
3535 AMDGPU::SReg_32_XM0RegClass,
MI,
3541 ScaledReg = IsSALU ? ResultReg : FrameReg;
3547 .
addImm(ST.getWavefrontSizeLog2());
3552 TmpResultReg = RS->scavengeRegisterBackwards(
3553 AMDGPU::VGPR_32RegClass,
MI,
false, 0,
true);
3556 if ((
Add =
TII->getAddNoCarry(*
MBB,
MI,
DL, TmpResultReg, *RS))) {
3559 .
addImm(ST.getWavefrontSizeLog2())
3561 if (
Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
3569 "offset is unsafe for v_mad_u32_u24");
3578 bool IsInlinableLiteral =
3580 if (!IsInlinableLiteral) {
3589 if (!IsInlinableLiteral) {
3595 Add.addImm(ST.getWavefrontSize()).addReg(FrameReg).addImm(0);
3598 .
addImm(ST.getWavefrontSizeLog2())
3604 NewDest = ResultReg;
3607 NewDest = RS->scavengeRegisterBackwards(
3608 AMDGPU::SReg_32_XM0RegClass, *
Add,
false, 0,
3611 if (CanUseFrameRegAsSGPRScratch) {
3613 RestoreFrameReg =
true;
3617 "unhandled SGPR spill to memory");
3618 NewDest = RS->scavengeRegisterBackwards(
3619 AMDGPU::SReg_32_XM0RegClass, *
Add,
false, 0);
3627 ResultReg = NewDest;
3635 if (!TmpScaledReg.
isValid()) {
3641 .
addImm(ST.getWavefrontSizeLog2());
3647 if (RestoreFrameReg) {
3656 .
addImm(ST.getWavefrontSize());
3659 int64_t ScaledOffset = -
Offset * ST.getWavefrontSize();
3660 if (!SCCLiveAfterMI) {
3680 MI->eraseFromParent();
3691 static_cast<int>(FIOperandNum) ==
3692 AMDGPU::getNamedOperandIdx(
MI->getOpcode(), AMDGPU::OpName::vaddr));
3694 auto &SOffset = *
TII->getNamedOperand(*
MI, AMDGPU::OpName::soffset);
3695 assert((SOffset.isImm() && SOffset.getImm() == 0));
3697 if (FrameReg != AMDGPU::NoRegister)
3698 SOffset.ChangeToRegister(FrameReg,
false);
3700 int64_t
Offset = FrameInfo.getObjectOffset(Index);
3702 TII->getNamedOperand(*
MI, AMDGPU::OpName::offset)->getImm();
3703 int64_t NewOffset = OldImm +
Offset;
3705 if (
TII->isLegalMUBUFImmOffset(NewOffset) &&
3707 MI->eraseFromParent();
3718 if (!
TII->isOperandLegal(*
MI, FIOperandNum, FIOp)) {
3720 TII->getRegClass(
MI->getDesc(), FIOperandNum);
3724 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3725 Register TmpReg = RS->scavengeRegisterBackwards(*RC,
MI,
false, 0);
3727 TII->get(UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32),
3747 return &AMDGPU::VReg_64RegClass;
3749 return &AMDGPU::VReg_96RegClass;
3751 return &AMDGPU::VReg_128RegClass;
3753 return &AMDGPU::VReg_160RegClass;
3755 return &AMDGPU::VReg_192RegClass;
3757 return &AMDGPU::VReg_224RegClass;
3759 return &AMDGPU::VReg_256RegClass;
3761 return &AMDGPU::VReg_288RegClass;
3763 return &AMDGPU::VReg_320RegClass;
3765 return &AMDGPU::VReg_352RegClass;
3767 return &AMDGPU::VReg_384RegClass;
3769 return &AMDGPU::VReg_512RegClass;
3771 return &AMDGPU::VReg_1024RegClass;
3779 return &AMDGPU::VReg_64_Align2RegClass;
3781 return &AMDGPU::VReg_96_Align2RegClass;
3783 return &AMDGPU::VReg_128_Align2RegClass;
3785 return &AMDGPU::VReg_160_Align2RegClass;
3787 return &AMDGPU::VReg_192_Align2RegClass;
3789 return &AMDGPU::VReg_224_Align2RegClass;
3791 return &AMDGPU::VReg_256_Align2RegClass;
3793 return &AMDGPU::VReg_288_Align2RegClass;
3795 return &AMDGPU::VReg_320_Align2RegClass;
3797 return &AMDGPU::VReg_352_Align2RegClass;
3799 return &AMDGPU::VReg_384_Align2RegClass;
3801 return &AMDGPU::VReg_512_Align2RegClass;
3803 return &AMDGPU::VReg_1024_Align2RegClass;
3811 return &AMDGPU::VReg_1RegClass;
3813 return &AMDGPU::VGPR_16RegClass;
3815 return &AMDGPU::VGPR_32RegClass;
3823 return &AMDGPU::VGPR_32_Lo256RegClass;
3825 return &AMDGPU::VReg_64_Lo256_Align2RegClass;
3827 return &AMDGPU::VReg_96_Lo256_Align2RegClass;
3829 return &AMDGPU::VReg_128_Lo256_Align2RegClass;
3831 return &AMDGPU::VReg_160_Lo256_Align2RegClass;
3833 return &AMDGPU::VReg_192_Lo256_Align2RegClass;
3835 return &AMDGPU::VReg_224_Lo256_Align2RegClass;
3837 return &AMDGPU::VReg_256_Lo256_Align2RegClass;
3839 return &AMDGPU::VReg_288_Lo256_Align2RegClass;
3841 return &AMDGPU::VReg_320_Lo256_Align2RegClass;
3843 return &AMDGPU::VReg_352_Lo256_Align2RegClass;
3845 return &AMDGPU::VReg_384_Lo256_Align2RegClass;
3847 return &AMDGPU::VReg_512_Lo256_Align2RegClass;
3849 return &AMDGPU::VReg_1024_Lo256_Align2RegClass;
3857 return &AMDGPU::AReg_64RegClass;
3859 return &AMDGPU::AReg_96RegClass;
3861 return &AMDGPU::AReg_128RegClass;
3863 return &AMDGPU::AReg_160RegClass;
3865 return &AMDGPU::AReg_192RegClass;
3867 return &AMDGPU::AReg_224RegClass;
3869 return &AMDGPU::AReg_256RegClass;
3871 return &AMDGPU::AReg_288RegClass;
3873 return &AMDGPU::AReg_320RegClass;
3875 return &AMDGPU::AReg_352RegClass;
3877 return &AMDGPU::AReg_384RegClass;
3879 return &AMDGPU::AReg_512RegClass;
3881 return &AMDGPU::AReg_1024RegClass;
3889 return &AMDGPU::AReg_64_Align2RegClass;
3891 return &AMDGPU::AReg_96_Align2RegClass;
3893 return &AMDGPU::AReg_128_Align2RegClass;
3895 return &AMDGPU::AReg_160_Align2RegClass;
3897 return &AMDGPU::AReg_192_Align2RegClass;
3899 return &AMDGPU::AReg_224_Align2RegClass;
3901 return &AMDGPU::AReg_256_Align2RegClass;
3903 return &AMDGPU::AReg_288_Align2RegClass;
3905 return &AMDGPU::AReg_320_Align2RegClass;
3907 return &AMDGPU::AReg_352_Align2RegClass;
3909 return &AMDGPU::AReg_384_Align2RegClass;
3911 return &AMDGPU::AReg_512_Align2RegClass;
3913 return &AMDGPU::AReg_1024_Align2RegClass;
3921 return &AMDGPU::AGPR_LO16RegClass;
3923 return &AMDGPU::AGPR_32RegClass;
3931 return &AMDGPU::AV_64RegClass;
3933 return &AMDGPU::AV_96RegClass;
3935 return &AMDGPU::AV_128RegClass;
3937 return &AMDGPU::AV_160RegClass;
3939 return &AMDGPU::AV_192RegClass;
3941 return &AMDGPU::AV_224RegClass;
3943 return &AMDGPU::AV_256RegClass;
3945 return &AMDGPU::AV_288RegClass;
3947 return &AMDGPU::AV_320RegClass;
3949 return &AMDGPU::AV_352RegClass;
3951 return &AMDGPU::AV_384RegClass;
3953 return &AMDGPU::AV_512RegClass;
3955 return &AMDGPU::AV_1024RegClass;
3963 return &AMDGPU::AV_64_Align2RegClass;
3965 return &AMDGPU::AV_96_Align2RegClass;
3967 return &AMDGPU::AV_128_Align2RegClass;
3969 return &AMDGPU::AV_160_Align2RegClass;
3971 return &AMDGPU::AV_192_Align2RegClass;
3973 return &AMDGPU::AV_224_Align2RegClass;
3975 return &AMDGPU::AV_256_Align2RegClass;
3977 return &AMDGPU::AV_288_Align2RegClass;
3979 return &AMDGPU::AV_320_Align2RegClass;
3981 return &AMDGPU::AV_352_Align2RegClass;
3983 return &AMDGPU::AV_384_Align2RegClass;
3985 return &AMDGPU::AV_512_Align2RegClass;
3987 return &AMDGPU::AV_1024_Align2RegClass;
3995 return &AMDGPU::AV_32RegClass;
3996 return ST.needsAlignedVGPRs()
4015 return &AMDGPU::SReg_32RegClass;
4017 return &AMDGPU::SReg_64RegClass;
4019 return &AMDGPU::SGPR_96RegClass;
4021 return &AMDGPU::SGPR_128RegClass;
4023 return &AMDGPU::SGPR_160RegClass;
4025 return &AMDGPU::SGPR_192RegClass;
4027 return &AMDGPU::SGPR_224RegClass;
4029 return &AMDGPU::SGPR_256RegClass;
4031 return &AMDGPU::SGPR_288RegClass;
4033 return &AMDGPU::SGPR_320RegClass;
4035 return &AMDGPU::SGPR_352RegClass;
4037 return &AMDGPU::SGPR_384RegClass;
4039 return &AMDGPU::SGPR_512RegClass;
4041 return &AMDGPU::SGPR_1024RegClass;
4049 if (Reg.isVirtual())
4050 RC =
MRI.getRegClass(Reg);
4052 RC = getPhysRegBaseClass(Reg);
4058 unsigned Size = getRegSizeInBits(*SRC);
4060 switch (SRC->
getID()) {
4063 case AMDGPU::VS_16_Lo128RegClassID:
4064 return getAllocatableClass(&AMDGPU::VGPR_16_Lo128RegClass);
4065 case AMDGPU::VS_32_Lo128RegClassID:
4066 return getAllocatableClass(&AMDGPU::VGPR_32_Lo128RegClass);
4067 case AMDGPU::VS_32_Lo256RegClassID:
4068 case AMDGPU::VS_64_Lo256RegClassID:
4074 assert(VRC &&
"Invalid register class size");
4080 unsigned Size = getRegSizeInBits(*SRC);
4082 assert(ARC &&
"Invalid register class size");
4088 unsigned Size = getRegSizeInBits(*SRC);
4090 assert(ARC &&
"Invalid register class size");
4096 unsigned Size = getRegSizeInBits(*VRC);
4098 return &AMDGPU::SGPR_32RegClass;
4100 assert(SRC &&
"Invalid register class size");
4107 unsigned SubIdx)
const {
4110 getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
4111 return MatchRC && MatchRC->
hasSubClassEq(SuperRC) ? MatchRC :
nullptr;
4117 return !ST.hasMFMAInlineLiteralBug();
4138 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::VCC_HI;
4141 if (ReserveHighestRegister) {
4143 if (
MRI.isAllocatable(Reg) && !
MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4147 if (
MRI.isAllocatable(Reg) && !
MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4164 unsigned EltSize)
const {
4166 assert(RegBitWidth >= 32 && RegBitWidth <= 1024 && EltSize >= 2);
4168 const unsigned RegHalves = RegBitWidth / 16;
4169 const unsigned EltHalves = EltSize / 2;
4170 assert(RegSplitParts.size() + 1 >= EltHalves);
4172 const std::vector<int16_t> &Parts = RegSplitParts[EltHalves - 1];
4173 const unsigned NumParts = RegHalves / EltHalves;
4181 return Reg.isVirtual() ?
MRI.getRegClass(Reg) : getPhysRegBaseClass(Reg);
4188 return getSubRegisterClass(SrcRC, MO.
getSubReg());
4208 unsigned MinOcc = ST.getOccupancyWithWorkGroupSizes(MF).first;
4209 switch (RC->
getID()) {
4211 return AMDGPUGenRegisterInfo::getRegPressureLimit(RC, MF);
4212 case AMDGPU::VGPR_32RegClassID:
4217 ST.getMaxNumVGPRs(MF));
4218 case AMDGPU::SGPR_32RegClassID:
4219 case AMDGPU::SGPR_LO16RegClassID:
4220 return std::min(ST.getMaxNumSGPRs(MinOcc,
true), ST.getMaxNumSGPRs(MF));
4225 unsigned Idx)
const {
4226 switch (
static_cast<AMDGPU::RegisterPressureSets
>(Idx)) {
4227 case AMDGPU::RegisterPressureSets::VGPR_32:
4228 case AMDGPU::RegisterPressureSets::AGPR_32:
4231 case AMDGPU::RegisterPressureSets::SReg_32:
4240 static const int Empty[] = { -1 };
4242 if (RegPressureIgnoredUnits[
static_cast<unsigned>(RegUnit)])
4245 return AMDGPUGenRegisterInfo::getRegUnitPressureSets(RegUnit);
4258 std::pair<unsigned, Register> Hint =
MRI.getRegAllocationHint(VirtReg);
4260 switch (Hint.first) {
4267 getMatchingSuperReg(Paired, AMDGPU::lo16, &AMDGPU::VGPR_32RegClass);
4268 }
else if (VRM && VRM->
hasPhys(Paired)) {
4269 PairedPhys = getMatchingSuperReg(VRM->
getPhys(Paired), AMDGPU::lo16,
4270 &AMDGPU::VGPR_32RegClass);
4277 Hints.
insert(PairedPhys);
4285 PairedPhys =
TRI->getSubReg(Paired, AMDGPU::lo16);
4286 }
else if (VRM && VRM->
hasPhys(Paired)) {
4287 PairedPhys =
TRI->getSubReg(VRM->
getPhys(Paired), AMDGPU::lo16);
4292 Hints.
insert(PairedPhys);
4302 if (AMDGPU::VGPR_16RegClass.
contains(PhysReg) &&
4303 !
MRI.isReserved(PhysReg))
4317 unsigned &MaxVGPRsForCurrentOccupancy)
const {
4322 unsigned CurrentOccupancy =
4323 ST.getOccupancyWithNumVGPRs(NumAllocatedVGPRs, DynamicVGPRBlockSize);
4324 MaxVGPRsForCurrentOccupancy =
4325 ST.getMaxNumVGPRs(CurrentOccupancy, DynamicVGPRBlockSize);
4327 LLVM_DEBUG(
dbgs() <<
"anti-hints: VGPRs allocated = " << NumAllocatedVGPRs
4328 <<
", RecordedMaxOccupancy = " << RecordedMaxOccupancy
4329 <<
", current occupancy = " << CurrentOccupancy <<
'\n');
4333 if (CurrentOccupancy == 1)
4342 unsigned MaxVGPRsCutOffForRecordedMaxOccupancy =
4343 (ST.getMaxNumVGPRs(RecordedMaxOccupancy, DynamicVGPRBlockSize) * 80) /
4345 unsigned MaxVGPRsCutOffForCurrentOccupancy =
4346 (MaxVGPRsForCurrentOccupancy * 95) / 100;
4348 if (NumAllocatedVGPRs >= MaxVGPRsCutOffForRecordedMaxOccupancy) {
4350 << MaxVGPRsCutOffForRecordedMaxOccupancy
4351 <<
" VGPR cutoff for RecordedMaxOccupancy\n");
4355 if (NumAllocatedVGPRs >= MaxVGPRsCutOffForCurrentOccupancy) {
4357 << MaxVGPRsCutOffForCurrentOccupancy
4358 <<
" VGPR cutoff for current occupancy\n");
4366bool SIRegisterInfo::isRegWithinOccupancyBudget(
4367 MCPhysReg Reg,
unsigned NumVGPRs,
unsigned NumAGPRs,
4368 unsigned MaxVGPRsForCurrentOccupancy)
const {
4375 unsigned RegEndIndex =
4378 unsigned MaxVGPR = NumVGPRs;
4379 unsigned MaxAGPR = NumAGPRs;
4382 MaxAGPR = std::max(MaxAGPR, RegEndIndex);
4384 MaxVGPR = std::max(MaxVGPR, RegEndIndex);
4386 return static_cast<unsigned>(
4388 MaxVGPRsForCurrentOccupancy;
4397 return isAntiHintedReg(Reg, AntiHintedRegUnits);
4403 "SGPR anti-hints are not handled");
4404 unsigned NumVGPRs = 0;
4405 unsigned NumAGPRs = 0;
4407 assert(
Matrix &&
"LiveRegMatrix required to compute occupancy");
4408 assert(RegClassInfo &&
"RegClassInfo required to compute occupancy");
4410 if (
Matrix->isPhysRegUsed(Reg) ||
4411 MRI.isPhysRegUsed(Reg,
true))
4416 if (
Matrix->isPhysRegUsed(Reg) ||
4417 MRI.isPhysRegUsed(Reg,
true))
4421 unsigned NumAllocatedVGPRs =
4425 unsigned MaxVGPRsForCurrentOccupancy = 0;
4431 auto *BeyondBudgetStart = std::stable_partition(
4433 return isRegWithinOccupancyBudget(Reg, NumVGPRs, NumAGPRs,
4434 MaxVGPRsForCurrentOccupancy);
4437 [[maybe_unused]]
auto *PartitionPoint = std::stable_partition(
4438 CustomOrder.
begin(), BeyondBudgetStart,
4439 [&](
MCPhysReg Reg) { return !isAntiHintedReg(Reg, AntiHintedRegUnits); });
4442 size_t NonAntiHintedCount =
4443 std::distance(CustomOrder.
begin(), PartitionPoint);
4444 size_t AntiHintedCount = std::distance(PartitionPoint, BeyondBudgetStart);
4445 size_t BeyondBudgetCount =
4446 std::distance(BeyondBudgetStart, CustomOrder.
end());
4447 dbgs() <<
"Added " << NonAntiHintedCount
4448 <<
" non-anti-hinted registers first\n"
4449 <<
"Added " << AntiHintedCount
4450 <<
" anti-hinted registers at the end\n"
4451 <<
"Beyond current occupancy budget, left: " << BeyondBudgetCount
4458 return AMDGPU::SGPR30_SGPR31;
4464 unsigned SizeEnc =
static_cast<unsigned>(
Size);
4465 switch (RB.
getID()) {
4466 case AMDGPU::VGPRRegBankID:
4468 std::max(ST.useRealTrue16Insts() ? 16u : 32u, SizeEnc));
4469 case AMDGPU::VCCRegBankID:
4472 case AMDGPU::SGPRRegBankID:
4474 case AMDGPU::AGPRRegBankID:
4488 return getAllocatableClass(RC);
4494 return isWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC;
4498 return isWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
4503 return ST.needsAlignedVGPRs() ? &AMDGPU::VReg_64_Align2RegClass
4504 : &AMDGPU::VReg_64RegClass;
4516 if (Reg.isVirtual()) {
4520 LaneBitmask SubLanes = SubReg ? getSubRegIndexLaneMask(SubReg)
4521 :
MRI.getMaxLaneMaskForVReg(Reg);
4525 if ((S.LaneMask & SubLanes) == SubLanes) {
4526 V = S.getVNInfoAt(UseIdx);
4538 for (MCRegUnit Unit : regunits(Reg.asMCReg())) {
4553 if (!Def || !MDT.dominates(Def, &
Use))
4556 assert(Def->modifiesRegister(Reg,
this));
4562 assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
4565 {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
4566 &AMDGPU::AGPR_32RegClass}) {
4567 if (
MCRegister Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
4571 getMatchingSuperReg(Reg, AMDGPU::hi16, &AMDGPU::VGPR_32RegClass)) {
4575 return AMDGPU::NoRegister;
4579 if (!ST.needsAlignedVGPRs())
4590 assert(&RC != &AMDGPU::VS_64RegClass);
4597 return ArrayRef(AMDGPU::SGPR_128RegClass.begin(), ST.getMaxNumSGPRs(MF) / 4);
4602 return ArrayRef(AMDGPU::SGPR_64RegClass.begin(), ST.getMaxNumSGPRs(MF) / 2);
4607 return ArrayRef(AMDGPU::SGPR_32RegClass.begin(), ST.getMaxNumSGPRs(MF));
4612 unsigned SubReg)
const {
4615 return std::min(128u, getSubRegIdxSize(SubReg));
4619 return std::min(32u, getSubRegIdxSize(SubReg));
4628 bool IncludeCalls)
const {
4629 unsigned NumArchVGPRs = ST.getAddressableNumArchVGPRs();
4631 (RC.
getID() == AMDGPU::VGPR_32RegClassID)
4635 if (Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
4636 MRI.isPhysRegUsed(Reg, !IncludeCalls))
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)
MachineRegisterInfo & MRI
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 bool isSCCLiveInto(const RegScavenger &RS, const MachineInstr &MI)
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 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 const TargetRegisterClass * getAlignedVectorSuperClassForBitWidth(unsigned BitWidth)
static const TargetRegisterClass * getAnyVectorSuperClassForBitWidth(unsigned BitWidth)
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)
Interface definition for SIRegisterInfo.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static const char * getRegisterName(MCRegister Reg)
bool isBottomOfStack() const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
bool empty() const
Returns whether there are no bits in this bitvector.
Diagnostic information for unsupported feature in backend.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
bool hasInterval(Register Reg) const
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
MachineDominatorTree & getDomTree()
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
This class represents the liveness of a register, stack slot, etc.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
unsigned getID() const
getID() - Return the register class ID number.
ArrayRef< MCPhysReg > getRegisters() const
const uint8_t TSFlags
Configurable target specific flags.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Generic base class for all target subtargets.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasCalls() const
Return true if the current function has any function calls.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
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.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
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
unsigned getOccupancy() 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
const TargetRegisterClass * getRegClassForSizeOnBank(uint64_t Size, const RegisterBank &Bank) const
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.
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
static bool hasVectorRegisters(const TargetRegisterClass *RC)
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 getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallSetVector< MCPhysReg, 16 > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
LLVM_READONLY const TargetRegisterClass * getAGPRClassForBitWidth(unsigned BitWidth) const
static bool isChainScratchRegister(Register VGPR)
MCRegister get32BitRegister(MCRegister Reg) const
bool requiresRegisterScavenging(const MachineFunction &Fn) const override
bool opCanUseInlineConstant(unsigned OpType) const
bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI, Register Reg) const override
const uint32_t * getNoPreservedMask() const override
bool shouldApplyAntiHints(const MachineFunction &MF, unsigned NumAllocatedVGPRs, unsigned &MaxVGPRsForCurrentOccupancy) const
StringRef getRegAsmName(MCRegister Reg) const override
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
void filterAndSortForAntiHintedRegs(Register VirtReg, MutableArrayRef< MCPhysReg > CustomOrder, const BitVector &AntiHintedRegUnits, const MachineFunction &MF, const LiveRegMatrix *Matrix=nullptr, const RegisterClassInfo *RegClassInfo=nullptr) const override
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
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 unsigned getSubRegFromChannel(uint64_t Channel, uint64_t NumRegs=1)
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
bool insert(const value_type &X)
Insert a new element into the SetVector.
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...
A SetVector that performs no allocations if smaller than a certain size.
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, SmallSetVector< MCPhysReg, 16 > &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_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_READONLY bool hasNamedOperand(uint32_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.
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 raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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.