blob: 7838a59b633827ac2c794ffb6115cfe500df3879 [file] [log] [blame]
Matt Arsenault5b0922f2019-07-03 23:32:29 +00001//===-- 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 "AMDGPUSubtarget.h"
20#include "SIInstrInfo.h"
21#include "SIMachineFunctionInfo.h"
22#include "llvm/CodeGen/LiveIntervals.h"
23#include "llvm/CodeGen/MachineBasicBlock.h"
24#include "llvm/CodeGen/MachineFunction.h"
25#include "llvm/CodeGen/MachineFunctionPass.h"
26#include "llvm/CodeGen/MachineInstr.h"
27#include "llvm/CodeGen/MachineInstrBuilder.h"
28#include "llvm/CodeGen/MachineOperand.h"
29#include "llvm/CodeGen/VirtRegMap.h"
30#include "llvm/Target/TargetMachine.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "si-lower-sgpr-spills"
35
36using MBBVector = SmallVector<MachineBasicBlock *, 4>;
37
38namespace {
39
40class SILowerSGPRSpills : public MachineFunctionPass {
41private:
42 const SIRegisterInfo *TRI = nullptr;
43 const SIInstrInfo *TII = nullptr;
44 VirtRegMap *VRM = nullptr;
45 LiveIntervals *LIS = nullptr;
46
47 // Save and Restore blocks of the current function. Typically there is a
48 // single save block, unless Windows EH funclets are involved.
49 MBBVector SaveBlocks;
50 MBBVector RestoreBlocks;
51
52public:
53 static char ID;
54
55 SILowerSGPRSpills() : MachineFunctionPass(ID) {}
56
57 void calculateSaveRestoreBlocks(MachineFunction &MF);
58 bool spillCalleeSavedRegs(MachineFunction &MF);
59
60 bool runOnMachineFunction(MachineFunction &MF) override;
61
62 void getAnalysisUsage(AnalysisUsage &AU) const override {
63 AU.setPreservesAll();
64 MachineFunctionPass::getAnalysisUsage(AU);
65 }
66};
67
68} // end anonymous namespace
69
70char SILowerSGPRSpills::ID = 0;
71
72INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE,
73 "SI lower SGPR spill instructions", false, false)
74INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
75INITIALIZE_PASS_END(SILowerSGPRSpills, DEBUG_TYPE,
76 "SI lower SGPR spill instructions", false, false)
77
78char &llvm::SILowerSGPRSpillsID = SILowerSGPRSpills::ID;
79
80/// Insert restore code for the callee-saved registers used in the function.
81static void insertCSRSaves(MachineBasicBlock &SaveBlock,
82 ArrayRef<CalleeSavedInfo> CSI,
83 LiveIntervals *LIS) {
84 MachineFunction &MF = *SaveBlock.getParent();
85 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
86 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
87 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
88
89 MachineBasicBlock::iterator I = SaveBlock.begin();
90 if (!TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI)) {
91 for (const CalleeSavedInfo &CS : CSI) {
92 // Insert the spill to the stack frame.
93 unsigned Reg = CS.getReg();
94
Michael Liao8d6ea2d2019-07-05 20:23:59 +000095 MachineInstrSpan MIS(I, &SaveBlock);
Matt Arsenault5b0922f2019-07-03 23:32:29 +000096 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
97
98 TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
99 TRI);
100
101 if (LIS) {
102 assert(std::distance(MIS.begin(), I) == 1);
103 MachineInstr &Inst = *std::prev(I);
104
105 LIS->InsertMachineInstrInMaps(Inst);
106 LIS->removeAllRegUnitsForPhysReg(Reg);
107 }
108 }
109 }
110}
111
112/// Insert restore code for the callee-saved registers used in the function.
113static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
114 std::vector<CalleeSavedInfo> &CSI,
115 LiveIntervals *LIS) {
116 MachineFunction &MF = *RestoreBlock.getParent();
117 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
118 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
119 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
120
121 // Restore all registers immediately before the return and any
122 // terminators that precede it.
123 MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator();
124
125 // FIXME: Just emit the readlane/writelane directly
126 if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
127 for (const CalleeSavedInfo &CI : reverse(CSI)) {
128 unsigned Reg = CI.getReg();
129 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
130
131 TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI);
132 assert(I != RestoreBlock.begin() &&
133 "loadRegFromStackSlot didn't insert any code!");
134 // Insert in reverse order. loadRegFromStackSlot can insert
135 // multiple instructions.
136
137 if (LIS) {
138 MachineInstr &Inst = *std::prev(I);
139 LIS->InsertMachineInstrInMaps(Inst);
140 LIS->removeAllRegUnitsForPhysReg(Reg);
141 }
142 }
143 }
144}
145
146/// Compute the sets of entry and return blocks for saving and restoring
147/// callee-saved registers, and placing prolog and epilog code.
148void SILowerSGPRSpills::calculateSaveRestoreBlocks(MachineFunction &MF) {
149 const MachineFrameInfo &MFI = MF.getFrameInfo();
150
151 // Even when we do not change any CSR, we still want to insert the
152 // prologue and epilogue of the function.
153 // So set the save points for those.
154
155 // Use the points found by shrink-wrapping, if any.
156 if (MFI.getSavePoint()) {
157 SaveBlocks.push_back(MFI.getSavePoint());
158 assert(MFI.getRestorePoint() && "Both restore and save must be set");
159 MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
160 // If RestoreBlock does not have any successor and is not a return block
161 // then the end point is unreachable and we do not need to insert any
162 // epilogue.
163 if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
164 RestoreBlocks.push_back(RestoreBlock);
165 return;
166 }
167
168 // Save refs to entry and return blocks.
169 SaveBlocks.push_back(&MF.front());
170 for (MachineBasicBlock &MBB : MF) {
171 if (MBB.isEHFuncletEntry())
172 SaveBlocks.push_back(&MBB);
173 if (MBB.isReturnBlock())
174 RestoreBlocks.push_back(&MBB);
175 }
176}
177
178bool SILowerSGPRSpills::spillCalleeSavedRegs(MachineFunction &MF) {
179 MachineRegisterInfo &MRI = MF.getRegInfo();
180 const Function &F = MF.getFunction();
181 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
182 const SIFrameLowering *TFI = ST.getFrameLowering();
183 MachineFrameInfo &MFI = MF.getFrameInfo();
184 RegScavenger *RS = nullptr;
185
186 // Determine which of the registers in the callee save list should be saved.
187 BitVector SavedRegs;
188 TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS);
189
190 // Add the code to save and restore the callee saved registers.
191 if (!F.hasFnAttribute(Attribute::Naked)) {
192 // FIXME: This is a lie. The CalleeSavedInfo is incomplete, but this is
193 // necessary for verifier liveness checks.
194 MFI.setCalleeSavedInfoValid(true);
195
196 std::vector<CalleeSavedInfo> CSI;
197 const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
198
199 for (unsigned I = 0; CSRegs[I]; ++I) {
200 unsigned Reg = CSRegs[I];
201 if (SavedRegs.test(Reg)) {
202 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
203 int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
204 TRI->getSpillAlignment(*RC),
205 true);
206
207 CSI.push_back(CalleeSavedInfo(Reg, JunkFI));
208 }
209 }
210
211 if (!CSI.empty()) {
212 for (MachineBasicBlock *SaveBlock : SaveBlocks)
213 insertCSRSaves(*SaveBlock, CSI, LIS);
214
215 for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
216 insertCSRRestores(*RestoreBlock, CSI, LIS);
217 return true;
218 }
219 }
220
221 return false;
222}
223
224bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) {
225 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
226 TII = ST.getInstrInfo();
227 TRI = &TII->getRegisterInfo();
228
229 VRM = getAnalysisIfAvailable<VirtRegMap>();
230
231 assert(SaveBlocks.empty() && RestoreBlocks.empty());
232
233 // First, expose any CSR SGPR spills. This is mostly the same as what PEI
234 // does, but somewhat simpler.
235 calculateSaveRestoreBlocks(MF);
236 bool HasCSRs = spillCalleeSavedRegs(MF);
237
238 MachineFrameInfo &MFI = MF.getFrameInfo();
239 if (!MFI.hasStackObjects() && !HasCSRs) {
240 SaveBlocks.clear();
241 RestoreBlocks.clear();
242 return false;
243 }
244
245 SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
246 bool MadeChange = false;
247
248 if (TRI->spillSGPRToVGPR() && (HasCSRs || FuncInfo->hasSpilledSGPRs())) {
249 // Process all SGPR spills before frame offsets are finalized. Ideally SGPRs
250 // are spilled to VGPRs, in which case we can eliminate the stack usage.
251 //
252 // This operates under the assumption that only other SGPR spills are users
253 // of the frame index.
254 for (MachineBasicBlock &MBB : MF) {
255 MachineBasicBlock::iterator Next;
256 for (auto I = MBB.begin(), E = MBB.end(); I != E; I = Next) {
257 MachineInstr &MI = *I;
258 Next = std::next(I);
259
260 if (!TII->isSGPRSpill(MI))
261 continue;
262
263 int FI = TII->getNamedOperand(MI, AMDGPU::OpName::addr)->getIndex();
264 assert(MFI.getStackID(FI) == TargetStackID::SGPRSpill);
265 if (FuncInfo->allocateSGPRSpillToVGPR(MF, FI)) {
266 bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex(MI, FI, nullptr);
267 (void)Spilled;
268 assert(Spilled && "failed to spill SGPR to VGPR when allocated");
269 }
270
271 }
272 }
273
274 for (MachineBasicBlock &MBB : MF) {
275 for (auto SSpill : FuncInfo->getSGPRSpillVGPRs())
276 MBB.addLiveIn(SSpill.VGPR);
277 MBB.sortUniqueLiveIns();
278 }
279
280 FuncInfo->removeSGPRToVGPRFrameIndices(MFI);
281 MadeChange = true;
282 }
283
284 SaveBlocks.clear();
285 RestoreBlocks.clear();
286
287 return MadeChange;
288}