summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp136
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;
}