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