LLVM 24.0.0git
SILowerSGPRSpills.cpp
Go to the documentation of this file.
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 "SILowerSGPRSpills.h"
19#include "AMDGPU.h"
20#include "GCNSubtarget.h"
23#include "SISpillUtils.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "si-lower-sgpr-spills"
34
36
37namespace {
38
39/// Insertion point for IMPLICIT_DEF: iterator may be MBB::end() and can't be
40/// dereferenced so the parent block is stored explicitly.
41struct LaneVGPRInsertPt {
44};
45
46static LaneVGPRInsertPt insertPt(MachineBasicBlock *MBB,
48 return {MBB, It};
49}
50
51static cl::opt<unsigned> MaxNumVGPRsForWwmAllocation(
52 "amdgpu-num-vgprs-for-wwm-alloc",
53 cl::desc("Max num VGPRs for whole-wave register allocation."),
55
56class SILowerSGPRSpills {
57private:
58 const SIRegisterInfo *TRI = nullptr;
59 const SIInstrInfo *TII = nullptr;
60 LiveIntervals *LIS = nullptr;
61 SlotIndexes *Indexes = nullptr;
62 MachineDominatorTree *MDT = nullptr;
63 MachineCycleInfo *MCI = nullptr;
64
65 // Save and Restore blocks of the current function. Typically there is a
66 // single save block, unless Windows EH funclets are involved.
67 MBBVector SaveBlocks;
68 MBBVector RestoreBlocks;
69
70 MachineBasicBlock *getCycleDomBB(CycleRef C);
71
72public:
73 SILowerSGPRSpills(LiveIntervals *LIS, SlotIndexes *Indexes,
75 : LIS(LIS), Indexes(Indexes), MDT(MDT), MCI(MCI) {}
76 bool run(MachineFunction &MF);
77 void calculateSaveRestoreBlocks(MachineFunction &MF);
78 bool spillCalleeSavedRegs(MachineFunction &MF,
79 SmallVectorImpl<int> &CalleeSavedFIs);
80 void updateLaneVGPRDomInstr(
82 DenseMap<Register, LaneVGPRInsertPt> &LaneVGPRDomInstr);
83 SmallVector<MCRegister> determineRegsForWWMAllocation(MachineFunction &MF);
84 void assignWWMRegs(MachineFunction &MF, ArrayRef<MCRegister> WWMRegCandidates,
85 bool RequiresFullWWMPool);
86};
87
88class SILowerSGPRSpillsLegacy : public MachineFunctionPass {
89public:
90 static char ID;
91
92 SILowerSGPRSpillsLegacy() : MachineFunctionPass(ID) {}
93
94 bool runOnMachineFunction(MachineFunction &MF) override;
95
96 void getAnalysisUsage(AnalysisUsage &AU) const override {
99 AU.setPreservesAll();
101 }
102
103 MachineFunctionProperties getClearedProperties() const override {
104 // SILowerSGPRSpills introduces new Virtual VGPRs for spilling SGPRs.
105 return MachineFunctionProperties().setIsSSA().setNoVRegs();
106 }
107};
108
109} // end anonymous namespace
110
111char SILowerSGPRSpillsLegacy::ID = 0;
112
113INITIALIZE_PASS_BEGIN(SILowerSGPRSpillsLegacy, DEBUG_TYPE,
114 "SI lower SGPR spill instructions", false, false)
119INITIALIZE_PASS_END(SILowerSGPRSpillsLegacy, DEBUG_TYPE,
120 "SI lower SGPR spill instructions", false, false)
121
122char &llvm::SILowerSGPRSpillsLegacyID = SILowerSGPRSpillsLegacy::ID;
123
124/// Insert spill code for the callee-saved registers used in the function.
126 ArrayRef<CalleeSavedInfo> CSI, SlotIndexes *Indexes,
127 LiveIntervals *LIS) {
128 const TargetFrameLowering *TFI = ST.getFrameLowering();
129 const TargetRegisterInfo *TRI = ST.getRegisterInfo();
130 MachineBasicBlock::iterator I = SaveBlock.begin();
131 MachineInstrSpan MIS(I, &SaveBlock);
132 bool Success = TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI);
133 assert(Success && "spillCalleeSavedRegisters should always succeed");
134 (void)Success;
135
136 // TFI doesn't update Indexes and LIS, so we have to do it separately.
137 if (Indexes)
138 Indexes->repairIndexesInRange(&SaveBlock, SaveBlock.begin(), I);
139
140 if (LIS)
141 for (const CalleeSavedInfo &CS : CSI)
142 LIS->removeAllRegUnitsForPhysReg(CS.getReg());
143}
144
145/// Insert restore code for the callee-saved registers used in the function.
146static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
148 SlotIndexes *Indexes, LiveIntervals *LIS) {
149 MachineFunction &MF = *RestoreBlock.getParent();
153 // Restore all registers immediately before the return and any
154 // terminators that precede it.
156 const MachineBasicBlock::iterator BeforeRestoresI =
157 I == RestoreBlock.begin() ? I : std::prev(I);
158
159 // FIXME: Just emit the readlane/writelane directly
160 if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
161 for (const CalleeSavedInfo &CI : reverse(CSI)) {
162 // Insert in reverse order. loadRegFromStackSlot can insert
163 // multiple instructions.
164 TFI->restoreCalleeSavedRegister(RestoreBlock, I, CI, &TII, TRI);
165
166 if (Indexes) {
167 MachineInstr &Inst = *std::prev(I);
168 Indexes->insertMachineInstrInMaps(Inst);
169 }
170
171 if (LIS)
172 LIS->removeAllRegUnitsForPhysReg(CI.getReg());
173 }
174 } else {
175 // TFI doesn't update Indexes and LIS, so we have to do it separately.
176 if (Indexes)
177 Indexes->repairIndexesInRange(&RestoreBlock, BeforeRestoresI,
178 RestoreBlock.getFirstTerminator());
179
180 if (LIS)
181 for (const CalleeSavedInfo &CS : CSI)
182 LIS->removeAllRegUnitsForPhysReg(CS.getReg());
183 }
184}
185
186/// Compute the sets of entry and return blocks for saving and restoring
187/// callee-saved registers, and placing prolog and epilog code.
188void SILowerSGPRSpills::calculateSaveRestoreBlocks(MachineFunction &MF) {
189 const MachineFrameInfo &MFI = MF.getFrameInfo();
190
191 // Even when we do not change any CSR, we still want to insert the
192 // prologue and epilogue of the function.
193 // So set the save points for those.
194
195 // Use the points found by shrink-wrapping, if any.
196 if (!MFI.getSavePoints().empty()) {
197 assert(MFI.getSavePoints().size() == 1 &&
198 "Multiple save points not yet supported!");
199 const auto &SavePoint = *MFI.getSavePoints().begin();
200 SaveBlocks.push_back(SavePoint.first);
201 assert(MFI.getRestorePoints().size() == 1 &&
202 "Multiple restore points not yet supported!");
203 const auto &RestorePoint = *MFI.getRestorePoints().begin();
204 MachineBasicBlock *RestoreBlock = RestorePoint.first;
205 // If RestoreBlock does not have any successor and is not a return block
206 // then the end point is unreachable and we do not need to insert any
207 // epilogue.
208 if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
209 RestoreBlocks.push_back(RestoreBlock);
210 return;
211 }
212
213 // Save refs to entry and return blocks.
214 SaveBlocks.push_back(&MF.front());
215 for (MachineBasicBlock &MBB : MF) {
216 if (MBB.isEHFuncletEntry())
217 SaveBlocks.push_back(&MBB);
218 if (MBB.isReturnBlock())
219 RestoreBlocks.push_back(&MBB);
220 }
221}
222
223// TODO: To support shrink wrapping, this would need to copy
224// PrologEpilogInserter's updateLiveness.
226 MachineBasicBlock &EntryBB = MF.front();
227
228 for (const CalleeSavedInfo &CSIReg : CSI)
229 EntryBB.addLiveIn(CSIReg.getReg());
230 EntryBB.sortUniqueLiveIns();
231}
232
233bool SILowerSGPRSpills::spillCalleeSavedRegs(
234 MachineFunction &MF, SmallVectorImpl<int> &CalleeSavedFIs) {
235 MachineRegisterInfo &MRI = MF.getRegInfo();
236 const Function &F = MF.getFunction();
237 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
238 const SIFrameLowering *TFI = ST.getFrameLowering();
239 MachineFrameInfo &MFI = MF.getFrameInfo();
240 RegScavenger *RS = nullptr;
241
242 // Determine which of the registers in the callee save list should be saved.
243 BitVector SavedRegs;
244 TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS);
245
246 // Add the code to save and restore the callee saved registers.
247 if (!F.hasFnAttribute(Attribute::Naked)) {
248 // FIXME: This is a lie. The CalleeSavedInfo is incomplete, but this is
249 // necessary for verifier liveness checks.
250 MFI.setCalleeSavedInfoValid(true);
251
252 std::vector<CalleeSavedInfo> CSI;
253 const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
254 MCRegister RetAddrReg = TRI->getReturnAddressReg(MF);
255 MCRegister RetAddrRegSub0 = TRI->getSubReg(RetAddrReg, AMDGPU::sub0);
256 MCRegister RetAddrRegSub1 = TRI->getSubReg(RetAddrReg, AMDGPU::sub1);
257 bool SpillRetAddrReg = false;
258
259 for (unsigned I = 0; CSRegs[I]; ++I) {
260 MCRegister Reg = CSRegs[I];
261
262 if (SavedRegs.test(Reg)) {
263 if (Reg == RetAddrRegSub0 || Reg == RetAddrRegSub1) {
264 SpillRetAddrReg = true;
265 continue;
266 }
267
268 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
269 int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
270 TRI->getSpillAlign(*RC), true,
271 nullptr, TRI->getSpillStackID(*RC));
272
273 CSI.emplace_back(Reg, JunkFI);
274 CalleeSavedFIs.push_back(JunkFI);
275 }
276 }
277
278 // Return address uses a register pair. Add the super register to the
279 // CSI list so that it's easier to identify the entire spill and CFI
280 // can be emitted appropriately.
281 if (SpillRetAddrReg) {
282 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(RetAddrReg);
283 int JunkFI =
284 MFI.CreateStackObject(TRI->getSpillSize(*RC), TRI->getSpillAlign(*RC),
285 true, nullptr, TRI->getSpillStackID(*RC));
286 CSI.push_back(CalleeSavedInfo(RetAddrReg, JunkFI));
287 CalleeSavedFIs.push_back(JunkFI);
288 }
289
290 if (!CSI.empty()) {
291 for (MachineBasicBlock *SaveBlock : SaveBlocks)
292 insertCSRSaves(ST, *SaveBlock, CSI, Indexes, LIS);
293
294 // Add live ins to save blocks.
295 assert(SaveBlocks.size() == 1 && "shrink wrapping not fully implemented");
296 updateLiveness(MF, CSI);
297
298 for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
299 insertCSRRestores(*RestoreBlock, CSI, Indexes, LIS);
300 return true;
301 }
302 }
303
304 return false;
305}
306
307MachineBasicBlock *SILowerSGPRSpills::getCycleDomBB(CycleRef C) {
308 // If the insertion point lands on a cycle entry, move it to a block that
309 // dominates all entries.
310 if (MCI->isReducible(C)) {
311 if (auto *IDom = MDT->getNode(MCI->getHeader(C))->getIDom())
312 return IDom->getBlock();
313 llvm_unreachable("Expected cycle to have an IDom.");
314 return nullptr;
315 }
316
318 assert(!Entries.empty() && "Expected cycle to have at least one entry.");
319 MachineBasicBlock *EntryBB = Entries[0];
320 for (unsigned I = 1; I < Entries.size(); ++I)
321 EntryBB = MDT->findNearestCommonDominator(EntryBB, Entries[I]);
322 return EntryBB;
323}
324
325void SILowerSGPRSpills::updateLaneVGPRDomInstr(
326 int FI, MachineBasicBlock *MBB, MachineBasicBlock::iterator InsertPt,
327 DenseMap<Register, LaneVGPRInsertPt> &LaneVGPRDomInstr) {
328 // For the Def of a virtual LaneVGPR to dominate all its uses, we should
329 // insert an IMPLICIT_DEF before the dominating spill. Switching to a
330 // depth first order doesn't really help since the machine function can be in
331 // the unstructured control flow post-SSA. For each virtual register, hence
332 // finding the common dominator to get either the dominating spill or a block
333 // dominating all spills.
334 SIMachineFunctionInfo *FuncInfo =
335 MBB->getParent()->getInfo<SIMachineFunctionInfo>();
337 FuncInfo->getSGPRSpillToVirtualVGPRLanes(FI);
338 Register PrevLaneVGPR;
339 for (auto &Spill : VGPRSpills) {
340 if (PrevLaneVGPR == Spill.VGPR)
341 continue;
342
343 PrevLaneVGPR = Spill.VGPR;
344 auto I = LaneVGPRDomInstr.find(Spill.VGPR);
345 if (Spill.Lane == 0 && I == LaneVGPRDomInstr.end()) {
346 LaneVGPRDomInstr[Spill.VGPR] = insertPt(MBB, InsertPt);
347 } else {
348 assert(I != LaneVGPRDomInstr.end());
349 LaneVGPRInsertPt Prev = I->second;
350 MachineBasicBlock *PrevInsertMBB = Prev.MBB;
351 MachineBasicBlock::iterator PrevInsertPt = Prev.It;
352 MachineBasicBlock *DomMBB = PrevInsertMBB;
353 if (DomMBB == MBB) {
354 // The insertion point earlier selected in a predecessor block whose
355 // spills are currently being lowered. The earlier InsertPt would be
356 // the one just before the block terminator and it should be changed
357 // if we insert any new spill in it.
358 if (PrevInsertPt == MBB->end() ||
359 MDT->dominates(&*InsertPt, &*PrevInsertPt))
360 I->second = insertPt(MBB, InsertPt);
361
362 continue;
363 }
364
365 // Find the common dominator block between PrevInsertPt and the
366 // current spill.
367 DomMBB = MDT->findNearestCommonDominator(DomMBB, MBB);
368
369 if (DomMBB == MBB)
370 I->second = insertPt(MBB, InsertPt);
371 else if (DomMBB != PrevInsertMBB)
372 I->second = insertPt(DomMBB, DomMBB->getFirstTerminator());
373 }
374 }
375}
376
378SILowerSGPRSpills::determineRegsForWWMAllocation(MachineFunction &MF) {
379 SmallVector<MCRegister> WWMRegCandidates;
380 if (!MaxNumVGPRsForWwmAllocation)
381 return WWMRegCandidates;
382
383 MachineRegisterInfo &MRI = MF.getRegInfo();
384 BitVector ReservedRegs = TRI->getReservedRegs(MF);
385 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
386 unsigned MaxNumVGPRs = ST.getMaxNumVectorRegs(MF.getFunction()).first;
387
388 // Try to use the highest available registers for now. Later after
389 // vgpr-regalloc, they can be shifted to the lowest range.
390 for (unsigned Reg = AMDGPU::VGPR0 + MaxNumVGPRs - 1;
391 WWMRegCandidates.size() < MaxNumVGPRsForWwmAllocation &&
392 Reg >= AMDGPU::VGPR0;
393 --Reg) {
394 if (!ReservedRegs.test(Reg) &&
395 !MRI.isPhysRegUsed(Reg, /*SkipRegMaskTest=*/true))
396 WWMRegCandidates.push_back(Reg);
397 }
398
399 return WWMRegCandidates;
400}
401
402void SILowerSGPRSpills::assignWWMRegs(MachineFunction &MF,
403 ArrayRef<MCRegister> WWMRegCandidates,
404 bool RequiresFullWWMPool) {
405 SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
406 if (FuncInfo->getSGPRSpillVGPRs().empty())
407 return;
408
409 BitVector WwmRegMask(TRI->getNumRegs());
410
411 unsigned DesiredPoolSize =
412 std::min(static_cast<unsigned>(FuncInfo->getSGPRSpillVGPRs().size()),
413 static_cast<unsigned>(MaxNumVGPRsForWwmAllocation));
414 unsigned SelectedPoolSize =
415 std::min<unsigned>(DesiredPoolSize, WWMRegCandidates.size());
416 // WWM register candidates are ordered high-to-low, so take the highest
417 // available registers when the desired pool is smaller than the candidate
418 // list.
419 for (MCRegister Reg : WWMRegCandidates.take_front(SelectedPoolSize))
420 TRI->markSuperRegs(WwmRegMask, Reg);
421
422 if (RequiresFullWWMPool && SelectedPoolSize != DesiredPoolSize) {
423 // Reserve an arbitrary register and report the error.
424 TRI->markSuperRegs(WwmRegMask, AMDGPU::VGPR0);
426 "cannot find enough VGPRs for wwm-regalloc");
427 }
428
429 BitVector PerLaneVGPRMask(WwmRegMask);
430 PerLaneVGPRMask.flip().clearBitsNotInMask(TRI->getAllVGPRRegMask());
431
432 // The complement set will be the registers for per-lane VGPR allocation.
433 FuncInfo->updatePerLaneVGPRMask(PerLaneVGPRMask);
434}
435
436bool SILowerSGPRSpillsLegacy::runOnMachineFunction(MachineFunction &MF) {
437 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
438 LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
439 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
440 SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
441 MachineDominatorTree *MDT =
442 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
443 MachineCycleInfo *MCI =
444 &getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
445 return SILowerSGPRSpills(LIS, Indexes, MDT, MCI).run(MF);
446}
447
448bool SILowerSGPRSpills::run(MachineFunction &MF) {
449 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
450 TII = ST.getInstrInfo();
451 TRI = &TII->getRegisterInfo();
452
453 assert(SaveBlocks.empty() && RestoreBlocks.empty());
454
455 // First, expose any CSR SGPR spills. This is mostly the same as what PEI
456 // does, but somewhat simpler.
457 calculateSaveRestoreBlocks(MF);
458 SmallVector<int> CalleeSavedFIs;
459 bool HasCSRs = spillCalleeSavedRegs(MF, CalleeSavedFIs);
460
461 MachineFrameInfo &MFI = MF.getFrameInfo();
462 MachineRegisterInfo &MRI = MF.getRegInfo();
463 SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
464
465 if (!MFI.hasStackObjects() && !HasCSRs) {
466 SaveBlocks.clear();
467 RestoreBlocks.clear();
468 return false;
469 }
470
471 bool MadeChange = false;
472 bool SpilledToVirtVGPRLanes = false;
473
474 // TODO: CSR VGPRs will never be spilled to AGPRs. These can probably be
475 // handled as SpilledToReg in regular PrologEpilogInserter.
476 const bool HasSGPRSpillToVGPR = TRI->spillSGPRToVGPR() &&
477 (HasCSRs || FuncInfo->hasSpilledSGPRs());
478 if (HasSGPRSpillToVGPR) {
479 // Process all SGPR spills before frame offsets are finalized. Ideally SGPRs
480 // are spilled to VGPRs, in which case we can eliminate the stack usage.
481 //
482 // This operates under the assumption that only other SGPR spills are users
483 // of the frame index.
484
485 // To track the spill frame indices handled in this pass.
486 BitVector SpillFIs(MFI.getObjectIndexEnd(), false);
487
488 // To track the IMPLICIT_DEF insertion point for the lane vgprs.
489 DenseMap<Register, LaneVGPRInsertPt> LaneVGPRDomInstr;
490
491 // Defer ordinary spills until physical CSR spills have reserved their
492 // lane VGPRs and the WWM allocation pool can be selected.
493 SmallVector<MachineInstr *> OrdinarySGPRSpills;
494 bool HasStrictWWMRegion = false;
495
496 for (MachineBasicBlock &MBB : MF) {
497 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
498 if (MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
499 MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM) {
500 HasStrictWWMRegion = true;
501 continue;
502 }
503
504 if (!TII->isSGPRSpill(MI))
505 continue;
506
507 if (MI.getOperand(0).isUndef()) {
508 if (Indexes)
510 MI.eraseFromParent();
511 continue;
512 }
513
514 int FI = TII->getNamedOperand(MI, AMDGPU::OpName::addr)->getIndex();
516
517 bool IsCalleeSaveSGPRSpill = llvm::is_contained(CalleeSavedFIs, FI);
518 if (IsCalleeSaveSGPRSpill) {
519 // Spill callee-saved SGPRs into physical VGPR lanes.
520
521 // TODO: This is to ensure the CFIs are static for efficient frame
522 // unwinding in the debugger. Spilling them into virtual VGPR lanes
523 // involve regalloc to allocate the physical VGPRs and that might
524 // cause intermediate spill/split of such liveranges for successful
525 // allocation. This would result in broken CFI encoding unless the
526 // regalloc aware CFI generation to insert new CFIs along with the
527 // intermediate spills is implemented. There is no such support
528 // currently exist in the LLVM compiler.
529 if (FuncInfo->allocateSGPRSpillToVGPRLane(
530 MF, FI, /*SpillToPhysVGPRLane=*/true)) {
531 bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex(
532 MI, FI, nullptr, Indexes, LIS, true);
533 if (!Spilled)
535 "failed to spill SGPR to physical VGPR lane when allocated");
536 }
537 } else
538 OrdinarySGPRSpills.push_back(&MI);
539 }
540 }
541
542 // Select candidates once, before ordinary lane lowering creates virtual
543 // VGPRs and changes the number of registers desired for the WWM pool.
544 SmallVector<MCRegister> WWMRegCandidates;
545 // These non-spillable WWM users retain the old all-or-nothing pool policy.
546 const bool RequiresFullWWMPool =
547 HasStrictWWMRegion || isPreallocateSGPRSpillVGPRsEnabled(MF);
548 if (!OrdinarySGPRSpills.empty())
549 WWMRegCandidates = determineRegsForWWMAllocation(MF);
550
551 const bool ShouldLowerOrdinarySpillsToVGPRLanes =
552 RequiresFullWWMPool || !WWMRegCandidates.empty();
553 if (!ShouldLowerOrdinarySpillsToVGPRLanes && !OrdinarySGPRSpills.empty())
555
556 if (ShouldLowerOrdinarySpillsToVGPRLanes) {
557 for (MachineInstr *MI : OrdinarySGPRSpills) {
558 int FI = TII->getNamedOperand(*MI, AMDGPU::OpName::addr)->getIndex();
559 if (FuncInfo->allocateSGPRSpillToVGPRLane(MF, FI)) {
560 MachineBasicBlock *MBB = MI->getParent();
561 MachineInstrSpan MIS(MI, MBB);
562 bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex(
563 *MI, FI, nullptr, Indexes, LIS);
564 if (!Spilled)
566 "failed to spill SGPR to virtual VGPR lane when allocated");
567 SpillFIs.set(FI);
568 updateLaneVGPRDomInstr(FI, MBB, MIS.begin(), LaneVGPRDomInstr);
569 SpilledToVirtVGPRLanes = true;
570 }
571 }
572 }
573
574 for (auto Reg : FuncInfo->getSGPRSpillVGPRs()) {
575 LaneVGPRInsertPt IP = LaneVGPRDomInstr[Reg];
576 if (CycleRef C = MCI->getTopLevelParentCycle(IP.MBB)) {
577 MachineBasicBlock *AdjMBB = getCycleDomBB(C);
578 IP = insertPt(AdjMBB, AdjMBB->getFirstTerminator());
579 }
580 // Insert the IMPLICIT_DEF at the identified points.
581 MachineBasicBlock &Block = *IP.MBB;
582 DebugLoc DL = Block.findDebugLoc(IP.It);
583 auto MIB = BuildMI(Block, IP.It, DL, TII->get(AMDGPU::IMPLICIT_DEF), Reg);
584
585 // Add WWM flag to the virtual register.
587
588 // Set SGPR_SPILL asm printer flag
589 MIB->setAsmPrinterFlag(AMDGPU::SGPR_SPILL);
590 if (LIS) {
591 LIS->InsertMachineInstrInMaps(*MIB);
593 }
594 }
595
596 // Assign the WWM pool from the pre-selected candidates and compute the
597 // complement mask for per-thread VGPR allocation.
598 assignWWMRegs(MF, WWMRegCandidates, RequiresFullWWMPool);
599
600 for (MachineBasicBlock &MBB : MF)
601 clearDebugInfoForSpillFIs(MFI, MBB, SpillFIs);
602
603 // All those frame indices which are dead by now should be removed from the
604 // function frame. Otherwise, there is a side effect such as re-mapping of
605 // free frame index ids by the later pass(es) like "stack slot coloring"
606 // which in turn could mess-up with the book keeping of "frame index to VGPR
607 // lane".
608 FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ false);
609
610 MadeChange = true;
611 }
612
613 if (SpilledToVirtVGPRLanes) {
614 const TargetRegisterClass *RC = TRI->getWaveMaskRegClass();
615 // Shift back the reserved SGPR for EXEC copy into the lowest range.
616 // This SGPR is reserved to handle the whole-wave spill/copy operations
617 // that might get inserted during vgpr regalloc.
618 Register UnusedLowSGPR = TRI->findUnusedRegister(MRI, RC, MF);
619 if (UnusedLowSGPR && TRI->getHWRegIndex(UnusedLowSGPR) <
620 TRI->getHWRegIndex(FuncInfo->getSGPRForEXECCopy()))
621 FuncInfo->setSGPRForEXECCopy(UnusedLowSGPR);
622 } else {
623 // No SGPR spills to virtual VGPR lanes and hence there won't be any WWM
624 // spills/copies. Reset the SGPR reserved for EXEC copy.
625 FuncInfo->setSGPRForEXECCopy(AMDGPU::NoRegister);
626 }
627
628 SaveBlocks.clear();
629 RestoreBlocks.clear();
630
631 return MadeChange;
632}
633
634PreservedAnalyses
637 MFPropsModifier _(*this, MF);
638 auto *LIS = MFAM.getCachedResult<LiveIntervalsAnalysis>(MF);
639 auto *Indexes = MFAM.getCachedResult<SlotIndexesAnalysis>(MF);
642 SILowerSGPRSpills(LIS, Indexes, MDT, &MCI).run(MF);
643 return PreservedAnalyses::all();
644}
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
AMD GCN specific subclass of TargetSubtarget.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static void insertCSRRestores(MachineBasicBlock &RestoreBlock, std::vector< CalleeSavedInfo > &CSI)
Insert restore code for the callee-saved registers used in the function.
SmallVector< MachineBasicBlock *, 4 > MBBVector
static void insertCSRSaves(MachineBasicBlock &SaveBlock, ArrayRef< CalleeSavedInfo > CSI)
Insert spill code for the callee-saved registers used in the function.
static void updateLiveness(MachineFunction &MF)
Helper function to update the liveness information for the callee-saved registers.
This file declares the machine register scavenger class.
static void insertCSRRestores(MachineBasicBlock &RestoreBlock, MutableArrayRef< CalleeSavedInfo > CSI, SlotIndexes *Indexes, LiveIntervals *LIS)
Insert restore code for the callee-saved registers used in the function.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition ArrayRef.h:218
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
bool test(unsigned Idx) const
Returns true if bit Idx is set.
Definition BitVector.h:482
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:353
bool isReducible(CycleRef C) const
ArrayRef< BlockT * > getEntries(CycleRef C) const
CycleRef getTopLevelParentCycle(const BlockT *Block) const
BlockT * getHeader(CycleRef C) const
const HexagonRegisterInfo & getRegisterInfo() const
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Legacy analysis pass which computes a MachineCycleInfo.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setCalleeSavedInfoValid(bool v)
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
uint8_t getStackID(int ObjectIdx) const
const SaveRestorePoints & getRestorePoints() const
const SaveRestorePoints & getSavePoints() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
Representation of each machine instruction.
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void setFlag(Register Reg, uint8_t Flag)
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToVirtualVGPRLanes(int FrameIndex) const
bool allocateSGPRSpillToVGPRLane(MachineFunction &MF, int FI, bool SpillToPhysVGPRLane=false, bool IsPrologEpilog=false)
bool removeDeadFrameIndices(MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs)
If ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill to the default stack.
void updatePerLaneVGPRMask(BitVector &RegMask)
ArrayRef< Register > getSGPRSpillVGPRs() const
SlotIndexes pass.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
LLVM_ABI void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
LLVM_ABI void repairIndexesInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End)
Repair indexes after adding and removing instructions.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Information about stack frame layout on the target.
void restoreCalleeSavedRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const CalleeSavedInfo &CS, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
void clearDebugInfoForSpillFIs(MachineFrameInfo &MFI, MachineBasicBlock &MBB, const BitVector &SpillFIs)
Replace frame index operands with null registers in debug value instructions for the specified spill ...
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
char & SILowerSGPRSpillsLegacyID
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isPreallocateSGPRSpillVGPRsEnabled(const MachineFunction &MF)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58