diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp | 136 |
1 files changed, 22 insertions, 114 deletions
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp index 47d28d5d0eab..d21107c02ef7 100644 --- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp @@ -50,9 +50,7 @@ public: SILowerSGPRSpills() : MachineFunctionPass(ID) {} void calculateSaveRestoreBlocks(MachineFunction &MF); - bool spillCalleeSavedRegs(MachineFunction &MF, - SmallVectorImpl<int> &CalleeSavedFIs); - void extendWWMVirtRegLiveness(MachineFunction &MF, LiveIntervals *LIS); + bool spillCalleeSavedRegs(MachineFunction &MF); bool runOnMachineFunction(MachineFunction &MF) override; @@ -60,13 +58,6 @@ public: AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } - - MachineFunctionProperties getClearedProperties() const override { - // SILowerSGPRSpills introduces new Virtual VGPRs for spilling SGPRs. - return MachineFunctionProperties() - .set(MachineFunctionProperties::Property::IsSSA) - .set(MachineFunctionProperties::Property::NoVRegs); - } }; } // end anonymous namespace @@ -206,8 +197,7 @@ static void updateLiveness(MachineFunction &MF, ArrayRef<CalleeSavedInfo> CSI) { EntryBB.sortUniqueLiveIns(); } -bool SILowerSGPRSpills::spillCalleeSavedRegs( - MachineFunction &MF, SmallVectorImpl<int> &CalleeSavedFIs) { +bool SILowerSGPRSpills::spillCalleeSavedRegs(MachineFunction &MF) { MachineRegisterInfo &MRI = MF.getRegInfo(); const Function &F = MF.getFunction(); const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); @@ -238,7 +228,6 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs( TRI->getSpillAlign(*RC), true); CSI.push_back(CalleeSavedInfo(Reg, JunkFI)); - CalleeSavedFIs.push_back(JunkFI); } } @@ -259,50 +248,6 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs( return false; } -void SILowerSGPRSpills::extendWWMVirtRegLiveness(MachineFunction &MF, - LiveIntervals *LIS) { - // TODO: This is a workaround to avoid the unmodelled liveness computed with - // whole-wave virtual registers when allocated together with the regular VGPR - // virtual registers. Presently, the liveness computed during the regalloc is - // only uniform (or single lane aware) and it doesn't take account of the - // divergent control flow that exists for our GPUs. Since the WWM registers - // can modify inactive lanes, the wave-aware liveness should be computed for - // the virtual registers to accurately plot their interferences. Without - // having the divergent CFG for the function, it is difficult to implement the - // wave-aware liveness info. Until then, we conservatively extend the liveness - // of the wwm registers into the entire function so that they won't be reused - // without first spilling/splitting their liveranges. - SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); - - // Insert the IMPLICIT_DEF for the wwm-registers in the entry blocks. - for (auto Reg : MFI->getSGPRSpillVGPRs()) { - for (MachineBasicBlock *SaveBlock : SaveBlocks) { - MachineBasicBlock::iterator InsertBefore = SaveBlock->begin(); - auto MIB = BuildMI(*SaveBlock, *InsertBefore, InsertBefore->getDebugLoc(), - TII->get(AMDGPU::IMPLICIT_DEF), Reg); - MFI->setFlag(Reg, AMDGPU::VirtRegFlag::WWM_REG); - if (LIS) { - LIS->InsertMachineInstrInMaps(*MIB); - } - } - } - - // Insert the KILL in the return blocks to extend their liveness untill the - // end of function. Insert a separate KILL for each VGPR. - for (MachineBasicBlock *RestoreBlock : RestoreBlocks) { - MachineBasicBlock::iterator InsertBefore = - RestoreBlock->getFirstTerminator(); - for (auto Reg : MFI->getSGPRSpillVGPRs()) { - auto MIB = - BuildMI(*RestoreBlock, *InsertBefore, InsertBefore->getDebugLoc(), - TII->get(TargetOpcode::KILL)); - MIB.addReg(Reg); - if (LIS) - LIS->InsertMachineInstrInMaps(*MIB); - } - } -} - bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); TII = ST.getInstrInfo(); @@ -316,8 +261,7 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { // First, expose any CSR SGPR spills. This is mostly the same as what PEI // does, but somewhat simpler. calculateSaveRestoreBlocks(MF); - SmallVector<int> CalleeSavedFIs; - bool HasCSRs = spillCalleeSavedRegs(MF, CalleeSavedFIs); + bool HasCSRs = spillCalleeSavedRegs(MF); MachineFrameInfo &MFI = MF.getFrameInfo(); MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -331,7 +275,6 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { bool MadeChange = false; bool NewReservedRegs = false; - bool SpilledToVirtVGPRLanes = false; // TODO: CSR VGPRs will never be spilled to AGPRs. These can probably be // handled as SpilledToReg in regular PrologEpilogInserter. @@ -354,53 +297,23 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { int FI = TII->getNamedOperand(MI, AMDGPU::OpName::addr)->getIndex(); assert(MFI.getStackID(FI) == TargetStackID::SGPRSpill); - - bool IsCalleeSaveSGPRSpill = - std::find(CalleeSavedFIs.begin(), CalleeSavedFIs.end(), FI) != - CalleeSavedFIs.end(); - if (IsCalleeSaveSGPRSpill) { - // Spill callee-saved SGPRs into physical VGPR lanes. - - // TODO: This is to ensure the CFIs are static for efficient frame - // unwinding in the debugger. Spilling them into virtual VGPR lanes - // involve regalloc to allocate the physical VGPRs and that might - // cause intermediate spill/split of such liveranges for successful - // allocation. This would result in broken CFI encoding unless the - // regalloc aware CFI generation to insert new CFIs along with the - // intermediate spills is implemented. There is no such support - // currently exist in the LLVM compiler. - if (FuncInfo->allocateSGPRSpillToVGPRLane(MF, FI, true)) { - NewReservedRegs = true; - bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex( - MI, FI, nullptr, Indexes, LIS, true); - if (!Spilled) - llvm_unreachable( - "failed to spill SGPR to physical VGPR lane when allocated"); - } - } else { - if (FuncInfo->allocateSGPRSpillToVGPRLane(MF, FI)) { - bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex( - MI, FI, nullptr, Indexes, LIS); - if (!Spilled) - llvm_unreachable( - "failed to spill SGPR to virtual VGPR lane when allocated"); - SpillFIs.set(FI); - SpilledToVirtVGPRLanes = true; - } + if (FuncInfo->allocateSGPRSpillToVGPRLane(MF, FI)) { + NewReservedRegs = true; + bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex( + MI, FI, nullptr, Indexes, LIS); + (void)Spilled; + assert(Spilled && "failed to spill SGPR to VGPR when allocated"); + SpillFIs.set(FI); } } } - if (SpilledToVirtVGPRLanes) { - extendWWMVirtRegLiveness(MF, LIS); - if (LIS) { - // Compute the LiveInterval for the newly created virtual registers. - for (auto Reg : FuncInfo->getSGPRSpillVGPRs()) - LIS->createAndComputeVirtRegInterval(Reg); - } - } - + // FIXME: Adding to live-ins redundant with reserving registers. for (MachineBasicBlock &MBB : MF) { + for (auto Reg : FuncInfo->getSGPRSpillVGPRs()) + MBB.addLiveIn(Reg); + MBB.sortUniqueLiveIns(); + // FIXME: The dead frame indices are replaced with a null register from // the debug value instructions. We should instead, update it with the // correct register value. But not sure the register value alone is @@ -421,10 +334,6 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { // lane". FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ false); - MadeChange = true; - } - - if (SpilledToVirtVGPRLanes) { const TargetRegisterClass *RC = TRI->getWaveMaskRegClass(); // Shift back the reserved SGPR for EXEC copy into the lowest range. // This SGPR is reserved to handle the whole-wave spill/copy operations @@ -433,21 +342,20 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) { if (UnusedLowSGPR && TRI->getHWRegIndex(UnusedLowSGPR) < TRI->getHWRegIndex(FuncInfo->getSGPRForEXECCopy())) FuncInfo->setSGPRForEXECCopy(UnusedLowSGPR); + + MadeChange = true; } else { - // No SGPR spills to virtual VGPR lanes and hence there won't be any WWM - // spills/copies. Reset the SGPR reserved for EXEC copy. + // No SGPR spills and hence there won't be any WWM spills/copies. Reset the + // SGPR reserved for EXEC copy. FuncInfo->setSGPRForEXECCopy(AMDGPU::NoRegister); } SaveBlocks.clear(); RestoreBlocks.clear(); - // Updated the reserved registers with any physical VGPRs added for SGPR - // spills. - if (NewReservedRegs) { - for (Register Reg : FuncInfo->getWWMReservedRegs()) - MRI.reserveReg(Reg, TRI); - } + // Updated the reserved registers with any VGPRs added for SGPR spills. + if (NewReservedRegs) + MRI.freezeReservedRegs(MF); return MadeChange; } |
