22#define DEBUG_TYPE "frame-info"
25 "amdgpu-spill-vgpr-to-agpr",
26 cl::desc(
"Enable spilling VGPRs to AGPRs"),
55 for (
unsigned i = 0; CSRegs[i]; ++i)
56 LiveUnits.
addReg(CSRegs[i]);
76 bool IncludeScratchCopy =
true) {
82 unsigned Size =
TRI->getSpillSize(RC);
83 Align Alignment =
TRI->getSpillAlign(RC);
91 if (IncludeScratchCopy)
95 int FI = FrameInfo.CreateStackObject(
Size, Alignment,
true,
nullptr,
98 if (
TRI->spillSGPRToVGPR() &&
115 FI = FrameInfo.CreateSpillStackObject(
Size, Alignment);
126 LiveUnits.
addReg(ScratchSGPR);
141 int64_t DwordOff = 0) {
142 unsigned Opc = ST.enableFlatScratch() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
143 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
150 LiveUnits.
addReg(SpillReg);
151 bool IsKill = !
MBB.isLiveIn(SpillReg);
152 TRI.buildSpillLoadStore(
MBB,
I,
DL,
Opc, FI, SpillReg, IsKill, FrameReg,
153 DwordOff, MMO,
nullptr, &LiveUnits);
165 Register FrameReg, int64_t DwordOff = 0) {
166 unsigned Opc = ST.enableFlatScratch() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
167 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
174 TRI.buildSpillLoadStore(
MBB,
I,
DL,
Opc, FI, SpillReg,
false, FrameReg,
175 DwordOff, MMO,
nullptr, &LiveUnits);
185 Register TargetLo =
TRI->getSubReg(TargetReg, AMDGPU::sub0);
186 Register TargetHi =
TRI->getSubReg(TargetReg, AMDGPU::sub1);
193 const MCInstrDesc &GetPC64 =
TII->get(AMDGPU::S_GETPC_B64_pseudo);
198 MBB.addLiveIn(GitPtrLo);
207 if (LiveUnits.
empty()) {
241 unsigned EltSize = 4;
243 void saveToMemory(
const int FI)
const {
245 assert(!MFI.isDeadObjectIndex(FI));
250 MRI, LiveUnits, AMDGPU::VGPR_32RegClass);
254 for (
unsigned I = 0, DwordOff = 0;
I < NumSubRegs; ++
I) {
257 :
Register(TRI.getSubReg(SuperReg, SplitParts[
I]));
258 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
262 FI, FrameReg, DwordOff);
267 void saveToVGPRLane(
const int FI)
const {
268 assert(!MFI.isDeadObjectIndex(FI));
272 FuncInfo->getSGPRSpillToPhysicalVGPRLanes(FI);
273 assert(Spill.size() == NumSubRegs);
275 for (
unsigned I = 0;
I < NumSubRegs; ++
I) {
278 :
Register(TRI.getSubReg(SuperReg, SplitParts[
I]));
279 BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_SPILL_S32_TO_VGPR),
287 void copyToScratchSGPR(
Register DstReg)
const {
288 BuildMI(MBB, MI, DL, TII->get(AMDGPU::COPY), DstReg)
293 void restoreFromMemory(
const int FI) {
298 MRI, LiveUnits, AMDGPU::VGPR_32RegClass);
302 for (
unsigned I = 0, DwordOff = 0;
I < NumSubRegs; ++
I) {
305 :
Register(TRI.getSubReg(SuperReg, SplitParts[
I]));
308 TmpVGPR, FI, FrameReg, DwordOff);
309 MRI.constrainRegClass(
SubReg, &AMDGPU::SReg_32_XM0RegClass);
310 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
SubReg)
316 void restoreFromVGPRLane(
const int FI) {
319 FuncInfo->getSGPRSpillToPhysicalVGPRLanes(FI);
320 assert(Spill.size() == NumSubRegs);
322 for (
unsigned I = 0;
I < NumSubRegs; ++
I) {
325 :
Register(TRI.getSubReg(SuperReg, SplitParts[
I]));
326 BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_RESTORE_S32_FROM_VGPR),
SubReg)
332 void copyFromScratchSGPR(
Register SrcReg)
const {
333 BuildMI(MBB, MI, DL, TII->get(AMDGPU::COPY), SuperReg)
346 : MI(MI), MBB(MBB), MF(*MBB.
getParent()),
347 ST(MF.getSubtarget<
GCNSubtarget>()), MFI(MF.getFrameInfo()),
349 SuperReg(Reg), SI(SI), LiveUnits(LiveUnits), DL(DL),
352 SplitParts = TRI.getRegSplitParts(RC, EltSize);
353 NumSubRegs = SplitParts.empty() ? 1 : SplitParts.size();
355 assert(SuperReg != AMDGPU::M0 &&
"m0 should never spill");
359 switch (SI.getKind()) {
361 return saveToMemory(SI.getIndex());
363 return saveToVGPRLane(SI.getIndex());
365 return copyToScratchSGPR(SI.getReg());
370 switch (SI.getKind()) {
372 return restoreFromMemory(SI.getIndex());
374 return restoreFromVGPRLane(SI.getIndex());
376 return copyFromScratchSGPR(SI.getReg());
384void SIFrameLowering::emitEntryFunctionFlatScratchInit(
388 const SIInstrInfo *
TII =
ST.getInstrInfo();
389 const SIRegisterInfo *
TRI = &
TII->getRegisterInfo();
390 const SIMachineFunctionInfo *MFI = MF.
getInfo<SIMachineFunctionInfo>();
405 if (
ST.isAmdPalOS()) {
407 LiveRegUnits LiveUnits;
413 Register FlatScrInit = AMDGPU::NoRegister;
416 AllSGPR64s = AllSGPR64s.
slice(
417 std::min(
static_cast<unsigned>(AllSGPR64s.
size()), NumPreloaded));
421 MRI.isAllocatable(
Reg) && !
TRI->isSubRegisterEq(
Reg, GITPtrLoReg)) {
426 assert(FlatScrInit &&
"Failed to find free register for scratch init");
428 FlatScrInitLo =
TRI->getSubReg(FlatScrInit, AMDGPU::sub0);
429 FlatScrInitHi =
TRI->getSubReg(FlatScrInit, AMDGPU::sub1);
436 const MCInstrDesc &LoadDwordX2 =
TII->get(AMDGPU::S_LOAD_DWORDX2_IMM);
444 const GCNSubtarget &Subtarget = MF.
getSubtarget<GCNSubtarget>();
453 const MCInstrDesc &SAndB32 =
TII->get(AMDGPU::S_AND_B32);
461 assert(FlatScratchInitReg);
464 MRI.addLiveIn(FlatScratchInitReg);
467 FlatScrInitLo =
TRI->getSubReg(FlatScratchInitReg, AMDGPU::sub0);
468 FlatScrInitHi =
TRI->getSubReg(FlatScratchInitReg, AMDGPU::sub1);
472 if (
ST.flatScratchIsPointer()) {
476 .
addReg(ScratchWaveOffsetReg);
483 using namespace AMDGPU::Hwreg;
486 .
addImm(int16_t(HwregEncoding::encode(ID_FLAT_SCR_LO, 0, 32)));
489 .
addImm(int16_t(HwregEncoding::encode(ID_FLAT_SCR_HI, 0, 32)));
496 .
addReg(ScratchWaveOffsetReg);
516 .
addReg(ScratchWaveOffsetReg);
539Register SIFrameLowering::getEntryFunctionReservedScratchRsrcReg(
543 const SIInstrInfo *
TII =
ST.getInstrInfo();
544 const SIRegisterInfo *
TRI = &
TII->getRegisterInfo();
546 SIMachineFunctionInfo *MFI = MF.
getInfo<SIMachineFunctionInfo>();
552 if (!ScratchRsrcReg || (!
MRI.isPhysRegUsed(ScratchRsrcReg) &&
556 if (
ST.hasSGPRInitBug() ||
557 ScratchRsrcReg !=
TRI->reservedPrivateSegmentBufferReg(MF))
558 return ScratchRsrcReg;
571 AllSGPR128s = AllSGPR128s.
slice(std::min(
static_cast<unsigned>(AllSGPR128s.
size()), NumPreloaded));
580 if (!
MRI.isPhysRegUsed(
Reg) &&
MRI.isAllocatable(
Reg) &&
581 (!GITPtrLoReg || !
TRI->isSubRegisterEq(
Reg, GITPtrLoReg))) {
582 MRI.replaceRegWith(ScratchRsrcReg,
Reg);
589 return ScratchRsrcReg;
593 return ST.enableFlatScratch() ? 1 : ST.getWavefrontSize();
598 assert(&MF.
front() == &
MBB &&
"Shrink-wrapping not yet supported");
631 if (!ST.enableFlatScratch())
632 ScratchRsrcReg = getEntryFunctionReservedScratchRsrcReg(MF);
635 if (ScratchRsrcReg) {
637 if (&OtherBB != &
MBB) {
638 OtherBB.addLiveIn(ScratchRsrcReg);
646 if (ST.isAmdHsaOrMesa(
F)) {
647 PreloadedScratchRsrcReg =
649 if (ScratchRsrcReg && PreloadedScratchRsrcReg) {
652 MRI.addLiveIn(PreloadedScratchRsrcReg);
653 MBB.addLiveIn(PreloadedScratchRsrcReg);
668 if (PreloadedScratchWaveOffsetReg &&
669 TRI->isSubRegisterEq(ScratchRsrcReg, PreloadedScratchWaveOffsetReg)) {
672 AllSGPRs = AllSGPRs.
slice(
673 std::min(
static_cast<unsigned>(AllSGPRs.
size()), NumPreloaded));
676 if (!
MRI.isPhysRegUsed(Reg) &&
MRI.isAllocatable(Reg) &&
677 !
TRI->isSubRegisterEq(ScratchRsrcReg, Reg) && GITPtrLoReg != Reg) {
678 ScratchWaveOffsetReg = Reg;
687 if (!ScratchWaveOffsetReg)
689 "could not find temporary scratch offset register in prolog");
691 ScratchWaveOffsetReg = PreloadedScratchWaveOffsetReg;
693 assert(ScratchWaveOffsetReg || !PreloadedScratchWaveOffsetReg);
742 ST.hasInv2PiInlineImm())) {
754 bool NeedsFlatScratchInit =
756 (
MRI.isPhysRegUsed(AMDGPU::FLAT_SCR) || FrameInfo.
hasCalls() ||
759 if ((NeedsFlatScratchInit || ScratchRsrcReg) &&
760 PreloadedScratchWaveOffsetReg && !ST.flatScratchIsArchitected()) {
761 MRI.addLiveIn(PreloadedScratchWaveOffsetReg);
762 MBB.addLiveIn(PreloadedScratchWaveOffsetReg);
765 if (NeedsFlatScratchInit) {
766 emitEntryFunctionFlatScratchInit(MF,
MBB,
I,
DL, ScratchWaveOffsetReg);
769 if (ScratchRsrcReg) {
770 emitEntryFunctionScratchRsrcRegSetup(MF,
MBB,
I,
DL,
771 PreloadedScratchRsrcReg,
772 ScratchRsrcReg, ScratchWaveOffsetReg);
777void SIFrameLowering::emitEntryFunctionScratchRsrcRegSetup(
788 if (ST.isAmdPalOS()) {
791 Register Rsrc01 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0_sub1);
792 Register Rsrc03 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub3);
799 const MCInstrDesc &LoadDwordX4 =
TII->get(AMDGPU::S_LOAD_DWORDX4_IMM);
828 }
else if (
ST.isMesaGfxShader(Fn) || !PreloadedScratchRsrcReg) {
830 const MCInstrDesc &SMovB32 =
TII->get(AMDGPU::S_MOV_B32);
832 Register Rsrc2 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub2);
833 Register Rsrc3 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub3);
836 uint64_t Rsrc23 =
TII->getScratchRsrcWords23();
839 Register Rsrc01 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0_sub1);
842 const MCInstrDesc &Mov64 =
TII->get(AMDGPU::S_MOV_B64);
848 const MCInstrDesc &LoadDwordX2 =
TII->get(AMDGPU::S_LOAD_DWORDX2_IMM);
867 Register Rsrc0 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0);
868 Register Rsrc1 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub1);
886 }
else if (
ST.isAmdHsaOrMesa(Fn)) {
887 assert(PreloadedScratchRsrcReg);
889 if (ScratchRsrcReg != PreloadedScratchRsrcReg) {
904 Register ScratchRsrcSub0 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0);
905 Register ScratchRsrcSub1 =
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub1);
911 .
addReg(ScratchWaveOffsetReg)
913 auto Addc =
BuildMI(
MBB,
I,
DL,
TII->get(AMDGPU::S_ADDC_U32), ScratchRsrcSub1)
941 bool EnableInactiveLanes) {
954 assert(IsProlog &&
"Epilog should look at return, not setup");
956 TII->getWholeWaveFunctionSetup(MF)->getOperand(0).getReg();
957 assert(ScratchExecCopy &&
"Couldn't find copy of EXEC");
960 MRI, LiveUnits, *
TRI.getWaveMaskRegClass());
963 if (!ScratchExecCopy)
966 LiveUnits.
addReg(ScratchExecCopy);
968 const unsigned SaveExecOpc =
969 ST.isWave32() ? (EnableInactiveLanes ? AMDGPU::S_XOR_SAVEEXEC_B32
970 : AMDGPU::S_OR_SAVEEXEC_B32)
971 : (EnableInactiveLanes ? AMDGPU::S_XOR_SAVEEXEC_B64
972 : AMDGPU::S_OR_SAVEEXEC_B64);
977 return ScratchExecCopy;
997 if (!WWMScratchRegs.
empty())
1002 auto StoreWWMRegisters =
1004 for (
const auto &Reg : WWMRegs) {
1006 int FI = Reg.second;
1008 VGPR, FI, FrameReg);
1013 if (!
MRI.isReserved(Reg)) {
1018 StoreWWMRegisters(WWMScratchRegs);
1020 auto EnableAllLanes = [&]() {
1024 if (!WWMCalleeSavedRegs.
empty()) {
1025 if (ScratchExecCopy) {
1034 StoreWWMRegisters(WWMCalleeSavedRegs);
1040 if (!ScratchExecCopy)
1043 else if (WWMCalleeSavedRegs.
empty())
1045 TII->getWholeWaveFunctionSetup(MF)->eraseFromParent();
1046 }
else if (ScratchExecCopy) {
1050 LiveUnits.
addReg(ScratchExecCopy);
1061 Spill.first == FramePtrReg ? FramePtrRegScratchCopy : Spill.first;
1066 LiveUnits, FrameReg);
1074 if (!ScratchSGPRs.
empty()) {
1079 MBB.sortUniqueLiveIns();
1081 if (!LiveUnits.
empty()) {
1106 Spill.first == FramePtrReg ? FramePtrRegScratchCopy : Spill.first;
1111 LiveUnits, FrameReg);
1121 auto RestoreWWMRegisters =
1123 for (
const auto &Reg : WWMRegs) {
1125 int FI = Reg.second;
1127 VGPR, FI, FrameReg);
1134 RestoreWWMRegisters(WWMCalleeSavedRegs);
1138 unsigned Opcode = Return.getOpcode();
1140 case AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN:
1141 Opcode = AMDGPU::SI_RETURN;
1143 case AMDGPU::SI_TCRETURN_GFX_WholeWave:
1144 Opcode = AMDGPU::SI_TCRETURN_GFX;
1149 Register OrigExec = Return.getOperand(0).getReg();
1151 if (!WWMScratchRegs.
empty()) {
1155 RestoreWWMRegisters(WWMScratchRegs);
1162 Return.removeOperand(0);
1163 Return.setDesc(
TII->get(Opcode));
1168 if (!WWMScratchRegs.
empty()) {
1173 RestoreWWMRegisters(WWMScratchRegs);
1174 if (!WWMCalleeSavedRegs.
empty()) {
1175 if (ScratchExecCopy) {
1184 RestoreWWMRegisters(WWMCalleeSavedRegs);
1185 if (ScratchExecCopy) {
1222 assert(StackPtrReg != AMDGPU::SP_REG);
1234 if (
TRI.hasStackRealignment(MF))
1238 if (!HasFP && !
hasFP(MF)) {
1242 FramePtrRegScratchCopy);
1245 Register SGPRForFPSaveRestoreCopy =
1249 if (SGPRForFPSaveRestoreCopy) {
1256 DL,
TII,
TRI, LiveUnits, FramePtrReg);
1258 LiveUnits.
addReg(SGPRForFPSaveRestoreCopy);
1263 MRI, LiveUnits, AMDGPU::SReg_32_XM0_XEXECRegClass);
1264 if (!FramePtrRegScratchCopy)
1267 LiveUnits.
addReg(FramePtrRegScratchCopy);
1276 RoundedSize += Alignment;
1277 if (LiveUnits.
empty()) {
1292 And->getOperand(3).setIsDead();
1294 }
else if ((HasFP =
hasFP(MF))) {
1303 FramePtrRegScratchCopy);
1304 if (FramePtrRegScratchCopy)
1305 LiveUnits.
removeReg(FramePtrRegScratchCopy);
1312 if ((HasBP =
TRI.hasBasePointer(MF))) {
1318 if (HasFP && RoundedSize != 0) {
1323 Add->getOperand(3).setIsDead();
1328 assert((!HasFP || FPSaved) &&
1329 "Needed to save FP but didn't save it anywhere");
1334 "Saved FP but didn't need it");
1338 assert((!HasBP || BPSaved) &&
1339 "Needed to save BP but didn't save it anywhere");
1341 assert((HasBP || !BPSaved) &&
"Saved BP but didn't need it");
1360 MBBI =
MBB.getLastNonDebugInstr();
1362 DL =
MBBI->getDebugLoc();
1364 MBBI =
MBB.getFirstTerminator();
1376 if (RoundedSize != 0) {
1377 if (
TRI.hasBasePointer(MF)) {
1381 }
else if (
hasFP(MF)) {
1389 Register SGPRForFPSaveRestoreCopy =
1397 if (SGPRForFPSaveRestoreCopy) {
1398 LiveUnits.
addReg(SGPRForFPSaveRestoreCopy);
1401 MRI, LiveUnits, AMDGPU::SReg_32_XM0_XEXECRegClass);
1402 if (!FramePtrRegScratchCopy)
1405 LiveUnits.
addReg(FramePtrRegScratchCopy);
1409 FramePtrRegScratchCopy);
1414 Register SrcReg = SGPRForFPSaveRestoreCopy ? SGPRForFPSaveRestoreCopy
1415 : FramePtrRegScratchCopy;
1419 if (SGPRForFPSaveRestoreCopy)
1425 FramePtrRegScratchCopy);
1466 const bool SpillVGPRToAGPR = ST.hasMAIInsts() && FuncInfo->
hasSpilledVGPRs()
1469 if (SpillVGPRToAGPR) {
1474 bool SeenDbgInstr =
false;
1479 if (
MI.isDebugInstr())
1480 SeenDbgInstr =
true;
1482 if (
TII->isVGPRSpill(
MI)) {
1485 unsigned FIOp = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
1486 AMDGPU::OpName::vaddr);
1487 int FI =
MI.getOperand(FIOp).getIndex();
1489 TII->getNamedOperand(
MI, AMDGPU::OpName::vdata)->getReg();
1491 TRI->isAGPR(
MRI, VReg))) {
1495 TRI->eliminateFrameIndex(
MI, 0, FIOp, RS);
1499 }
else if (
TII->isStoreToStackSlot(
MI, FrameIndex) ||
1500 TII->isLoadFromStackSlot(
MI, FrameIndex))
1502 NonVGPRSpillFIs.
set(FrameIndex);
1508 for (
unsigned FI : SpillFIs.
set_bits())
1509 if (!NonVGPRSpillFIs.
test(FI))
1519 MBB.sortUniqueLiveIns();
1521 if (!SpillFIs.
empty() && SeenDbgInstr) {
1526 if (
MI.isDebugValue()) {
1527 uint32_t StackOperandIdx =
MI.isDebugValueList() ? 2 : 0;
1528 if (
MI.getOperand(StackOperandIdx).isFI() &&
1530 MI.getOperand(StackOperandIdx).getIndex()) &&
1531 SpillFIs[
MI.getOperand(StackOperandIdx).getIndex()]) {
1532 MI.getOperand(StackOperandIdx)
1533 .ChangeToRegister(
Register(),
false );
1544 bool HaveSGPRToVMemSpill =
1547 "SGPR spill should have been removed in SILowerSGPRSpills");
1553 assert(RS &&
"RegScavenger required if spilling");
1560 if (HaveSGPRToVMemSpill &&
1574 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
1581 TRI->findUnusedRegister(
MRI, &AMDGPU::VGPR_32RegClass, MF);
1582 if (UnusedLowVGPR && (
TRI->getHWRegIndex(UnusedLowVGPR) <
1583 TRI->getHWRegIndex(VGPRForAGPRCopy))) {
1589 MRI.reserveReg(UnusedLowVGPR,
TRI);
1596 TRI->findUnusedRegister(
MRI, &AMDGPU::SGPR_64RegClass, MF);
1601 if (LongBranchReservedReg && UnusedLowSGPR) {
1603 MRI.reserveReg(UnusedLowSGPR,
TRI);
1611 bool NeedExecCopyReservedReg)
const {
1622 for (
unsigned I = 0; CSRegs[
I]; ++
I)
1628 if (NeedExecCopyReservedReg ||
1629 (ReservedRegForExecCopy &&
1630 MRI.isPhysRegUsed(ReservedRegForExecCopy,
true))) {
1631 MRI.reserveReg(ReservedRegForExecCopy,
TRI);
1633 if (UnusedScratchReg) {
1637 MRI.replaceRegWith(ReservedRegForExecCopy, UnusedScratchReg);
1638 LiveUnits.
addReg(UnusedScratchReg);
1642 "Re-reserving spill slot for EXEC copy register");
1646 }
else if (ReservedRegForExecCopy) {
1660 const bool WillHaveFP =
1664 if (WillHaveFP ||
hasFP(MF)) {
1667 "Re-reserving spill slot for FP");
1671 if (
TRI->hasBasePointer(MF)) {
1674 "Re-reserving spill slot for BP");
1696 bool NeedExecCopyReservedReg =
false;
1703 if (
TII->isWWMRegSpillOpcode(
MI.getOpcode()))
1704 NeedExecCopyReservedReg =
true;
1705 else if (
MI.getOpcode() == AMDGPU::SI_RETURN ||
1706 MI.getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG ||
1707 MI.getOpcode() == AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN ||
1709 TII->isChainCallOpcode(
MI.getOpcode()))) {
1712 (
count_if(
MI.operands(), [](
auto Op) { return Op.isReg(); }) ==
1725 if (
TRI->getRegSizeInBits(*RC) != 32)
1730 sort(SortedWWMVGPRs, std::greater<Register>());
1739 assert(!NeedExecCopyReservedReg &&
1740 "Whole wave functions can use the reg mapped for their i1 argument");
1743 unsigned NumArchVGPRs = ST.has1024AddressableVGPRs() ? 1024 : 256;
1745 AMDGPU::VGPR_32RegClass.getRegisters().take_front(NumArchVGPRs))
1748 MF.
begin()->addLiveIn(Reg);
1750 MF.
begin()->sortUniqueLiveIns();
1758 SavedVGPRs.
reset(
Op.getReg());
1766 TRI->getSpillAlign(*RC));
1775 if (!ST.hasGFX90AInsts())
1783 SavedVGPRs.
reset(Reg.first);
1800 const BitVector AllSavedRegs = SavedRegs;
1809 const bool WillHaveFP =
1813 if (WillHaveFP ||
hasFP(MF))
1823 Register RetAddrReg =
TRI->getReturnAddressReg(MF);
1825 (FrameInfo.
hasCalls() ||
MRI.isPhysRegModified(RetAddrReg))) {
1826 SavedRegs.
set(
TRI->getSubReg(RetAddrReg, AMDGPU::sub0));
1827 SavedRegs.
set(
TRI->getSubReg(RetAddrReg, AMDGPU::sub1));
1833 std::vector<CalleeSavedInfo> &CSI,
1834 unsigned &MinCSFrameIndex,
1835 unsigned &MaxCSFrameIndex) {
1843 return A.getReg() <
B.getReg();
1845 "Callee saved registers not sorted");
1848 return !CSI.isSpilledToReg() &&
1849 TRI->getPhysRegBaseClass(CSI.getReg()) == &AMDGPU::VGPR_32RegClass &&
1853 auto CSEnd = CSI.end();
1854 for (
auto CSIt = CSI.begin(); CSIt != CSEnd; ++CSIt) {
1856 if (!CanUseBlockOps(*CSIt))
1863 CSEnd = std::remove_if(
1865 if (CanUseBlockOps(CSI) && CSI.
getReg() <
Reg + 32) {
1875 TRI->getMatchingSuperReg(
Reg, AMDGPU::sub0, BlockRegClass);
1884 TRI->getMatchingSuperReg(LastBlockStart, AMDGPU::sub0, BlockRegClass);
1885 assert(RegBlock &&
TRI->isSubRegister(RegBlock,
Reg) &&
1886 "Couldn't find super register");
1887 int RegDelta =
Reg - LastBlockStart;
1889 "Bad shift amount");
1900 unsigned BlockSize =
TRI->getSpillSize(*BlockRegClass) - UnusedBits * 4;
1902 MFI.CreateStackObject(
BlockSize,
TRI->getSpillAlign(*BlockRegClass),
1904 if ((
unsigned)FrameIdx < MinCSFrameIndex)
1905 MinCSFrameIndex = FrameIdx;
1906 if ((
unsigned)FrameIdx > MaxCSFrameIndex)
1907 MaxCSFrameIndex = FrameIdx;
1909 CSIt->setFrameIdx(FrameIdx);
1910 CSIt->setReg(RegBlock);
1912 CSI.erase(CSEnd, CSI.end());
1917 std::vector<CalleeSavedInfo> &CSI,
unsigned &MinCSFrameIndex,
1918 unsigned &MaxCSFrameIndex)
const {
1923 bool UseVGPRBlocks = ST.useVGPRBlockOpsForCSR();
1933 std::vector<CalleeSavedInfo> &CSI)
const {
1941 Register BasePtrReg = RI->getBaseRegister();
1942 Register SGPRForFPSaveRestoreCopy =
1944 Register SGPRForBPSaveRestoreCopy =
1946 if (!SGPRForFPSaveRestoreCopy && !SGPRForBPSaveRestoreCopy)
1949 unsigned NumModifiedRegs = 0;
1951 if (SGPRForFPSaveRestoreCopy)
1953 if (SGPRForBPSaveRestoreCopy)
1956 for (
auto &CS : CSI) {
1957 if (CS.getReg() == FramePtrReg.
asMCReg() && SGPRForFPSaveRestoreCopy) {
1958 CS.setDstReg(SGPRForFPSaveRestoreCopy);
1959 if (--NumModifiedRegs)
1961 }
else if (CS.getReg() == BasePtrReg.
asMCReg() &&
1962 SGPRForBPSaveRestoreCopy) {
1963 CS.setDstReg(SGPRForBPSaveRestoreCopy);
1964 if (--NumModifiedRegs)
1978 uint64_t EstStackSize = MFI.estimateStackSize(MF);
1979 uint64_t MaxOffset = EstStackSize - 1;
1988 if (ST.enableFlatScratch()) {
1993 if (
TII->isLegalMUBUFImmOffset(MaxOffset))
2005 if (!ST.useVGPRBlockOpsForCSR())
2017 if (!BlockRegClass->contains(Reg) ||
2025 int FrameIndex = CS.getFrameIdx();
2034 TII->get(AMDGPU::SI_BLOCK_SPILL_V1024_SAVE))
2050 MBB.sortUniqueLiveIns();
2060 if (!ST.useVGPRBlockOpsForCSR())
2070 if (!BlockRegClass->
contains(Reg) ||
2078 int FrameIndex = CS.getFrameIdx();
2083 MFI.getObjectAlign(FrameIndex));
2086 TII->get(AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE), Reg)
2101 MBB.sortUniqueLiveIns();
2109 int64_t Amount =
I->getOperand(0).getImm();
2111 return MBB.erase(
I);
2116 unsigned Opc =
I->getOpcode();
2117 bool IsDestroy =
Opc ==
TII->getCallFrameDestroyOpcode();
2118 uint64_t CalleePopAmount = IsDestroy ?
I->getOperand(1).getImm() : 0;
2132 Add->getOperand(3).setIsDead();
2133 }
else if (CalleePopAmount != 0) {
2137 return MBB.erase(
I);
2196 "only expected to call this for entry points and chain functions");
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
This file declares the machine register scavenger class.
static void buildEpilogRestore(const GCNSubtarget &ST, const SIRegisterInfo &TRI, const SIMachineFunctionInfo &FuncInfo, LiveRegUnits &LiveUnits, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register SpillReg, int FI, Register FrameReg, int64_t DwordOff=0)
static cl::opt< bool > EnableSpillVGPRToAGPR("amdgpu-spill-vgpr-to-agpr", cl::desc("Enable spilling VGPRs to AGPRs"), cl::ReallyHidden, cl::init(true))
static void getVGPRSpillLaneOrTempRegister(MachineFunction &MF, LiveRegUnits &LiveUnits, Register SGPR, const TargetRegisterClass &RC=AMDGPU::SReg_32_XM0_XEXECRegClass, bool IncludeScratchCopy=true)
Query target location for spilling SGPRs IncludeScratchCopy : Also look for free scratch SGPRs.
static void buildGitPtr(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, const SIInstrInfo *TII, Register TargetReg)
static bool allStackObjectsAreDead(const MachineFrameInfo &MFI)
static void buildPrologSpill(const GCNSubtarget &ST, const SIRegisterInfo &TRI, const SIMachineFunctionInfo &FuncInfo, LiveRegUnits &LiveUnits, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register SpillReg, int FI, Register FrameReg, int64_t DwordOff=0)
static Register buildScratchExecCopy(LiveRegUnits &LiveUnits, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool IsProlog, bool EnableInactiveLanes)
static bool frameTriviallyRequiresSP(const MachineFrameInfo &MFI)
Returns true if the frame will require a reference to the stack pointer.
static void assignSlotsUsingVGPRBlocks(MachineFunction &MF, const GCNSubtarget &ST, std::vector< CalleeSavedInfo > &CSI, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex)
static void initLiveUnits(LiveRegUnits &LiveUnits, const SIRegisterInfo &TRI, const SIMachineFunctionInfo *FuncInfo, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool IsProlog)
static bool allSGPRSpillsAreDead(const MachineFunction &MF)
static MCRegister findScratchNonCalleeSaveRegister(MachineRegisterInfo &MRI, LiveRegUnits &LiveUnits, const TargetRegisterClass &RC, bool Unused=false)
static MCRegister findUnusedRegister(MachineRegisterInfo &MRI, const LiveRegUnits &LiveUnits, const TargetRegisterClass &RC)
static unsigned getScratchScaleFactor(const GCNSubtarget &ST)
static const int BlockSize
bool isChainFunction() const
bool isEntryFunction() const
static const LaneMaskConstants & get(const GCNSubtarget &ST)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
bool test(unsigned Idx) const
void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
bool any() const
any - Returns true if any bit is set.
void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
clearBitsInMask - Clear any bits in this vector that are set in Mask.
iterator_range< const_set_bits_iterator > set_bits() const
bool empty() const
empty - Tests whether there are no bits in this bitvector.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
MCRegister getReg() const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasImplicitBufferPtr() const
bool hasFlatScratchInit() const
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.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
void addReg(MCRegister Reg)
Adds register units covered by physical register Reg.
LLVM_ABI void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
void removeReg(MCRegister Reg)
Removes all register units covered by physical register Reg.
bool empty() const
Returns true if the set is empty.
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)
Adds registers living into block MBB.
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
bool hasTailCall() const
Returns true if the function contains a tail call.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
uint8_t getStackID(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
void setIsDead(bool Val=true)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
PrologEpilogSGPRSpillBuilder(Register Reg, const PrologEpilogSGPRSaveRestoreInfo SI, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, const SIInstrInfo *TII, const SIRegisterInfo &TRI, LiveRegUnits &LiveUnits, Register FrameReg)
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void backward()
Update internal register state and move MBB iterator backwards.
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
void determinePrologEpilogSGPRSaves(MachineFunction &MF, BitVector &SavedRegs, bool NeedExecCopyReservedReg) const
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
bool mayReserveScratchForCWSR(const MachineFunction &MF) const
bool allocateScavengingFrameIndexesNearIncomingSP(const MachineFunction &MF) const override
Control the placement of special register scavenging spill slots when allocating a stack frame.
bool requiresStackPointerReference(const MachineFunction &MF) const
void emitEntryFunctionPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void emitCSRSpillStores(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL, LiveRegUnits &LiveUnits, Register FrameReg, Register FramePtrRegScratchCopy) const
bool hasFPImpl(const MachineFunction &MF) const override
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
void determineCalleeSavesSGPR(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
void emitCSRSpillRestores(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL, LiveRegUnits &LiveUnits, Register FrameReg, Register FramePtrRegScratchCopy) const
void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
bool isSupportedStackID(TargetStackID::Value ID) const override
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
ArrayRef< PrologEpilogSGPRSpill > getPrologEpilogSGPRSpills() const
const WWMSpillsMap & getWWMSpills() const
void getAllScratchSGPRCopyDstRegs(SmallVectorImpl< Register > &Regs) const
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
void setSGPRForEXECCopy(Register Reg)
unsigned getNumPreloadedSGPRs() const
void shiftWwmVGPRsToLowestRange(MachineFunction &MF, SmallVectorImpl< Register > &WWMVGPRs, BitVector &SavedVGPRs)
void setMaskForVGPRBlockOps(Register RegisterBlock, uint32_t Mask)
GCNUserSGPRUsageInfo & getUserSGPRInfo()
void allocateWWMSpill(MachineFunction &MF, Register VGPR, uint64_t Size=4, Align Alignment=Align(4))
Register getLongBranchReservedReg() const
unsigned getDynamicVGPRBlockSize() const
bool hasSpilledVGPRs() const
void setVGPRToAGPRSpillDead(int FrameIndex)
bool isWholeWaveFunction() const
Register getStackPtrOffsetReg() const
bool isStackRealigned() const
Register getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses.
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI)
uint32_t getMaskForVGPRBlockOps(Register RegisterBlock) const
bool hasMaskForVGPRBlockOps(Register RegisterBlock) const
bool hasPrologEpilogSGPRSpillEntry(Register Reg) const
Register getGITPtrLoReg(const MachineFunction &MF) const
void setVGPRForAGPRCopy(Register NewVGPRForAGPRCopy)
bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR)
Reserve AGPRs or VGPRs to support spilling for FrameIndex FI.
void splitWWMSpillRegisters(MachineFunction &MF, SmallVectorImpl< std::pair< Register, int > > &CalleeSavedRegs, SmallVectorImpl< std::pair< Register, int > > &ScratchRegs) const
Register getSGPRForEXECCopy() const
bool isWWMReservedRegister(Register Reg) const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToPhysicalVGPRLanes(int FrameIndex) const
Register getVGPRForAGPRCopy() const
bool allocateSGPRSpillToVGPRLane(MachineFunction &MF, int FI, bool SpillToPhysVGPRLane=false, bool IsPrologEpilog=false)
Register getFrameOffsetReg() const
void setLongBranchReservedReg(Register Reg)
void setHasSpilledVGPRs(bool Spill=true)
bool removeDeadFrameIndices(MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs)
If ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill to the default stack.
void setScratchReservedForDynamicVGPRs(unsigned SizeInBytes)
MCRegister getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
bool checkIndexInPrologEpilogSGPRSpills(int FI) const
const ReservedRegSet & getWWMReservedRegs() const
Register getImplicitBufferPtrUserSGPR() const
const PrologEpilogSGPRSaveRestoreInfo & getPrologEpilogSGPRSaveRestoreInfo(Register Reg) const
void setIsStackRealigned(bool Realigned=true)
unsigned getGITPtrHigh() const
bool hasSpilledSGPRs() const
void addToPrologEpilogSGPRSpills(Register Reg, PrologEpilogSGPRSaveRestoreInfo SI)
Register getScratchSGPRCopyDstReg(Register Reg) const
void setScratchRSrcReg(Register Reg)
void reserveWWMRegister(Register Reg)
Register getFrameRegister(const MachineFunction &MF) const override
const TargetRegisterClass * getRegClassForBlockOp(const MachineFunction &MF) const
void addImplicitUsesForBlockCSRLoad(MachineInstrBuilder &MIB, Register BlockReg) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void restoreCalleeSavedRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const CalleeSavedInfo &CS, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
void spillCalleeSavedRegister(MachineBasicBlock &SaveBlock, MachineBasicBlock::iterator MI, const CalleeSavedInfo &CS, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegister - Default implementation for spilling a single callee saved register.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ PRIVATE_ADDRESS
Address space for private memory.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned getVGPRAllocGranule(const MCSubtargetInfo *STI, unsigned DynamicVGPRBlockSize, std::optional< bool > EnableWavefrontSize32)
uint64_t convertSMRDOffsetUnits(const MCSubtargetInfo &ST, uint64_t ByteOffset)
Convert ByteOffset to dwords if the subtarget uses dword SMRD immediate offsets.
LLVM_READNONE constexpr bool isEntryFunctionCC(CallingConv::ID CC)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM_READNONE constexpr bool isCompute(CallingConv::ID CC)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ ScalablePredicateVector
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
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.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
@ And
Bitwise or logical AND of integers.
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
@ PRIVATE_SEGMENT_WAVE_BYTE_OFFSET
static constexpr uint64_t encode(Fields... Values)
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.