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);
 
  311      BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 
SubReg)
 
  317  void restoreFromVGPRLane(
const int FI) {
 
  320        FuncInfo->getSGPRSpillToPhysicalVGPRLanes(FI);
 
  321    assert(Spill.size() == NumSubRegs);
 
  323    for (
unsigned I = 0; 
I < NumSubRegs; ++
I) {
 
  326                            : 
Register(TRI.getSubReg(SuperReg, SplitParts[
I]));
 
  327      BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), 
SubReg)
 
  333  void copyFromScratchSGPR(
Register SrcReg)
 const {
 
  334    BuildMI(MBB, MI, DL, TII->get(AMDGPU::COPY), SuperReg)
 
  347      : MI(MI), MBB(MBB), MF(*MBB.
getParent()),
 
  348        ST(MF.getSubtarget<
GCNSubtarget>()), MFI(MF.getFrameInfo()),
 
  350        SuperReg(Reg), SI(SI), LiveUnits(LiveUnits), DL(DL),
 
  353    SplitParts = TRI.getRegSplitParts(RC, EltSize);
 
  354    NumSubRegs = SplitParts.empty() ? 1 : SplitParts.size();
 
  356    assert(SuperReg != AMDGPU::M0 && 
"m0 should never spill");
 
 
  360    switch (SI.getKind()) {
 
  362      return saveToMemory(SI.getIndex());
 
  364      return saveToVGPRLane(SI.getIndex());
 
  366      return copyToScratchSGPR(SI.getReg());
 
 
  371    switch (SI.getKind()) {
 
  373      return restoreFromMemory(SI.getIndex());
 
  375      return restoreFromVGPRLane(SI.getIndex());
 
  377      return copyFromScratchSGPR(SI.getReg());
 
 
 
  385void SIFrameLowering::emitEntryFunctionFlatScratchInit(
 
  389  const SIInstrInfo *
TII = 
ST.getInstrInfo();
 
  390  const SIRegisterInfo *
TRI = &
TII->getRegisterInfo();
 
  391  const SIMachineFunctionInfo *MFI = MF.
getInfo<SIMachineFunctionInfo>();
 
  406  if (
ST.isAmdPalOS()) {
 
  408    LiveRegUnits LiveUnits;
 
  414    Register FlatScrInit = AMDGPU::NoRegister;
 
  417    AllSGPR64s = AllSGPR64s.
slice(
 
  418        std::min(
static_cast<unsigned>(AllSGPR64s.
size()), NumPreloaded));
 
  422          MRI.isAllocatable(
Reg) && !
TRI->isSubRegisterEq(
Reg, GITPtrLoReg)) {
 
  427    assert(FlatScrInit && 
"Failed to find free register for scratch init");
 
  429    FlatScrInitLo = 
TRI->getSubReg(FlatScrInit, AMDGPU::sub0);
 
  430    FlatScrInitHi = 
TRI->getSubReg(FlatScrInit, AMDGPU::sub1);
 
  437    const MCInstrDesc &LoadDwordX2 = 
TII->get(AMDGPU::S_LOAD_DWORDX2_IMM);
 
  445    const GCNSubtarget &Subtarget = MF.
getSubtarget<GCNSubtarget>();
 
  454    const MCInstrDesc &SAndB32 = 
TII->get(AMDGPU::S_AND_B32);
 
  462    assert(FlatScratchInitReg);
 
  465    MRI.addLiveIn(FlatScratchInitReg);
 
  468    FlatScrInitLo = 
TRI->getSubReg(FlatScratchInitReg, AMDGPU::sub0);
 
  469    FlatScrInitHi = 
TRI->getSubReg(FlatScratchInitReg, AMDGPU::sub1);
 
  473  if (
ST.flatScratchIsPointer()) {
 
  477        .
addReg(ScratchWaveOffsetReg);
 
  484      using namespace AMDGPU::Hwreg;
 
  487          .
addImm(int16_t(HwregEncoding::encode(ID_FLAT_SCR_LO, 0, 32)));
 
  490          .
addImm(int16_t(HwregEncoding::encode(ID_FLAT_SCR_HI, 0, 32)));
 
  497      .
addReg(ScratchWaveOffsetReg);
 
  517      .
addReg(ScratchWaveOffsetReg);
 
  540Register SIFrameLowering::getEntryFunctionReservedScratchRsrcReg(
 
  544  const SIInstrInfo *
TII = 
ST.getInstrInfo();
 
  545  const SIRegisterInfo *
TRI = &
TII->getRegisterInfo();
 
  547  SIMachineFunctionInfo *MFI = MF.
getInfo<SIMachineFunctionInfo>();
 
  553  if (!ScratchRsrcReg || (!
MRI.isPhysRegUsed(ScratchRsrcReg) &&
 
  557  if (
ST.hasSGPRInitBug() ||
 
  558      ScratchRsrcReg != 
TRI->reservedPrivateSegmentBufferReg(MF))
 
  559    return ScratchRsrcReg;
 
  572  AllSGPR128s = AllSGPR128s.
slice(std::min(
static_cast<unsigned>(AllSGPR128s.
size()), NumPreloaded));
 
  581    if (!
MRI.isPhysRegUsed(
Reg) && 
MRI.isAllocatable(
Reg) &&
 
  582        (!GITPtrLoReg || !
TRI->isSubRegisterEq(
Reg, GITPtrLoReg))) {
 
  583      MRI.replaceRegWith(ScratchRsrcReg, 
Reg);
 
  590  return ScratchRsrcReg;
 
  594  return ST.enableFlatScratch() ? 1 : ST.getWavefrontSize();
 
 
  599  assert(&MF.
front() == &
MBB && 
"Shrink-wrapping not yet supported");
 
  632  if (!ST.enableFlatScratch())
 
  633    ScratchRsrcReg = getEntryFunctionReservedScratchRsrcReg(MF);
 
  636  if (ScratchRsrcReg) {
 
  638      if (&OtherBB != &
MBB) {
 
  639        OtherBB.addLiveIn(ScratchRsrcReg);
 
  647  if (ST.isAmdHsaOrMesa(
F)) {
 
  648    PreloadedScratchRsrcReg =
 
  650    if (ScratchRsrcReg && PreloadedScratchRsrcReg) {
 
  653      MRI.addLiveIn(PreloadedScratchRsrcReg);
 
  654      MBB.addLiveIn(PreloadedScratchRsrcReg);
 
  669  if (PreloadedScratchWaveOffsetReg &&
 
  670      TRI->isSubRegisterEq(ScratchRsrcReg, PreloadedScratchWaveOffsetReg)) {
 
  673    AllSGPRs = AllSGPRs.
slice(
 
  674        std::min(
static_cast<unsigned>(AllSGPRs.
size()), NumPreloaded));
 
  677      if (!
MRI.isPhysRegUsed(Reg) && 
MRI.isAllocatable(Reg) &&
 
  678          !
TRI->isSubRegisterEq(ScratchRsrcReg, Reg) && GITPtrLoReg != Reg) {
 
  679        ScratchWaveOffsetReg = Reg;
 
  688    if (!ScratchWaveOffsetReg)
 
  690          "could not find temporary scratch offset register in prolog");
 
  692    ScratchWaveOffsetReg = PreloadedScratchWaveOffsetReg;
 
  694  assert(ScratchWaveOffsetReg || !PreloadedScratchWaveOffsetReg);
 
  743                                       ST.hasInv2PiInlineImm())) {
 
  755  bool NeedsFlatScratchInit =
 
  757      (
MRI.isPhysRegUsed(AMDGPU::FLAT_SCR) || FrameInfo.
hasCalls() ||
 
  760  if ((NeedsFlatScratchInit || ScratchRsrcReg) &&
 
  761      PreloadedScratchWaveOffsetReg && !ST.flatScratchIsArchitected()) {
 
  762    MRI.addLiveIn(PreloadedScratchWaveOffsetReg);
 
  763    MBB.addLiveIn(PreloadedScratchWaveOffsetReg);
 
  766  if (NeedsFlatScratchInit) {
 
  767    emitEntryFunctionFlatScratchInit(MF, 
MBB, 
I, 
DL, ScratchWaveOffsetReg);
 
  770  if (ScratchRsrcReg) {
 
  771    emitEntryFunctionScratchRsrcRegSetup(MF, 
MBB, 
I, 
DL,
 
  772                                         PreloadedScratchRsrcReg,
 
  773                                         ScratchRsrcReg, ScratchWaveOffsetReg);
 
 
  778void SIFrameLowering::emitEntryFunctionScratchRsrcRegSetup(
 
  789  if (ST.isAmdPalOS()) {
 
  792    Register Rsrc01 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0_sub1);
 
  793    Register Rsrc03 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub3);
 
  800    const MCInstrDesc &LoadDwordX4 = 
TII->get(AMDGPU::S_LOAD_DWORDX4_IMM);
 
  829  } 
else if (
ST.isMesaGfxShader(Fn) || !PreloadedScratchRsrcReg) {
 
  831    const MCInstrDesc &SMovB32 = 
TII->get(AMDGPU::S_MOV_B32);
 
  833    Register Rsrc2 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub2);
 
  834    Register Rsrc3 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub3);
 
  837    uint64_t Rsrc23 = 
TII->getScratchRsrcWords23();
 
  840      Register Rsrc01 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0_sub1);
 
  843        const MCInstrDesc &Mov64 = 
TII->get(AMDGPU::S_MOV_B64);
 
  849        const MCInstrDesc &LoadDwordX2 = 
TII->get(AMDGPU::S_LOAD_DWORDX2_IMM);
 
  868      Register Rsrc0 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0);
 
  869      Register Rsrc1 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub1);
 
  887  } 
else if (
ST.isAmdHsaOrMesa(Fn)) {
 
  888    assert(PreloadedScratchRsrcReg);
 
  890    if (ScratchRsrcReg != PreloadedScratchRsrcReg) {
 
  905  Register ScratchRsrcSub0 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0);
 
  906  Register ScratchRsrcSub1 = 
TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub1);
 
  912      .
addReg(ScratchWaveOffsetReg)
 
  914  auto Addc = 
BuildMI(
MBB, 
I, 
DL, 
TII->get(AMDGPU::S_ADDC_U32), ScratchRsrcSub1)
 
  942                                     bool EnableInactiveLanes) {
 
  955    assert(IsProlog && 
"Epilog should look at return, not setup");
 
  957        TII->getWholeWaveFunctionSetup(MF)->getOperand(0).getReg();
 
  958    assert(ScratchExecCopy && 
"Couldn't find copy of EXEC");
 
  961        MRI, LiveUnits, *
TRI.getWaveMaskRegClass());
 
  964  if (!ScratchExecCopy)
 
  967  LiveUnits.
addReg(ScratchExecCopy);
 
  969  const unsigned SaveExecOpc =
 
  970      ST.isWave32() ? (EnableInactiveLanes ? AMDGPU::S_XOR_SAVEEXEC_B32
 
  971                                           : AMDGPU::S_OR_SAVEEXEC_B32)
 
  972                    : (EnableInactiveLanes ? AMDGPU::S_XOR_SAVEEXEC_B64
 
  973                                           : AMDGPU::S_OR_SAVEEXEC_B64);
 
  978  return ScratchExecCopy;
 
 
  998  if (!WWMScratchRegs.
empty())
 
 1003  auto StoreWWMRegisters =
 
 1005        for (
const auto &Reg : WWMRegs) {
 
 1007          int FI = Reg.second;
 
 1009                           VGPR, FI, FrameReg);
 
 1014    if (!
MRI.isReserved(Reg)) {
 
 1019  StoreWWMRegisters(WWMScratchRegs);
 
 1021  auto EnableAllLanes = [&]() {
 
 1025  if (!WWMCalleeSavedRegs.
empty()) {
 
 1026    if (ScratchExecCopy) {
 
 1035  StoreWWMRegisters(WWMCalleeSavedRegs);
 
 1039    if (!ScratchExecCopy)
 
 1042    else if (WWMCalleeSavedRegs.
empty())
 
 1044  } 
else if (ScratchExecCopy) {
 
 1048    LiveUnits.
addReg(ScratchExecCopy);
 
 1059        Spill.first == FramePtrReg ? FramePtrRegScratchCopy : Spill.first;
 
 1064                                    LiveUnits, FrameReg);
 
 1072  if (!ScratchSGPRs.
empty()) {
 
 1077      MBB.sortUniqueLiveIns();
 
 1079    if (!LiveUnits.
empty()) {
 
 
 1104        Spill.first == FramePtrReg ? FramePtrRegScratchCopy : Spill.first;
 
 1109                                    LiveUnits, FrameReg);
 
 1119  auto RestoreWWMRegisters =
 
 1121        for (
const auto &Reg : WWMRegs) {
 
 1123          int FI = Reg.second;
 
 1125                             VGPR, FI, FrameReg);
 
 1132    RestoreWWMRegisters(WWMCalleeSavedRegs);
 
 1136    unsigned Opcode = Return.getOpcode();
 
 1138    case AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN:
 
 1139      Opcode = AMDGPU::SI_RETURN;
 
 1141    case AMDGPU::SI_TCRETURN_GFX_WholeWave:
 
 1142      Opcode = AMDGPU::SI_TCRETURN_GFX;
 
 1147    Register OrigExec = Return.getOperand(0).getReg();
 
 1149    if (!WWMScratchRegs.
empty()) {
 
 1153      RestoreWWMRegisters(WWMScratchRegs);
 
 1160    Return.removeOperand(0);
 
 1161    Return.setDesc(
TII->get(Opcode));
 
 1166  if (!WWMScratchRegs.
empty()) {
 
 1171  RestoreWWMRegisters(WWMScratchRegs);
 
 1172  if (!WWMCalleeSavedRegs.
empty()) {
 
 1173    if (ScratchExecCopy) {
 
 1182  RestoreWWMRegisters(WWMCalleeSavedRegs);
 
 1183  if (ScratchExecCopy) {
 
 
 1220      assert(StackPtrReg != AMDGPU::SP_REG);
 
 1232  if (
TRI.hasStackRealignment(MF))
 
 1236  if (!HasFP && !
hasFP(MF)) {
 
 1240                       FramePtrRegScratchCopy);
 
 1243    Register SGPRForFPSaveRestoreCopy =
 
 1247    if (SGPRForFPSaveRestoreCopy) {
 
 1254          DL, 
TII, 
TRI, LiveUnits, FramePtrReg);
 
 1256      LiveUnits.
addReg(SGPRForFPSaveRestoreCopy);
 
 1261          MRI, LiveUnits, AMDGPU::SReg_32_XM0_XEXECRegClass);
 
 1262      if (!FramePtrRegScratchCopy)
 
 1265      LiveUnits.
addReg(FramePtrRegScratchCopy);
 
 1274    RoundedSize += Alignment;
 
 1275    if (LiveUnits.
empty()) {
 
 1290    And->getOperand(3).setIsDead(); 
 
 1292  } 
else if ((HasFP = 
hasFP(MF))) {
 
 1301                       FramePtrRegScratchCopy);
 
 1302    if (FramePtrRegScratchCopy)
 
 1303      LiveUnits.
removeReg(FramePtrRegScratchCopy);
 
 1310  if ((HasBP = 
TRI.hasBasePointer(MF))) {
 
 1316  if (HasFP && RoundedSize != 0) {
 
 1321    Add->getOperand(3).setIsDead(); 
 
 1326  assert((!HasFP || FPSaved) &&
 
 1327         "Needed to save FP but didn't save it anywhere");
 
 1332         "Saved FP but didn't need it");
 
 1336  assert((!HasBP || BPSaved) &&
 
 1337         "Needed to save BP but didn't save it anywhere");
 
 1339  assert((HasBP || !BPSaved) && 
"Saved BP but didn't need it");
 
 1343    TII->getWholeWaveFunctionSetup(MF)->eraseFromParent();
 
 
 1363    MBBI = 
MBB.getLastNonDebugInstr();
 
 1365      DL = 
MBBI->getDebugLoc();
 
 1367    MBBI = 
MBB.getFirstTerminator();
 
 1379  if (RoundedSize != 0) {
 
 1380    if (
TRI.hasBasePointer(MF)) {
 
 1384    } 
else if (
hasFP(MF)) {
 
 1392  Register SGPRForFPSaveRestoreCopy =
 
 1400    if (SGPRForFPSaveRestoreCopy) {
 
 1401      LiveUnits.
addReg(SGPRForFPSaveRestoreCopy);
 
 1404          MRI, LiveUnits, AMDGPU::SReg_32_XM0_XEXECRegClass);
 
 1405      if (!FramePtrRegScratchCopy)
 
 1408      LiveUnits.
addReg(FramePtrRegScratchCopy);
 
 1412                         FramePtrRegScratchCopy);
 
 1417    Register SrcReg = SGPRForFPSaveRestoreCopy ? SGPRForFPSaveRestoreCopy
 
 1418                                               : FramePtrRegScratchCopy;
 
 1422    if (SGPRForFPSaveRestoreCopy)
 
 1428                         FramePtrRegScratchCopy);
 
 
 1469  const bool SpillVGPRToAGPR = ST.hasMAIInsts() && FuncInfo->
hasSpilledVGPRs()
 
 1472  if (SpillVGPRToAGPR) {
 
 1477    bool SeenDbgInstr = 
false;
 
 1482        if (
MI.isDebugInstr())
 
 1483          SeenDbgInstr = 
true;
 
 1485        if (
TII->isVGPRSpill(
MI)) {
 
 1488          unsigned FIOp = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
 
 1489                                                     AMDGPU::OpName::vaddr);
 
 1490          int FI = 
MI.getOperand(FIOp).getIndex();
 
 1492            TII->getNamedOperand(
MI, AMDGPU::OpName::vdata)->getReg();
 
 1494                                                TRI->isAGPR(
MRI, VReg))) {
 
 1496            RS->enterBasicBlockEnd(
MBB);
 
 1497            RS->backward(std::next(
MI.getIterator()));
 
 1498            TRI->eliminateFrameIndex(
MI, 0, FIOp, RS);
 
 1502        } 
else if (
TII->isStoreToStackSlot(
MI, FrameIndex) ||
 
 1503                   TII->isLoadFromStackSlot(
MI, FrameIndex))
 
 1505            NonVGPRSpillFIs.
set(FrameIndex);
 
 1511    for (
unsigned FI : SpillFIs.
set_bits())
 
 1512      if (!NonVGPRSpillFIs.
test(FI))
 
 1522      MBB.sortUniqueLiveIns();
 
 1524      if (!SpillFIs.
empty() && SeenDbgInstr) {
 
 1529          if (
MI.isDebugValue()) {
 
 1530            uint32_t StackOperandIdx = 
MI.isDebugValueList() ? 2 : 0;
 
 1531            if (
MI.getOperand(StackOperandIdx).isFI() &&
 
 1533                    MI.getOperand(StackOperandIdx).getIndex()) &&
 
 1534                SpillFIs[
MI.getOperand(StackOperandIdx).getIndex()]) {
 
 1535              MI.getOperand(StackOperandIdx)
 
 1536                  .ChangeToRegister(
Register(), 
false );
 
 1547  bool HaveSGPRToVMemSpill =
 
 1550         "SGPR spill should have been removed in SILowerSGPRSpills");
 
 1556    assert(RS && 
"RegScavenger required if spilling");
 
 1563    if (HaveSGPRToVMemSpill &&
 
 
 1577  if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
 
 1584        TRI->findUnusedRegister(
MRI, &AMDGPU::VGPR_32RegClass, MF);
 
 1585    if (UnusedLowVGPR && (
TRI->getHWRegIndex(UnusedLowVGPR) <
 
 1586                          TRI->getHWRegIndex(VGPRForAGPRCopy))) {
 
 1592      MRI.reserveReg(UnusedLowVGPR, 
TRI);
 
 1599      TRI->findUnusedRegister(
MRI, &AMDGPU::SGPR_64RegClass, MF);
 
 1604  if (LongBranchReservedReg && UnusedLowSGPR) {
 
 1606    MRI.reserveReg(UnusedLowSGPR, 
TRI);
 
 
 1614    bool NeedExecCopyReservedReg)
 const {
 
 1625  for (
unsigned I = 0; CSRegs[
I]; ++
I)
 
 1631  if (NeedExecCopyReservedReg ||
 
 1632      (ReservedRegForExecCopy &&
 
 1633       MRI.isPhysRegUsed(ReservedRegForExecCopy, 
true))) {
 
 1634    MRI.reserveReg(ReservedRegForExecCopy, 
TRI);
 
 1636    if (UnusedScratchReg) {
 
 1640      MRI.replaceRegWith(ReservedRegForExecCopy, UnusedScratchReg);
 
 1641      LiveUnits.
addReg(UnusedScratchReg);
 
 1645             "Re-reserving spill slot for EXEC copy register");
 
 1649  } 
else if (ReservedRegForExecCopy) {
 
 1663  const bool WillHaveFP =
 
 1667  if (WillHaveFP || 
hasFP(MF)) {
 
 1670           "Re-reserving spill slot for FP");
 
 1674  if (
TRI->hasBasePointer(MF)) {
 
 1677           "Re-reserving spill slot for BP");
 
 
 1699  bool NeedExecCopyReservedReg = 
false;
 
 1706      if (
TII->isWWMRegSpillOpcode(
MI.getOpcode()))
 
 1707        NeedExecCopyReservedReg = 
true;
 
 1708      else if (
MI.getOpcode() == AMDGPU::SI_RETURN ||
 
 1709               MI.getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG ||
 
 1710               MI.getOpcode() == AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN ||
 
 1712                TII->isChainCallOpcode(
MI.getOpcode()))) {
 
 1715               (
count_if(
MI.operands(), [](
auto Op) { return Op.isReg(); }) ==
 
 1728    if (
TRI->getRegSizeInBits(*RC) != 32)
 
 1733  sort(SortedWWMVGPRs, std::greater<Register>());
 
 1742    assert(!NeedExecCopyReservedReg &&
 
 1743           "Whole wave functions can use the reg mapped for their i1 argument");
 
 1746    unsigned NumArchVGPRs = ST.has1024AddressableVGPRs() ? 1024 : 256;
 
 1748         AMDGPU::VGPR_32RegClass.getRegisters().take_front(NumArchVGPRs))
 
 1751        MF.
begin()->addLiveIn(Reg);
 
 1753    MF.
begin()->sortUniqueLiveIns();
 
 1761        SavedVGPRs.
reset(
Op.getReg());
 
 1769                          TRI->getSpillAlign(*RC));
 
 1778  if (!ST.hasGFX90AInsts())
 
 1786    SavedVGPRs.
reset(Reg.first);
 
 
 1803  const BitVector AllSavedRegs = SavedRegs;
 
 1812  const bool WillHaveFP =
 
 1816  if (WillHaveFP || 
hasFP(MF))
 
 1826  Register RetAddrReg = 
TRI->getReturnAddressReg(MF);
 
 1828      (FrameInfo.
hasCalls() || 
MRI.isPhysRegModified(RetAddrReg))) {
 
 1829    SavedRegs.
set(
TRI->getSubReg(RetAddrReg, AMDGPU::sub0));
 
 1830    SavedRegs.
set(
TRI->getSubReg(RetAddrReg, AMDGPU::sub1));
 
 
 1836                                       std::vector<CalleeSavedInfo> &CSI,
 
 1837                                       unsigned &MinCSFrameIndex,
 
 1838                                       unsigned &MaxCSFrameIndex) {
 
 1846                        return A.getReg() < 
B.getReg();
 
 1848      "Callee saved registers not sorted");
 
 1851    return !CSI.isSpilledToReg() &&
 
 1852           TRI->getPhysRegBaseClass(CSI.getReg()) == &AMDGPU::VGPR_32RegClass &&
 
 1856  auto CSEnd = CSI.end();
 
 1857  for (
auto CSIt = CSI.begin(); CSIt != CSEnd; ++CSIt) {
 
 1859    if (!CanUseBlockOps(*CSIt))
 
 1866    CSEnd = std::remove_if(
 
 1868          if (CanUseBlockOps(CSI) && CSI.
getReg() < 
Reg + 32) {
 
 1878        TRI->getMatchingSuperReg(
Reg, AMDGPU::sub0, BlockRegClass);
 
 1887          TRI->getMatchingSuperReg(LastBlockStart, AMDGPU::sub0, BlockRegClass);
 
 1888      assert(RegBlock && 
TRI->isSubRegister(RegBlock, 
Reg) &&
 
 1889             "Couldn't find super register");
 
 1890      int RegDelta = 
Reg - LastBlockStart;
 
 1892             "Bad shift amount");
 
 1903    unsigned BlockSize = 
TRI->getSpillSize(*BlockRegClass) - UnusedBits * 4;
 
 1905        MFI.CreateStackObject(
BlockSize, 
TRI->getSpillAlign(*BlockRegClass),
 
 1907    if ((
unsigned)FrameIdx < MinCSFrameIndex)
 
 1908      MinCSFrameIndex = FrameIdx;
 
 1909    if ((
unsigned)FrameIdx > MaxCSFrameIndex)
 
 1910      MaxCSFrameIndex = FrameIdx;
 
 1912    CSIt->setFrameIdx(FrameIdx);
 
 1913    CSIt->setReg(RegBlock);
 
 1915  CSI.erase(CSEnd, CSI.end());
 
 
 1920    std::vector<CalleeSavedInfo> &CSI, 
unsigned &MinCSFrameIndex,
 
 1921    unsigned &MaxCSFrameIndex)
 const {
 
 1926  bool UseVGPRBlocks = ST.useVGPRBlockOpsForCSR();
 
 
 1936    std::vector<CalleeSavedInfo> &CSI)
 const {
 
 1944  Register BasePtrReg = RI->getBaseRegister();
 
 1945  Register SGPRForFPSaveRestoreCopy =
 
 1947  Register SGPRForBPSaveRestoreCopy =
 
 1949  if (!SGPRForFPSaveRestoreCopy && !SGPRForBPSaveRestoreCopy)
 
 1952  unsigned NumModifiedRegs = 0;
 
 1954  if (SGPRForFPSaveRestoreCopy)
 
 1956  if (SGPRForBPSaveRestoreCopy)
 
 1959  for (
auto &CS : CSI) {
 
 1960    if (CS.getReg() == FramePtrReg.
asMCReg() && SGPRForFPSaveRestoreCopy) {
 
 1961      CS.setDstReg(SGPRForFPSaveRestoreCopy);
 
 1962      if (--NumModifiedRegs)
 
 1964    } 
else if (CS.getReg() == BasePtrReg.
asMCReg() &&
 
 1965               SGPRForBPSaveRestoreCopy) {
 
 1966      CS.setDstReg(SGPRForBPSaveRestoreCopy);
 
 1967      if (--NumModifiedRegs)
 
 
 1981  uint64_t EstStackSize = MFI.estimateStackSize(MF);
 
 1982  uint64_t MaxOffset = EstStackSize - 1;
 
 1991  if (ST.enableFlatScratch()) {
 
 1996    if (
TII->isLegalMUBUFImmOffset(MaxOffset))
 
 
 2008  if (!ST.useVGPRBlockOpsForCSR())
 
 2020    if (!BlockRegClass->contains(Reg) ||
 
 2028    int FrameIndex = CS.getFrameIdx();
 
 2037            TII->get(AMDGPU::SI_BLOCK_SPILL_V1024_SAVE))
 
 2053  MBB.sortUniqueLiveIns();
 
 
 2063  if (!ST.useVGPRBlockOpsForCSR())
 
 2073    if (!BlockRegClass->
contains(Reg) ||
 
 2081    int FrameIndex = CS.getFrameIdx();
 
 2086        MFI.getObjectAlign(FrameIndex));
 
 2089                       TII->get(AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE), Reg)
 
 2104  MBB.sortUniqueLiveIns();
 
 
 2112  int64_t Amount = 
I->getOperand(0).getImm();
 
 2114    return MBB.erase(
I);
 
 2119  unsigned Opc = 
I->getOpcode();
 
 2120  bool IsDestroy = 
Opc == 
TII->getCallFrameDestroyOpcode();
 
 2121  uint64_t CalleePopAmount = IsDestroy ? 
I->getOperand(1).getImm() : 0;
 
 2135    Add->getOperand(3).setIsDead(); 
 
 2136  } 
else if (CalleePopAmount != 0) {
 
 2140  return MBB.erase(
I);
 
 
 2199         "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)
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.