1 //===-- SILowerSGPRSPills.cpp ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Handle SGPR spills. This pass takes the place of PrologEpilogInserter for all
10 // SGPR spills, so must insert CSR SGPR spills as well as expand them.
11 //
12 // This pass must never create new SGPR virtual registers.
13 //
14 // FIXME: Must stop RegScavenger spills in later passes.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #include "AMDGPU.h"
19 #include "GCNSubtarget.h"
20 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
21 #include "SIMachineFunctionInfo.h"
22 #include "llvm/CodeGen/LiveIntervals.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/InitializePasses.h"
26
27 using namespace llvm;
28
29 #define DEBUG_TYPE "si-lower-sgpr-spills"
30
31 using MBBVector = SmallVector<MachineBasicBlock *, 4>;
32
33 namespace {
34
35 class SILowerSGPRSpills : public MachineFunctionPass {
36 private:
37 const SIRegisterInfo *TRI = nullptr;
38 const SIInstrInfo *TII = nullptr;
39 LiveIntervals *LIS = nullptr;
40
41 // Save and Restore blocks of the current function. Typically there is a
42 // single save block, unless Windows EH funclets are involved.
43 MBBVector SaveBlocks;
44 MBBVector RestoreBlocks;
45
46 public:
47 static char ID;
48
SILowerSGPRSpills()49 SILowerSGPRSpills() : MachineFunctionPass(ID) {}
50
51 void calculateSaveRestoreBlocks(MachineFunction &MF);
52 bool spillCalleeSavedRegs(MachineFunction &MF);
53
54 bool runOnMachineFunction(MachineFunction &MF) override;
55
getAnalysisUsage(AnalysisUsage & AU) const56 void getAnalysisUsage(AnalysisUsage &AU) const override {
57 AU.setPreservesAll();
58 MachineFunctionPass::getAnalysisUsage(AU);
59 }
60 };
61
62 } // end anonymous namespace
63
64 char SILowerSGPRSpills::ID = 0;
65
66 INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE,
67 "SI lower SGPR spill instructions", false, false)
68 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
69 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
70 INITIALIZE_PASS_END(SILowerSGPRSpills, DEBUG_TYPE,
71 "SI lower SGPR spill instructions", false, false)
72
73 char &llvm::SILowerSGPRSpillsID = SILowerSGPRSpills::ID;
74
75 /// Insert spill code for the callee-saved registers used in the function.
insertCSRSaves(MachineBasicBlock & SaveBlock,ArrayRef<CalleeSavedInfo> CSI,LiveIntervals * LIS)76 static void insertCSRSaves(MachineBasicBlock &SaveBlock,
77 ArrayRef<CalleeSavedInfo> CSI,
78 LiveIntervals *LIS) {
79 MachineFunction &MF = *SaveBlock.getParent();
80 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
81 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
82 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
83 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
84 const SIRegisterInfo *RI = ST.getRegisterInfo();
85
86 MachineBasicBlock::iterator I = SaveBlock.begin();
87 if (!TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI)) {
88 const MachineRegisterInfo &MRI = MF.getRegInfo();
89
90 for (const CalleeSavedInfo &CS : CSI) {
91 // Insert the spill to the stack frame.
92 MCRegister Reg = CS.getReg();
93
94 MachineInstrSpan MIS(I, &SaveBlock);
95 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(
96 Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
97
98 // If this value was already livein, we probably have a direct use of the
99 // incoming register value, so don't kill at the spill point. This happens
100 // since we pass some special inputs (workgroup IDs) in the callee saved
101 // range.
102 const bool IsLiveIn = MRI.isLiveIn(Reg);
103 TII.storeRegToStackSlot(SaveBlock, I, Reg, !IsLiveIn, CS.getFrameIdx(),
104 RC, TRI);
105
106 if (LIS) {
107 assert(std::distance(MIS.begin(), I) == 1);
108 MachineInstr &Inst = *std::prev(I);
109
110 LIS->InsertMachineInstrInMaps(Inst);
111 LIS->removeAllRegUnitsForPhysReg(Reg);
112 }
113 }
114 }
115 }
116
117 /// Insert restore code for the callee-saved registers used in the function.
insertCSRRestores(MachineBasicBlock & RestoreBlock,MutableArrayRef<CalleeSavedInfo> CSI,LiveIntervals * LIS)118 static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
119 MutableArrayRef<CalleeSavedInfo> CSI,
120 LiveIntervals *LIS) {
121 MachineFunction &MF = *RestoreBlock.getParent();
122 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
123 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
124 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
125 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
126 const SIRegisterInfo *RI = ST.getRegisterInfo();
127 // Restore all registers immediately before the return and any
128 // terminators that precede it.
129 MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator();
130
131 // FIXME: Just emit the readlane/writelane directly
132 if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
133 for (const CalleeSavedInfo &CI : reverse(CSI)) {
134 Register Reg = CI.getReg();
135 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(
136 Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
137
138 TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI);
139 assert(I != RestoreBlock.begin() &&
140 "loadRegFromStackSlot didn't insert any code!");
141 // Insert in reverse order. loadRegFromStackSlot can insert
142 // multiple instructions.
143
144 if (LIS) {
145 MachineInstr &Inst = *std::prev(I);
146 LIS->InsertMachineInstrInMaps(Inst);
147 LIS->removeAllRegUnitsForPhysReg(Reg);
148 }
149 }
150 }
151 }
152
153 /// Compute the sets of entry and return blocks for saving and restoring
154 /// callee-saved registers, and placing prolog and epilog code.
calculateSaveRestoreBlocks(MachineFunction & MF)155 void SILowerSGPRSpills::calculateSaveRestoreBlocks(MachineFunction &MF) {
156 const MachineFrameInfo &MFI = MF.getFrameInfo();
157
158 // Even when we do not change any CSR, we still want to insert the
159 // prologue and epilogue of the function.
160 // So set the save points for those.
161
162 // Use the points found by shrink-wrapping, if any.
163 if (MFI.getSavePoint()) {
164 SaveBlocks.push_back(MFI.getSavePoint());
165 assert(MFI.getRestorePoint() && "Both restore and save must be set");
166 MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
167 // If RestoreBlock does not have any successor and is not a return block
168 // then the end point is unreachable and we do not need to insert any
169 // epilogue.
170 if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
171 RestoreBlocks.push_back(RestoreBlock);
172 return;
173 }
174
175 // Save refs to entry and return blocks.
176 SaveBlocks.push_back(&MF.front());
177 for (MachineBasicBlock &MBB : MF) {
178 if (MBB.isEHFuncletEntry())
179 SaveBlocks.push_back(&MBB);
180 if (MBB.isReturnBlock())
181 RestoreBlocks.push_back(&MBB);
182 }
183 }
184
185 // TODO: To support shrink wrapping, this would need to copy
186 // PrologEpilogInserter's updateLiveness.
updateLiveness(MachineFunction & MF,ArrayRef<CalleeSavedInfo> CSI)187 static void updateLiveness(MachineFunction &MF, ArrayRef<CalleeSavedInfo> CSI) {
188 MachineBasicBlock &EntryBB = MF.front();
189
190 for (const CalleeSavedInfo &CSIReg : CSI)
191 EntryBB.addLiveIn(CSIReg.getReg());
192 EntryBB.sortUniqueLiveIns();
193 }
194
spillCalleeSavedRegs(MachineFunction & MF)195 bool SILowerSGPRSpills::spillCalleeSavedRegs(MachineFunction &MF) {
196 MachineRegisterInfo &MRI = MF.getRegInfo();
197 const Function &F = MF.getFunction();
198 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
199 const SIFrameLowering *TFI = ST.getFrameLowering();
200 MachineFrameInfo &MFI = MF.getFrameInfo();
201 RegScavenger *RS = nullptr;
202
203 // Determine which of the registers in the callee save list should be saved.
204 BitVector SavedRegs;
205 TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS);
206
207 // Add the code to save and restore the callee saved registers.
208 if (!F.hasFnAttribute(Attribute::Naked)) {
209 // FIXME: This is a lie. The CalleeSavedInfo is incomplete, but this is
210 // necessary for verifier liveness checks.
211 MFI.setCalleeSavedInfoValid(true);
212
213 std::vector<CalleeSavedInfo> CSI;
214 const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
215
216 for (unsigned I = 0; CSRegs[I]; ++I) {
217 MCRegister Reg = CSRegs[I];
218
219 if (SavedRegs.test(Reg)) {
220 const TargetRegisterClass *RC =
221 TRI->getMinimalPhysRegClass(Reg, MVT::i32);
222 int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
223 TRI->getSpillAlign(*RC), true);
224
225 CSI.push_back(CalleeSavedInfo(Reg, JunkFI));
226 }
227 }
228
229 if (!CSI.empty()) {
230 for (MachineBasicBlock *SaveBlock : SaveBlocks)
231 insertCSRSaves(*SaveBlock, CSI, LIS);
232
233 // Add live ins to save blocks.
234 assert(SaveBlocks.size() == 1 && "shrink wrapping not fully implemented");
235 updateLiveness(MF, CSI);
236
237 for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
238 insertCSRRestores(*RestoreBlock, CSI, LIS);
239 return true;
240 }
241 }
242
243 return false;
244 }
245
runOnMachineFunction(MachineFunction & MF)246 bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) {
247 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
248 TII = ST.getInstrInfo();
249 TRI = &TII->getRegisterInfo();
250
251 LIS = getAnalysisIfAvailable<LiveIntervals>();
252
253 assert(SaveBlocks.empty() && RestoreBlocks.empty());
254
255 // First, expose any CSR SGPR spills. This is mostly the same as what PEI
256 // does, but somewhat simpler.
257 calculateSaveRestoreBlocks(MF);
258 bool HasCSRs = spillCalleeSavedRegs(MF);
259
260 MachineFrameInfo &MFI = MF.getFrameInfo();
261 MachineRegisterInfo &MRI = MF.getRegInfo();
262 SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
263
264 if (!MFI.hasStackObjects() && !HasCSRs) {
265 SaveBlocks.clear();
266 RestoreBlocks.clear();
267 return false;
268 }
269
270 bool MadeChange = false;
271 bool NewReservedRegs = false;
272
273 // TODO: CSR VGPRs will never be spilled to AGPRs. These can probably be
274 // handled as SpilledToReg in regular PrologEpilogInserter.
275 const bool HasSGPRSpillToVGPR = TRI->spillSGPRToVGPR() &&
276 (HasCSRs || FuncInfo->hasSpilledSGPRs());
277 if (HasSGPRSpillToVGPR) {
278 // Process all SGPR spills before frame offsets are finalized. Ideally SGPRs
279 // are spilled to VGPRs, in which case we can eliminate the stack usage.
280 //
281 // This operates under the assumption that only other SGPR spills are users
282 // of the frame index.
283
284 // To track the spill frame indices handled in this pass.
285 BitVector SpillFIs(MFI.getObjectIndexEnd(), false);
286
287 for (MachineBasicBlock &MBB : MF) {
288 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
289 if (!TII->isSGPRSpill(MI))
290 continue;
291
292 int FI = TII->getNamedOperand(MI, AMDGPU::OpName::addr)->getIndex();
293 assert(MFI.getStackID(FI) == TargetStackID::SGPRSpill);
294 if (FuncInfo->allocateSGPRSpillToVGPR(MF, FI)) {
295 NewReservedRegs = true;
296 bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex(MI, FI,
297 nullptr, LIS);
298 (void)Spilled;
299 assert(Spilled && "failed to spill SGPR to VGPR when allocated");
300 SpillFIs.set(FI);
301 }
302 }
303 }
304
305 // FIXME: Adding to live-ins redundant with reserving registers.
306 for (MachineBasicBlock &MBB : MF) {
307 for (auto SSpill : FuncInfo->getSGPRSpillVGPRs())
308 MBB.addLiveIn(SSpill.VGPR);
309 MBB.sortUniqueLiveIns();
310
311 // FIXME: The dead frame indices are replaced with a null register from
312 // the debug value instructions. We should instead, update it with the
313 // correct register value. But not sure the register value alone is
314 // adequate to lower the DIExpression. It should be worked out later.
315 for (MachineInstr &MI : MBB) {
316 if (MI.isDebugValue() && MI.getOperand(0).isFI() &&
317 SpillFIs[MI.getOperand(0).getIndex()]) {
318 MI.getOperand(0).ChangeToRegister(Register(), false /*isDef*/);
319 }
320 }
321 }
322
323 // All those frame indices which are dead by now should be removed from the
324 // function frame. Otherwise, there is a side effect such as re-mapping of
325 // free frame index ids by the later pass(es) like "stack slot coloring"
326 // which in turn could mess-up with the book keeping of "frame index to VGPR
327 // lane".
328 FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ false);
329
330 MadeChange = true;
331 }
332
333 SaveBlocks.clear();
334 RestoreBlocks.clear();
335
336 // Updated the reserved registers with any VGPRs added for SGPR spills.
337 if (NewReservedRegs)
338 MRI.freezeReservedRegs(MF);
339
340 return MadeChange;
341 }
342