diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIFrameLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIFrameLowering.cpp | 102 |
1 files changed, 59 insertions, 43 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp index c9883d38e08c..882b9a203755 100644 --- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp @@ -125,8 +125,8 @@ static void buildPrologSpill(const GCNSubtarget &ST, const SIRegisterInfo &TRI, const SIMachineFunctionInfo &FuncInfo, LivePhysRegs &LiveRegs, MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, Register SpillReg, - int FI) { + MachineBasicBlock::iterator I, const DebugLoc &DL, + Register SpillReg, int FI) { unsigned Opc = ST.enableFlatScratch() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR : AMDGPU::BUFFER_STORE_DWORD_OFFSET; @@ -136,7 +136,7 @@ static void buildPrologSpill(const GCNSubtarget &ST, const SIRegisterInfo &TRI, PtrInfo, MachineMemOperand::MOStore, FrameInfo.getObjectSize(FI), FrameInfo.getObjectAlign(FI)); LiveRegs.addReg(SpillReg); - TRI.buildSpillLoadStore(MBB, I, Opc, FI, SpillReg, true, + TRI.buildSpillLoadStore(MBB, I, DL, Opc, FI, SpillReg, true, FuncInfo.getStackPtrOffsetReg(), 0, MMO, nullptr, &LiveRegs); LiveRegs.removeReg(SpillReg); @@ -147,8 +147,8 @@ static void buildEpilogRestore(const GCNSubtarget &ST, const SIMachineFunctionInfo &FuncInfo, LivePhysRegs &LiveRegs, MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, Register SpillReg, - int FI) { + MachineBasicBlock::iterator I, + const DebugLoc &DL, Register SpillReg, int FI) { unsigned Opc = ST.enableFlatScratch() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR : AMDGPU::BUFFER_LOAD_DWORD_OFFSET; @@ -157,7 +157,7 @@ static void buildEpilogRestore(const GCNSubtarget &ST, MachineMemOperand *MMO = MF.getMachineMemOperand( PtrInfo, MachineMemOperand::MOLoad, FrameInfo.getObjectSize(FI), FrameInfo.getObjectAlign(FI)); - TRI.buildSpillLoadStore(MBB, I, Opc, FI, SpillReg, false, + TRI.buildSpillLoadStore(MBB, I, DL, Opc, FI, SpillReg, false, FuncInfo.getStackPtrOffsetReg(), 0, MMO, nullptr, &LiveRegs); } @@ -258,9 +258,10 @@ void SIFrameLowering::emitEntryFunctionFlatScratchInit( // Mask the offset in [47:0] of the descriptor const MCInstrDesc &SAndB32 = TII->get(AMDGPU::S_AND_B32); - BuildMI(MBB, I, DL, SAndB32, FlatScrInitHi) + auto And = BuildMI(MBB, I, DL, SAndB32, FlatScrInitHi) .addReg(FlatScrInitHi) .addImm(0xffff); + And->getOperand(3).setIsDead(); // Mark SCC as dead. } else { Register FlatScratchInitReg = MFI->getPreloadedReg(AMDGPUFunctionArgInfo::FLAT_SCRATCH_INIT); @@ -280,9 +281,12 @@ void SIFrameLowering::emitEntryFunctionFlatScratchInit( BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADD_U32), FlatScrInitLo) .addReg(FlatScrInitLo) .addReg(ScratchWaveOffsetReg); - BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), FlatScrInitHi) + auto Addc = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), + FlatScrInitHi) .addReg(FlatScrInitHi) .addImm(0); + Addc->getOperand(3).setIsDead(); // Mark SCC as dead. + BuildMI(MBB, I, DL, TII->get(AMDGPU::S_SETREG_B32)). addReg(FlatScrInitLo). addImm(int16_t(AMDGPU::Hwreg::ID_FLAT_SCR_LO | @@ -298,9 +302,11 @@ void SIFrameLowering::emitEntryFunctionFlatScratchInit( BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADD_U32), AMDGPU::FLAT_SCR_LO) .addReg(FlatScrInitLo) .addReg(ScratchWaveOffsetReg); - BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), AMDGPU::FLAT_SCR_HI) + auto Addc = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), + AMDGPU::FLAT_SCR_HI) .addReg(FlatScrInitHi) .addImm(0); + Addc->getOperand(3).setIsDead(); // Mark SCC as dead. return; } @@ -318,9 +324,11 @@ void SIFrameLowering::emitEntryFunctionFlatScratchInit( .addReg(ScratchWaveOffsetReg); // Convert offset to 256-byte units. - BuildMI(MBB, I, DL, TII->get(AMDGPU::S_LSHR_B32), AMDGPU::FLAT_SCR_HI) + auto LShr = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_LSHR_B32), + AMDGPU::FLAT_SCR_HI) .addReg(FlatScrInitLo, RegState::Kill) .addImm(8); + LShr->getOperand(3).setIsDead(true); // Mark SCC as dead. } // Note SGPRSpill stack IDs should only be used for SGPR spilling to VGPRs, not @@ -419,9 +427,6 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, Register PreloadedScratchWaveOffsetReg = MFI->getPreloadedReg( AMDGPUFunctionArgInfo::PRIVATE_SEGMENT_WAVE_BYTE_OFFSET); - // FIXME: Hack to not crash in situations which emitted an error. - if (!PreloadedScratchWaveOffsetReg) - return; // We need to do the replacement of the private segment buffer register even // if there are no stack objects. There could be stores to undef or a @@ -467,7 +472,8 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, // chosen by SITargetLowering::allocateSystemSGPRs, COPY the scratch // wave offset to a free SGPR. Register ScratchWaveOffsetReg; - if (TRI->isSubRegisterEq(ScratchRsrcReg, PreloadedScratchWaveOffsetReg)) { + if (PreloadedScratchWaveOffsetReg && + TRI->isSubRegisterEq(ScratchRsrcReg, PreloadedScratchWaveOffsetReg)) { ArrayRef<MCPhysReg> AllSGPRs = TRI->getAllSGPR32(MF); unsigned NumPreloaded = MFI->getNumPreloadedSGPRs(); AllSGPRs = AllSGPRs.slice( @@ -485,7 +491,7 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, } else { ScratchWaveOffsetReg = PreloadedScratchWaveOffsetReg; } - assert(ScratchWaveOffsetReg); + assert(ScratchWaveOffsetReg || !PreloadedScratchWaveOffsetReg); if (requiresStackPointerReference(MF)) { Register SPReg = MFI->getStackPtrOffsetReg(); @@ -506,7 +512,7 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, (!allStackObjectsAreDead(FrameInfo) && ST.enableFlatScratch())); if ((NeedsFlatScratchInit || ScratchRsrcReg) && - !ST.flatScratchIsArchitected()) { + PreloadedScratchWaveOffsetReg && !ST.flatScratchIsArchitected()) { MRI.addLiveIn(PreloadedScratchWaveOffsetReg); MBB.addLiveIn(PreloadedScratchWaveOffsetReg); } @@ -660,10 +666,11 @@ void SIFrameLowering::emitEntryFunctionScratchRsrcRegSetup( .addReg(ScratchRsrcSub0) .addReg(ScratchWaveOffsetReg) .addReg(ScratchRsrcReg, RegState::ImplicitDefine); - BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), ScratchRsrcSub1) + auto Addc = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADDC_U32), ScratchRsrcSub1) .addReg(ScratchRsrcSub1) .addImm(0) .addReg(ScratchRsrcReg, RegState::ImplicitDefine); + Addc->getOperand(3).setIsDead(); // Mark SCC as dead. } bool SIFrameLowering::isSupportedStackID(TargetStackID::Value ID) const { @@ -720,7 +727,9 @@ static Register buildScratchExecCopy(LivePhysRegs &LiveRegs, const unsigned OrSaveExec = ST.isWave32() ? AMDGPU::S_OR_SAVEEXEC_B32 : AMDGPU::S_OR_SAVEEXEC_B64; - BuildMI(MBB, MBBI, DL, TII->get(OrSaveExec), ScratchExecCopy).addImm(-1); + auto SaveExec = BuildMI(MBB, MBBI, DL, TII->get(OrSaveExec), ScratchExecCopy) + .addImm(-1); + SaveExec->getOperand(3).setIsDead(); // Mark SCC as dead. return ScratchExecCopy; } @@ -776,7 +785,7 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, ScratchExecCopy = buildScratchExecCopy(LiveRegs, MF, MBB, MBBI, /*IsProlog*/ true); - buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, Reg.VGPR, + buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, Reg.VGPR, *Reg.FI); } @@ -791,7 +800,8 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, ScratchExecCopy = buildScratchExecCopy(LiveRegs, MF, MBB, MBBI, /*IsProlog*/ true); - buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, VGPR, *FI); + buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, VGPR, + *FI); } if (ScratchExecCopy) { @@ -817,7 +827,7 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR) .addReg(FramePtrReg); - buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, TmpVGPR, + buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, TmpVGPR, FramePtrFI); } @@ -835,7 +845,7 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR) .addReg(BasePtrReg); - buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, TmpVGPR, + buildPrologSpill(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, TmpVGPR, BasePtrFI); } @@ -927,10 +937,11 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, .addReg(StackPtrReg) .addImm((Alignment - 1) * getScratchScaleFactor(ST)) .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_AND_B32), FramePtrReg) + auto And = BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_AND_B32), FramePtrReg) .addReg(FramePtrReg, RegState::Kill) .addImm(-Alignment * getScratchScaleFactor(ST)) .setMIFlag(MachineInstr::FrameSetup); + And->getOperand(3).setIsDead(); // Mark SCC as dead. FuncInfo->setIsStackRealigned(true); } else if ((HasFP = hasFP(MF))) { BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::COPY), FramePtrReg) @@ -949,18 +960,22 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF, } if (HasFP && RoundedSize != 0) { - BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_ADD_I32), StackPtrReg) + auto Add = BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_ADD_I32), StackPtrReg) .addReg(StackPtrReg) .addImm(RoundedSize * getScratchScaleFactor(ST)) .setMIFlag(MachineInstr::FrameSetup); + Add->getOperand(3).setIsDead(); // Mark SCC as dead. } assert((!HasFP || (FuncInfo->SGPRForFPSaveRestoreCopy || FuncInfo->FramePointerSaveIndex)) && "Needed to save FP but didn't save it anywhere"); + // If we allow spilling to AGPRs we may have saved FP but then spill + // everything into AGPRs instead of the stack. assert((HasFP || (!FuncInfo->SGPRForFPSaveRestoreCopy && - !FuncInfo->FramePointerSaveIndex)) && + !FuncInfo->FramePointerSaveIndex) || + EnableSpillVGPRToAGPR) && "Saved FP but didn't need it"); assert((!HasBP || (FuncInfo->SGPRForBPSaveRestoreCopy || @@ -1000,10 +1015,11 @@ void SIFrameLowering::emitEpilogue(MachineFunction &MF, Optional<int> BPSaveIndex = FuncInfo->BasePointerSaveIndex; if (RoundedSize != 0 && hasFP(MF)) { - BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_ADD_I32), StackPtrReg) + auto Add = BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::S_ADD_I32), StackPtrReg) .addReg(StackPtrReg) .addImm(-static_cast<int64_t>(RoundedSize * getScratchScaleFactor(ST))) .setMIFlag(MachineInstr::FrameDestroy); + Add->getOperand(3).setIsDead(); // Mark SCC as dead. } if (FuncInfo->SGPRForFPSaveRestoreCopy) { @@ -1028,8 +1044,8 @@ void SIFrameLowering::emitEpilogue(MachineFunction &MF, MRI, LiveRegs, AMDGPU::VGPR_32RegClass); if (!TmpVGPR) report_fatal_error("failed to find free scratch register"); - buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, TmpVGPR, - FramePtrFI); + buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, + TmpVGPR, FramePtrFI); BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), FramePtrReg) .addReg(TmpVGPR, RegState::Kill); } else { @@ -1054,8 +1070,8 @@ void SIFrameLowering::emitEpilogue(MachineFunction &MF, MRI, LiveRegs, AMDGPU::VGPR_32RegClass); if (!TmpVGPR) report_fatal_error("failed to find free scratch register"); - buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, TmpVGPR, - BasePtrFI); + buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, + TmpVGPR, BasePtrFI); BuildMI(MBB, MBBI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), BasePtrReg) .addReg(TmpVGPR, RegState::Kill); } else { @@ -1080,8 +1096,8 @@ void SIFrameLowering::emitEpilogue(MachineFunction &MF, ScratchExecCopy = buildScratchExecCopy(LiveRegs, MF, MBB, MBBI, /*IsProlog*/ false); - buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, Reg.VGPR, - *Reg.FI); + buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, + Reg.VGPR, *Reg.FI); } for (const auto &Reg : FuncInfo->WWMReservedRegs) { @@ -1094,7 +1110,8 @@ void SIFrameLowering::emitEpilogue(MachineFunction &MF, ScratchExecCopy = buildScratchExecCopy(LiveRegs, MF, MBB, MBBI, /*IsProlog*/ false); - buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, VGPR, *FI); + buildEpilogRestore(ST, TRI, *FuncInfo, LiveRegs, MF, MBB, MBBI, DL, VGPR, + *FI); } if (ScratchExecCopy) { @@ -1154,11 +1171,7 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized( bool SeenDbgInstr = false; for (MachineBasicBlock &MBB : MF) { - MachineBasicBlock::iterator Next; - for (auto I = MBB.begin(), E = MBB.end(); I != E; I = Next) { - MachineInstr &MI = *I; - Next = std::next(I); - + for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) { if (MI.isDebugInstr()) SeenDbgInstr = true; @@ -1199,7 +1212,6 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized( if (MI.isDebugValue() && MI.getOperand(0).isFI() && SpillFIs[MI.getOperand(0).getIndex()]) { MI.getOperand(0).ChangeToRegister(Register(), false /*isDef*/); - MI.getOperand(0).setIsDebug(); } } } @@ -1301,10 +1313,13 @@ void SIFrameLowering::determineCalleeSavesSGPR(MachineFunction &MF, // If clearing VGPRs changed the mask, we will have some CSR VGPR spills. const bool HaveAnyCSRVGPR = SavedRegs != AllSavedRegs; - // We have to anticipate introducing CSR VGPR spills if we don't have any - // stack objects already, since we require an FP if there is a call and stack. + // We have to anticipate introducing CSR VGPR spills or spill of caller + // save VGPR reserved for SGPR spills as we now always create stack entry + // for it, if we don't have any stack objects already, since we require + // an FP if there is a call and stack. MachineFrameInfo &FrameInfo = MF.getFrameInfo(); - const bool WillHaveFP = FrameInfo.hasCalls() && HaveAnyCSRVGPR; + const bool WillHaveFP = + FrameInfo.hasCalls() && (HaveAnyCSRVGPR || MFI->VGPRReservedForSGPRSpill); // FP will be specially managed like SP. if (WillHaveFP || hasFP(MF)) @@ -1373,9 +1388,10 @@ MachineBasicBlock::iterator SIFrameLowering::eliminateCallFramePseudoInstr( Amount *= getScratchScaleFactor(ST); if (IsDestroy) Amount = -Amount; - BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADD_I32), SPReg) + auto Add = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ADD_I32), SPReg) .addReg(SPReg) .addImm(Amount); + Add->getOperand(3).setIsDead(); // Mark SCC as dead. } else if (CalleePopAmount != 0) { llvm_unreachable("is this used?"); } |
