LLVM 24.0.0git
SIRegisterInfo.cpp
Go to the documentation of this file.
1//===-- SIRegisterInfo.cpp - SI Register Information ---------------------===//
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/// \file
10/// SI implementation of the TargetRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
15#include "GCNSubtarget.h"
23
24using namespace llvm;
25
26#define GET_REGINFO_TARGET_DESC
27#include "AMDGPUGenRegisterInfo.inc"
28
30 "amdgpu-spill-sgpr-to-vgpr",
31 cl::desc("Enable spilling SGPRs to VGPRs"),
33 cl::init(true));
34
36 "amdgpu-spill-cfi-saved-regs",
37 cl::desc("Enable spilling the registers required for CFI emission"),
39
41 "amdgpu-stress-vgpr", cl::Hidden, cl::init(0),
42 cl::desc("Limit VGPRs to N registers by reserving the rest"));
43
45 "amdgpu-stress-agpr", cl::Hidden, cl::init(0),
46 cl::desc("Limit AGPRs to N registers by reserving the rest"));
47
49 "amdgpu-stress-sgpr", cl::Hidden, cl::init(0),
50 cl::desc("Limit SGPRs to N registers by reserving the rest"));
51
52std::array<std::vector<int16_t>, 32> SIRegisterInfo::RegSplitParts;
53std::array<std::array<uint16_t, 32>, 9> SIRegisterInfo::SubRegFromChannelTable;
54
55// Map numbers of DWORDs to indexes in SubRegFromChannelTable.
56// Valid indexes are shifted 1, such that a 0 mapping means unsupported.
57// e.g. for 8 DWORDs (256-bit), SubRegFromChannelTableWidthMap[8] = 8,
58// meaning index 7 in SubRegFromChannelTable.
59static const std::array<unsigned, 17> SubRegFromChannelTableWidthMap = {
60 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 9};
61
62static void emitUnsupportedError(const Function &Fn, const MachineInstr &MI,
63 const Twine &ErrMsg) {
65 DiagnosticInfoUnsupported(Fn, ErrMsg, MI.getDebugLoc()));
66}
67
68namespace llvm {
69
70// A temporary struct to spill SGPRs.
71// This is mostly to spill SGPRs to memory. Spilling SGPRs into VGPR lanes emits
72// just v_writelane and v_readlane.
73//
74// When spilling to memory, the SGPRs are written into VGPR lanes and the VGPR
75// is saved to scratch (or the other way around for loads).
76// For this, a VGPR is required where the needed lanes can be clobbered. The
77// RegScavenger can provide a VGPR where currently active lanes can be
78// clobbered, but we still need to save inactive lanes.
79// The high-level steps are:
80// - Try to scavenge SGPR(s) to save exec
81// - Try to scavenge VGPR
82// - Save needed, all or inactive lanes of a TmpVGPR
83// - Spill/Restore SGPRs using TmpVGPR
84// - Restore TmpVGPR
85//
86// To save all lanes of TmpVGPR, exec needs to be saved and modified. If we
87// cannot scavenge temporary SGPRs to save exec, we use the following code:
88// buffer_store_dword TmpVGPR ; only if active lanes need to be saved
89// s_not exec, exec
90// buffer_store_dword TmpVGPR ; save inactive lanes
91// s_not exec, exec
93 struct PerVGPRData {
94 unsigned PerVGPR;
95 unsigned NumVGPRs;
96 int64_t VGPRLanes;
97 };
98
99 // The SGPR to save
103 unsigned NumSubRegs;
104 bool IsKill;
105 const DebugLoc &DL;
106
107 /* When spilling to stack */
108 // The SGPRs are written into this VGPR, which is then written to scratch
109 // (or vice versa for loads).
110 Register TmpVGPR = AMDGPU::NoRegister;
111 // Temporary spill slot to save TmpVGPR to.
113 // If TmpVGPR is live before the spill or if it is scavenged.
114 bool TmpVGPRLive = false;
115 // Scavenged SGPR to save EXEC.
116 Register SavedExecReg = AMDGPU::NoRegister;
117 // Stack index to write the SGPRs to.
118 int Index;
119 unsigned EltSize = 4;
120
129 unsigned MovOpc;
130 unsigned NotOpc;
131
135 : SGPRSpillBuilder(TRI, TII, IsWave32, MI, MI->getOperand(0).getReg(),
136 MI->getOperand(0).isKill(), Index, RS) {}
137
140 bool IsKill, int Index, RegScavenger *RS)
141 : SuperReg(Reg), MI(MI), IsKill(IsKill), DL(MI->getDebugLoc()),
142 Index(Index), RS(RS), MBB(MI->getParent()), MF(*MBB->getParent()),
143 MFI(*MF.getInfo<SIMachineFunctionInfo>()), TII(TII), TRI(TRI),
145 const TargetRegisterClass *RC = TRI.getPhysRegBaseClass(SuperReg);
146 SplitParts = TRI.getRegSplitParts(RC, EltSize);
147 NumSubRegs = SplitParts.empty() ? 1 : SplitParts.size();
148
149 if (IsWave32) {
150 ExecReg = AMDGPU::EXEC_LO;
151 MovOpc = AMDGPU::S_MOV_B32;
152 NotOpc = AMDGPU::S_NOT_B32;
153 } else {
154 ExecReg = AMDGPU::EXEC;
155 MovOpc = AMDGPU::S_MOV_B64;
156 NotOpc = AMDGPU::S_NOT_B64;
157 }
158
159 assert(SuperReg != AMDGPU::M0 && "m0 should never spill");
160 assert(SuperReg != AMDGPU::EXEC_LO && SuperReg != AMDGPU::EXEC_HI &&
161 SuperReg != AMDGPU::EXEC && "exec should never spill");
162 }
163
166 Data.PerVGPR = IsWave32 ? 32 : 64;
167 Data.NumVGPRs = (NumSubRegs + (Data.PerVGPR - 1)) / Data.PerVGPR;
168 Data.VGPRLanes = (1LL << std::min(Data.PerVGPR, NumSubRegs)) - 1LL;
169 return Data;
170 }
171
172 // Tries to scavenge SGPRs to save EXEC and a VGPR. Uses v0 if no VGPR is
173 // free.
174 // Writes these instructions if an SGPR can be scavenged:
175 // s_mov_b64 s[6:7], exec ; Save exec
176 // s_mov_b64 exec, 3 ; Wanted lanemask
177 // buffer_store_dword v1 ; Write scavenged VGPR to emergency slot
178 //
179 // Writes these instructions if no SGPR can be scavenged:
180 // buffer_store_dword v0 ; Only if no free VGPR was found
181 // s_not_b64 exec, exec
182 // buffer_store_dword v0 ; Save inactive lanes
183 // ; exec stays inverted, it is flipped back in
184 // ; restore.
185 void prepare() {
186 // Scavenged temporary VGPR to use. It must be scavenged once for any number
187 // of spilled subregs.
188 // FIXME: The liveness analysis is limited and does not tell if a register
189 // is in use in lanes that are currently inactive. We can never be sure if
190 // a register as actually in use in another lane, so we need to save all
191 // used lanes of the chosen VGPR.
192 assert(RS && "Cannot spill SGPR to memory without RegScavenger");
193 TmpVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false,
194 0, false);
195
196 // Reserve temporary stack slot
197 TmpVGPRIndex = MFI.getScavengeFI(MF.getFrameInfo(), TRI);
198 if (TmpVGPR) {
199 // Found a register that is dead in the currently active lanes, we only
200 // need to spill inactive lanes.
201 TmpVGPRLive = false;
202 } else {
203 // Pick v0 because it doesn't make a difference.
204 TmpVGPR = AMDGPU::VGPR0;
205 TmpVGPRLive = true;
206 }
207
208 if (TmpVGPRLive) {
209 // We need to inform the scavenger that this index is already in use until
210 // we're done with the custom emergency spill.
211 RS->assignRegToScavengingIndex(TmpVGPRIndex, TmpVGPR);
212 }
213
214 // We may end up recursively calling the scavenger, and don't want to re-use
215 // the same register.
216 RS->setRegUsed(TmpVGPR);
217
218 // Try to scavenge SGPRs to save exec
219 assert(!SavedExecReg && "Exec is already saved, refuse to save again");
220 const TargetRegisterClass &RC =
221 IsWave32 ? AMDGPU::SGPR_32RegClass : AMDGPU::SGPR_64RegClass;
222 RS->setRegUsed(SuperReg);
223 SavedExecReg = RS->scavengeRegisterBackwards(RC, MI, false, 0, false);
224
225 int64_t VGPRLanes = getPerVGPRData().VGPRLanes;
226
227 if (SavedExecReg) {
228 RS->setRegUsed(SavedExecReg);
229 // Set exec to needed lanes
231 auto I =
232 BuildMI(*MBB, MI, DL, TII.get(MovOpc), ExecReg).addImm(VGPRLanes);
233 if (!TmpVGPRLive)
235 // Spill needed lanes
236 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ false);
237 } else {
238 // The modify and restore of exec clobber SCC, which we would have to save
239 // and restore. FIXME: We probably would need to reserve a register for
240 // this.
241 if (RS->isRegUsed(AMDGPU::SCC))
242 emitUnsupportedError(MF.getFunction(), *MI,
243 "unhandled SGPR spill to memory");
244
245 // Spill active lanes
246 if (TmpVGPRLive)
247 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ false,
248 /*IsKill*/ false);
249 // Spill inactive lanes
250 auto I = BuildMI(*MBB, MI, DL, TII.get(NotOpc), ExecReg).addReg(ExecReg);
251 if (!TmpVGPRLive)
253 I->getOperand(2).setIsDead(); // Mark SCC as dead.
254 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ false);
255 }
256 }
257
258 // Writes these instructions if an SGPR can be scavenged:
259 // buffer_load_dword v1 ; Write scavenged VGPR to emergency slot
260 // s_waitcnt vmcnt(0) ; If a free VGPR was found
261 // s_mov_b64 exec, s[6:7] ; Save exec
262 //
263 // Writes these instructions if no SGPR can be scavenged:
264 // buffer_load_dword v0 ; Restore inactive lanes
265 // s_waitcnt vmcnt(0) ; If a free VGPR was found
266 // s_not_b64 exec, exec
267 // buffer_load_dword v0 ; Only if no free VGPR was found
268 void restore() {
269 if (SavedExecReg) {
270 // Restore used lanes
271 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ true,
272 /*IsKill*/ false);
273 // Restore exec
274 auto I = BuildMI(*MBB, MI, DL, TII.get(MovOpc), ExecReg)
276 // Add an implicit use of the load so it is not dead.
277 // FIXME This inserts an unnecessary waitcnt
278 if (!TmpVGPRLive) {
280 }
281 } else {
282 // Restore inactive lanes
283 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ true,
284 /*IsKill*/ false);
285 auto I = BuildMI(*MBB, MI, DL, TII.get(NotOpc), ExecReg).addReg(ExecReg);
286 if (!TmpVGPRLive)
288 I->getOperand(2).setIsDead(); // Mark SCC as dead.
289
290 // Restore active lanes
291 if (TmpVGPRLive)
292 TRI.buildVGPRSpillLoadStore(*this, TmpVGPRIndex, 0, /*IsLoad*/ true);
293 }
294
295 // Inform the scavenger where we're releasing our custom scavenged register.
296 if (TmpVGPRLive) {
297 MachineBasicBlock::iterator RestorePt = std::prev(MI);
298 RS->assignRegToScavengingIndex(TmpVGPRIndex, TmpVGPR, &*RestorePt);
299 }
300 }
301
302 // Write TmpVGPR to memory or read TmpVGPR from memory.
303 // Either using a single buffer_load/store if exec is set to the needed mask
304 // or using
305 // buffer_load
306 // s_not exec, exec
307 // buffer_load
308 // s_not exec, exec
309 void readWriteTmpVGPR(unsigned Offset, bool IsLoad) {
310 if (SavedExecReg) {
311 // Spill needed lanes
312 TRI.buildVGPRSpillLoadStore(*this, Index, Offset, IsLoad);
313 } else {
314 // The modify and restore of exec clobber SCC, which we would have to save
315 // and restore. FIXME: We probably would need to reserve a register for
316 // this.
317 if (RS->isRegUsed(AMDGPU::SCC))
318 emitUnsupportedError(MF.getFunction(), *MI,
319 "unhandled SGPR spill to memory");
320
321 // Spill active lanes
322 TRI.buildVGPRSpillLoadStore(*this, Index, Offset, IsLoad,
323 /*IsKill*/ false);
324 // Spill inactive lanes
325 auto Not0 = BuildMI(*MBB, MI, DL, TII.get(NotOpc), ExecReg).addReg(ExecReg);
326 Not0->getOperand(2).setIsDead(); // Mark SCC as dead.
327 TRI.buildVGPRSpillLoadStore(*this, Index, Offset, IsLoad);
328 auto Not1 = BuildMI(*MBB, MI, DL, TII.get(NotOpc), ExecReg).addReg(ExecReg);
329 Not1->getOperand(2).setIsDead(); // Mark SCC as dead.
330 }
331 }
332
334 assert(MBB->getParent() == &MF);
335 MI = NewMI;
336 MBB = NewMBB;
337 }
338};
339
340} // namespace llvm
341
343 : AMDGPUGenRegisterInfo(AMDGPU::PC_REG, ST.getAMDGPUDwarfFlavour(),
344 ST.getAMDGPUDwarfFlavour(),
345 /*PC=*/0,
346 ST.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
347 ST(ST), SpillSGPRToVGPR(EnableSpillSGPRToVGPR), isWave32(ST.isWave32()) {
348
349 assert(getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() == 3 &&
350 getSubRegIndexLaneMask(AMDGPU::sub31).getAsInteger() == (3ULL << 62) &&
351 (getSubRegIndexLaneMask(AMDGPU::lo16) |
352 getSubRegIndexLaneMask(AMDGPU::hi16)).getAsInteger() ==
353 getSubRegIndexLaneMask(AMDGPU::sub0).getAsInteger() &&
354 "getNumCoveredRegs() will not work with generated subreg masks!");
355
356 RegPressureIgnoredUnits.resize(getNumRegUnits());
357 RegPressureIgnoredUnits.set(
358 static_cast<unsigned>(*regunits(MCRegister::from(AMDGPU::M0)).begin()));
359 for (auto Reg : AMDGPU::VGPR_16RegClass) {
360 if (AMDGPU::isHi16Reg(Reg, *this))
361 RegPressureIgnoredUnits.set(
362 static_cast<unsigned>(*regunits(Reg).begin()));
363 }
364
365 // HACK: Until this is fully tablegen'd.
366 static llvm::once_flag InitializeRegSplitPartsFlag;
367
368 static auto InitializeRegSplitPartsOnce = [this]() {
369 for (unsigned Idx = 1, E = getNumSubRegIndices() - 1; Idx < E; ++Idx) {
370 unsigned Size = getSubRegIdxSize(Idx);
371 if (Size & 15)
372 continue;
373 std::vector<int16_t> &Vec = RegSplitParts[Size / 16 - 1];
374 unsigned Pos = getSubRegIdxOffset(Idx);
375 if (Pos % Size)
376 continue;
377 Pos /= Size;
378 if (Vec.empty()) {
379 unsigned MaxNumParts = 1024 / Size; // Maximum register is 1024 bits.
380 Vec.resize(MaxNumParts);
381 }
382 Vec[Pos] = Idx;
383 }
384 };
385
386 static llvm::once_flag InitializeSubRegFromChannelTableFlag;
387
388 static auto InitializeSubRegFromChannelTableOnce = [this]() {
389 for (auto &Row : SubRegFromChannelTable)
390 Row.fill(AMDGPU::NoSubRegister);
391 for (unsigned Idx = 1; Idx < getNumSubRegIndices(); ++Idx) {
392 unsigned Width = getSubRegIdxSize(Idx) / 32;
393 unsigned Offset = getSubRegIdxOffset(Idx) / 32;
395 Width = SubRegFromChannelTableWidthMap[Width];
396 if (Width == 0)
397 continue;
398 unsigned TableIdx = Width - 1;
399 assert(TableIdx < SubRegFromChannelTable.size());
400 assert(Offset < SubRegFromChannelTable[TableIdx].size());
401 SubRegFromChannelTable[TableIdx][Offset] = Idx;
402 }
403 };
404
405 llvm::call_once(InitializeRegSplitPartsFlag, InitializeRegSplitPartsOnce);
406 llvm::call_once(InitializeSubRegFromChannelTableFlag,
407 InitializeSubRegFromChannelTableOnce);
408}
409
410void SIRegisterInfo::reserveRegisterTuples(BitVector &Reserved,
411 MCRegister Reg) const {
412 for (MCRegAliasIterator R(Reg, this, true); R.isValid(); ++R)
413 Reserved.set(*R);
414}
415
416// Forced to be here by one .inc
418 const MachineFunction *MF) const {
420 switch (CC) {
421 case CallingConv::C:
424 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_SaveList
425 : CSR_AMDGPU_SaveList;
428 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_SaveList
429 : CSR_AMDGPU_SI_Gfx_SaveList;
431 return CSR_AMDGPU_CS_ChainPreserve_SaveList;
432 default: {
433 // Dummy to not crash RegisterClassInfo.
434 static const MCPhysReg NoCalleeSavedReg = AMDGPU::NoRegister;
435 return &NoCalleeSavedReg;
436 }
437 }
438}
439
440const MCPhysReg *
442 return nullptr;
443}
444
446 CallingConv::ID CC) const {
447 switch (CC) {
448 case CallingConv::C:
451 return ST.hasGFX90AInsts() ? CSR_AMDGPU_GFX90AInsts_RegMask
452 : CSR_AMDGPU_RegMask;
455 return ST.hasGFX90AInsts() ? CSR_AMDGPU_SI_Gfx_GFX90AInsts_RegMask
456 : CSR_AMDGPU_SI_Gfx_RegMask;
459 // Calls to these functions never return, so we can pretend everything is
460 // preserved.
461 return AMDGPU_AllVGPRs_RegMask;
462 default:
463 return nullptr;
464 }
465}
466
468 return CSR_AMDGPU_NoRegs_RegMask;
469}
470
472 return VGPR >= AMDGPU::VGPR0 && VGPR < AMDGPU::VGPR8;
473}
474
477 const MachineFunction &MF) const {
478 // FIXME: Should have a helper function like getEquivalentVGPRClass to get the
479 // equivalent AV class. If used one, the verifier will crash after
480 // RegBankSelect in the GISel flow. The aligned regclasses are not fully given
481 // until Instruction selection.
482 if (ST.hasMAIInsts() && (isVGPRClass(RC) || isAGPRClass(RC))) {
483 if (RC == &AMDGPU::VGPR_32RegClass || RC == &AMDGPU::AGPR_32RegClass)
484 return &AMDGPU::AV_32RegClass;
485 if (RC == &AMDGPU::VReg_64RegClass || RC == &AMDGPU::AReg_64RegClass)
486 return &AMDGPU::AV_64RegClass;
487 if (RC == &AMDGPU::VReg_64_Align2RegClass ||
488 RC == &AMDGPU::AReg_64_Align2RegClass)
489 return &AMDGPU::AV_64_Align2RegClass;
490 if (RC == &AMDGPU::VReg_96RegClass || RC == &AMDGPU::AReg_96RegClass)
491 return &AMDGPU::AV_96RegClass;
492 if (RC == &AMDGPU::VReg_96_Align2RegClass ||
493 RC == &AMDGPU::AReg_96_Align2RegClass)
494 return &AMDGPU::AV_96_Align2RegClass;
495 if (RC == &AMDGPU::VReg_128RegClass || RC == &AMDGPU::AReg_128RegClass)
496 return &AMDGPU::AV_128RegClass;
497 if (RC == &AMDGPU::VReg_128_Align2RegClass ||
498 RC == &AMDGPU::AReg_128_Align2RegClass)
499 return &AMDGPU::AV_128_Align2RegClass;
500 if (RC == &AMDGPU::VReg_160RegClass || RC == &AMDGPU::AReg_160RegClass)
501 return &AMDGPU::AV_160RegClass;
502 if (RC == &AMDGPU::VReg_160_Align2RegClass ||
503 RC == &AMDGPU::AReg_160_Align2RegClass)
504 return &AMDGPU::AV_160_Align2RegClass;
505 if (RC == &AMDGPU::VReg_192RegClass || RC == &AMDGPU::AReg_192RegClass)
506 return &AMDGPU::AV_192RegClass;
507 if (RC == &AMDGPU::VReg_192_Align2RegClass ||
508 RC == &AMDGPU::AReg_192_Align2RegClass)
509 return &AMDGPU::AV_192_Align2RegClass;
510 if (RC == &AMDGPU::VReg_256RegClass || RC == &AMDGPU::AReg_256RegClass)
511 return &AMDGPU::AV_256RegClass;
512 if (RC == &AMDGPU::VReg_256_Align2RegClass ||
513 RC == &AMDGPU::AReg_256_Align2RegClass)
514 return &AMDGPU::AV_256_Align2RegClass;
515 if (RC == &AMDGPU::VReg_512RegClass || RC == &AMDGPU::AReg_512RegClass)
516 return &AMDGPU::AV_512RegClass;
517 if (RC == &AMDGPU::VReg_512_Align2RegClass ||
518 RC == &AMDGPU::AReg_512_Align2RegClass)
519 return &AMDGPU::AV_512_Align2RegClass;
520 if (RC == &AMDGPU::VReg_1024RegClass || RC == &AMDGPU::AReg_1024RegClass)
521 return &AMDGPU::AV_1024RegClass;
522 if (RC == &AMDGPU::VReg_1024_Align2RegClass ||
523 RC == &AMDGPU::AReg_1024_Align2RegClass)
524 return &AMDGPU::AV_1024_Align2RegClass;
525 }
526
528}
529
531 const SIFrameLowering *TFI = ST.getFrameLowering();
533
534 // During ISel lowering we always reserve the stack pointer in entry and chain
535 // functions, but never actually want to reference it when accessing our own
536 // frame. If we need a frame pointer we use it, but otherwise we can just use
537 // an immediate "0" which we represent by returning NoRegister.
538 if (FuncInfo->isBottomOfStack()) {
539 return TFI->hasFP(MF) ? FuncInfo->getFrameOffsetReg() : Register();
540 }
541 return TFI->hasFP(MF) ? FuncInfo->getFrameOffsetReg()
542 : FuncInfo->getStackPtrOffsetReg();
543}
544
546 // When we need stack realignment, we can't reference off of the
547 // stack pointer, so we reserve a base pointer.
548 return shouldRealignStack(MF);
549}
550
551Register SIRegisterInfo::getBaseRegister() const { return AMDGPU::SGPR34; }
552
554 return AMDGPU_AllVGPRs_RegMask;
555}
556
558 return AMDGPU_AllAGPRs_RegMask;
559}
560
562 return AMDGPU_AllVectorRegs_RegMask;
563}
564
566 return AMDGPU_AllAllocatableSRegs_RegMask;
567}
568
569unsigned SIRegisterInfo::getSubRegFromChannel(unsigned Channel,
570 unsigned NumRegs) {
571 assert(NumRegs < SubRegFromChannelTableWidthMap.size());
572 unsigned NumRegIndex = SubRegFromChannelTableWidthMap[NumRegs];
573 assert(NumRegIndex && "Not implemented");
574 assert(Channel < SubRegFromChannelTable[NumRegIndex - 1].size());
575 return SubRegFromChannelTable[NumRegIndex - 1][Channel];
576}
577
581
584 const unsigned Align,
585 const TargetRegisterClass *RC) const {
586 unsigned BaseIdx = alignDown(ST.getMaxNumSGPRs(MF), Align) - Align;
587 MCRegister BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx));
588 return getMatchingSuperReg(BaseReg, AMDGPU::sub0, RC);
589}
590
592 const MachineFunction &MF) const {
593 return getAlignedHighSGPRForRC(MF, /*Align=*/4, &AMDGPU::SGPR_128RegClass);
594}
595
597 BitVector Reserved(getNumRegs());
598 Reserved.set(AMDGPU::MODE);
599
601
602 // Reserve special purpose registers.
603 //
604 // EXEC_LO and EXEC_HI could be allocated and used as regular register, but
605 // this seems likely to result in bugs, so I'm marking them as reserved.
606 reserveRegisterTuples(Reserved, AMDGPU::EXEC);
607 reserveRegisterTuples(Reserved, AMDGPU::FLAT_SCR);
608
609 // M0 has to be reserved so that llvm accepts it as a live-in into a block.
610 reserveRegisterTuples(Reserved, AMDGPU::M0);
611
612 // Reserve src_vccz, src_execz, src_scc.
613 reserveRegisterTuples(Reserved, AMDGPU::SRC_VCCZ);
614 reserveRegisterTuples(Reserved, AMDGPU::SRC_EXECZ);
615 reserveRegisterTuples(Reserved, AMDGPU::SRC_SCC);
616
617 // Reserve the memory aperture registers
618 reserveRegisterTuples(Reserved, AMDGPU::SRC_SHARED_BASE);
619 reserveRegisterTuples(Reserved, AMDGPU::SRC_SHARED_LIMIT);
620 reserveRegisterTuples(Reserved, AMDGPU::SRC_PRIVATE_BASE);
621 reserveRegisterTuples(Reserved, AMDGPU::SRC_PRIVATE_LIMIT);
622 reserveRegisterTuples(Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_LO);
623 reserveRegisterTuples(Reserved, AMDGPU::SRC_FLAT_SCRATCH_BASE_HI);
624
625 // Reserve async counters pseudo registers
626 reserveRegisterTuples(Reserved, AMDGPU::ASYNCcnt);
627 reserveRegisterTuples(Reserved, AMDGPU::TENSORcnt);
628
629 // Reserve src_pops_exiting_wave_id - support is not implemented in Codegen.
630 reserveRegisterTuples(Reserved, AMDGPU::SRC_POPS_EXITING_WAVE_ID);
631
632 // Reserve xnack_mask registers - support is not implemented in Codegen.
633 reserveRegisterTuples(Reserved, AMDGPU::XNACK_MASK);
634
635 // Reserve lds_direct register - support is not implemented in Codegen.
636 reserveRegisterTuples(Reserved, AMDGPU::LDS_DIRECT);
637
638 // Reserve Trap Handler registers - support is not implemented in Codegen.
639 reserveRegisterTuples(Reserved, AMDGPU::TBA);
640 reserveRegisterTuples(Reserved, AMDGPU::TMA);
641 reserveRegisterTuples(Reserved, AMDGPU::TTMP0_TTMP1);
642 reserveRegisterTuples(Reserved, AMDGPU::TTMP2_TTMP3);
643 reserveRegisterTuples(Reserved, AMDGPU::TTMP4_TTMP5);
644 reserveRegisterTuples(Reserved, AMDGPU::TTMP6_TTMP7);
645 reserveRegisterTuples(Reserved, AMDGPU::TTMP8_TTMP9);
646 reserveRegisterTuples(Reserved, AMDGPU::TTMP10_TTMP11);
647 reserveRegisterTuples(Reserved, AMDGPU::TTMP12_TTMP13);
648 reserveRegisterTuples(Reserved, AMDGPU::TTMP14_TTMP15);
649
650 // Reserve null register - it shall never be allocated
651 reserveRegisterTuples(Reserved, AMDGPU::SGPR_NULL64);
652
653 // Reserve SGPRs.
654 //
655 unsigned MaxNumSGPRs = ST.getMaxNumSGPRs(MF);
656 if (StressSGPRLimit.getNumOccurrences() && StressSGPRLimit < MaxNumSGPRs)
657 MaxNumSGPRs = StressSGPRLimit;
658 unsigned TotalNumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
659 for (const TargetRegisterClass &RC : regclasses()) {
660 if (RC.isBaseClass() && isSGPRClass(&RC)) {
661 unsigned NumRegs = divideCeil(getRegSizeInBits(RC), 32);
662 for (MCPhysReg Reg : RC) {
663 unsigned Index = getHWRegIndex(Reg);
664 if (Index + NumRegs > MaxNumSGPRs && Index < TotalNumSGPRs &&
665 Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
666 Reg != AMDGPU::VCC)
667 Reserved.set(Reg);
668 }
669 }
670 }
671
672 Register ScratchRSrcReg = MFI->getScratchRSrcReg();
673 if (ScratchRSrcReg != AMDGPU::NoRegister) {
674 // Reserve 4 SGPRs for the scratch buffer resource descriptor in case we
675 // need to spill.
676 // TODO: May need to reserve a VGPR if doing LDS spilling.
677 reserveRegisterTuples(Reserved, ScratchRSrcReg);
678 }
679
680 Register LongBranchReservedReg = MFI->getLongBranchReservedReg();
681 if (LongBranchReservedReg)
682 reserveRegisterTuples(Reserved, LongBranchReservedReg);
683
684 // We have to assume the SP is needed in case there are calls in the function,
685 // which is detected after the function is lowered. If we aren't really going
686 // to need SP, don't bother reserving it.
687 MCRegister StackPtrReg = MFI->getStackPtrOffsetReg();
688 if (StackPtrReg) {
689 reserveRegisterTuples(Reserved, StackPtrReg);
690 assert(!isSubRegister(ScratchRSrcReg, StackPtrReg));
691 }
692
693 MCRegister FrameReg = MFI->getFrameOffsetReg();
694 if (FrameReg) {
695 reserveRegisterTuples(Reserved, FrameReg);
696 assert(!isSubRegister(ScratchRSrcReg, FrameReg));
697 }
698
699 if (hasBasePointer(MF)) {
700 MCRegister BasePtrReg = getBaseRegister();
701 reserveRegisterTuples(Reserved, BasePtrReg);
702 assert(!isSubRegister(ScratchRSrcReg, BasePtrReg));
703 }
704
705 // FIXME: Use same reserved register introduced in D149775
706 // SGPR used to preserve EXEC MASK around WWM spill/copy instructions.
707 Register ExecCopyReg = MFI->getSGPRForEXECCopy();
708 if (ExecCopyReg)
709 reserveRegisterTuples(Reserved, ExecCopyReg);
710
711 // Reserve VGPRs/AGPRs.
712 //
713 auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.getFunction());
714
715 // Stress test: override VGPR/AGPR limits.
716 if (StressVGPRLimit.getNumOccurrences() && StressVGPRLimit < MaxNumVGPRs)
717 MaxNumVGPRs = StressVGPRLimit;
718 if (StressAGPRLimit.getNumOccurrences() && StressAGPRLimit < MaxNumAGPRs)
719 MaxNumAGPRs = StressAGPRLimit;
720
721 for (const TargetRegisterClass &RC : regclasses()) {
722 if (RC.isBaseClass() && isVGPRClass(&RC)) {
723 unsigned NumRegs = divideCeil(getRegSizeInBits(RC), 32);
724 for (MCPhysReg Reg : RC) {
725 unsigned Index = getHWRegIndex(Reg);
726 if (Index + NumRegs > MaxNumVGPRs)
727 Reserved.set(Reg);
728 }
729 }
730 }
731
732 // Reserve all the AGPRs if there are no instructions to use it.
733 if (!ST.hasMAIInsts())
734 MaxNumAGPRs = 0;
735 for (const TargetRegisterClass &RC : regclasses()) {
736 if (RC.isBaseClass() && isAGPRClass(&RC)) {
737 unsigned NumRegs = divideCeil(getRegSizeInBits(RC), 32);
738 for (MCPhysReg Reg : RC) {
739 unsigned Index = getHWRegIndex(Reg);
740 if (Index + NumRegs > MaxNumAGPRs)
741 Reserved.set(Reg);
742 }
743 }
744 }
745
746 // On GFX908, in order to guarantee copying between AGPRs, we need a scratch
747 // VGPR available at all times.
748 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
749 reserveRegisterTuples(Reserved, MFI->getVGPRForAGPRCopy());
750 }
751
752 // During wwm-regalloc, reserve the registers for per-lane VGPR allocation.
753 // The MFI->getPerLaneVGPRMask() field will have a valid bitmask only during
754 // wwm-regalloc and it would be empty otherwise.
755 BitVector PerLaneVGPRMask = MFI->getPerLaneVGPRMask();
756 if (!PerLaneVGPRMask.empty()) {
757 for (unsigned RegI = AMDGPU::VGPR0, RegE = AMDGPU::VGPR0 + MaxNumVGPRs;
758 RegI < RegE; ++RegI) {
759 if (PerLaneVGPRMask.test(RegI))
760 reserveRegisterTuples(Reserved, RegI);
761 }
762 }
763
764 for (Register Reg : MFI->getWWMReservedRegs())
765 reserveRegisterTuples(Reserved, Reg);
766
767 // FIXME: Stop using reserved registers for this.
768 for (MCPhysReg Reg : MFI->getAGPRSpillVGPRs())
769 reserveRegisterTuples(Reserved, Reg);
770
771 for (MCPhysReg Reg : MFI->getVGPRSpillAGPRs())
772 reserveRegisterTuples(Reserved, Reg);
773
774 return Reserved;
775}
776
778 MCRegister PhysReg) const {
779 return !MF.getRegInfo().isReserved(PhysReg);
780}
781
784 // On entry or in chain functions, the base address is 0, so it can't possibly
785 // need any more alignment.
786
787 // FIXME: Should be able to specify the entry frame alignment per calling
788 // convention instead.
789 if (Info->isBottomOfStack())
790 return false;
791
793}
794
797 if (Info->isEntryFunction()) {
798 const MachineFrameInfo &MFI = Fn.getFrameInfo();
799 return MFI.hasStackObjects() || MFI.hasCalls();
800 }
801
802 // May need scavenger for dealing with callee saved registers.
803 return true;
804}
805
807 const MachineFunction &MF) const {
808 // Do not use frame virtual registers. They used to be used for SGPRs, but
809 // once we reach PrologEpilogInserter, we can no longer spill SGPRs. If the
810 // scavenger fails, we can increment/decrement the necessary SGPRs to avoid a
811 // spill.
812 return false;
813}
814
816 const MachineFunction &MF) const {
817 const MachineFrameInfo &MFI = MF.getFrameInfo();
818 return MFI.hasStackObjects();
819}
820
822 const MachineFunction &) const {
823 // There are no special dedicated stack or frame pointers.
824 return true;
825}
826
829
830 int OffIdx = AMDGPU::getNamedOperandIdx(MI->getOpcode(),
831 AMDGPU::OpName::offset);
832 return MI->getOperand(OffIdx).getImm();
833}
834
836 int Idx) const {
837 switch (MI->getOpcode()) {
838 case AMDGPU::V_ADD_U32_e32:
839 case AMDGPU::V_ADD_U32_e64:
840 case AMDGPU::V_ADD_CO_U32_e32: {
841 int OtherIdx = Idx == 1 ? 2 : 1;
842 const MachineOperand &OtherOp = MI->getOperand(OtherIdx);
843 return OtherOp.isImm() ? OtherOp.getImm() : 0;
844 }
845 case AMDGPU::V_ADD_CO_U32_e64: {
846 int OtherIdx = Idx == 2 ? 3 : 2;
847 const MachineOperand &OtherOp = MI->getOperand(OtherIdx);
848 return OtherOp.isImm() ? OtherOp.getImm() : 0;
849 }
850 default:
851 break;
852 }
853
855 return 0;
856
857 assert((Idx == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
858 AMDGPU::OpName::vaddr) ||
859 (Idx == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
860 AMDGPU::OpName::saddr))) &&
861 "Should never see frame index on non-address operand");
862
864}
865
867 const MachineInstr &MI) {
868 assert(MI.getDesc().isAdd());
869 const MachineOperand &Src0 = MI.getOperand(1);
870 const MachineOperand &Src1 = MI.getOperand(2);
871
872 if (Src0.isFI()) {
873 return Src1.isImm() || (Src1.isReg() && TRI.isVGPR(MI.getMF()->getRegInfo(),
874 Src1.getReg()));
875 }
876
877 if (Src1.isFI()) {
878 return Src0.isImm() || (Src0.isReg() && TRI.isVGPR(MI.getMF()->getRegInfo(),
879 Src0.getReg()));
880 }
881
882 return false;
883}
884
886 // TODO: Handle v_add_co_u32, v_or_b32, v_and_b32 and scalar opcodes.
887 switch (MI->getOpcode()) {
888 case AMDGPU::V_ADD_U32_e32: {
889 // TODO: We could handle this but it requires work to avoid violating
890 // operand restrictions.
891 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e32) < 2 &&
892 !isFIPlusImmOrVGPR(*this, *MI))
893 return false;
894 [[fallthrough]];
895 }
896 case AMDGPU::V_ADD_U32_e64:
897 // FIXME: This optimization is barely profitable hasFlatScratchEnabled
898 // as-is.
899 //
900 // Much of the benefit with the MUBUF handling is we avoid duplicating the
901 // shift of the frame register, which isn't needed with scratch.
902 //
903 // materializeFrameBaseRegister doesn't know the register classes of the
904 // uses, and unconditionally uses an s_add_i32, which will end up using a
905 // copy for the vector uses.
906 return !ST.hasFlatScratchEnabled();
907 case AMDGPU::V_ADD_CO_U32_e32:
908 if (ST.getConstantBusLimit(AMDGPU::V_ADD_CO_U32_e32) < 2 &&
909 !isFIPlusImmOrVGPR(*this, *MI))
910 return false;
911 // We can't deal with the case where the carry out has a use (though this
912 // should never happen)
913 return MI->getOperand(3).isDead();
914 case AMDGPU::V_ADD_CO_U32_e64:
915 // TODO: Should we check use_empty instead?
916 return MI->getOperand(1).isDead();
917 default:
918 break;
919 }
920
922 return false;
923
924 int64_t FullOffset = Offset + getScratchInstrOffset(MI);
925
926 const SIInstrInfo *TII = ST.getInstrInfo();
928 return !TII->isLegalMUBUFImmOffset(FullOffset);
929
930 return !TII->isLegalFLATOffset(FullOffset, AMDGPUAS::PRIVATE_ADDRESS,
932}
933
935 int FrameIdx,
936 int64_t Offset) const {
937 MachineBasicBlock::iterator Ins = MBB->begin();
938 DebugLoc DL; // Defaults to "unknown"
939
940 if (Ins != MBB->end())
941 DL = Ins->getDebugLoc();
942
943 MachineFunction *MF = MBB->getParent();
944 const SIInstrInfo *TII = ST.getInstrInfo();
945 MachineRegisterInfo &MRI = MF->getRegInfo();
946 unsigned MovOpc =
947 ST.hasFlatScratchEnabled() ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
948
949 Register BaseReg = MRI.createVirtualRegister(
950 ST.hasFlatScratchEnabled() ? &AMDGPU::SReg_32_XEXEC_HIRegClass
951 : &AMDGPU::VGPR_32RegClass);
952
953 if (Offset == 0) {
954 BuildMI(*MBB, Ins, DL, TII->get(MovOpc), BaseReg)
955 .addFrameIndex(FrameIdx);
956 return BaseReg;
957 }
958
959 Register OffsetReg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
960
961 Register FIReg = MRI.createVirtualRegister(ST.hasFlatScratchEnabled()
962 ? &AMDGPU::SReg_32_XM0RegClass
963 : &AMDGPU::VGPR_32RegClass);
964
965 BuildMI(*MBB, Ins, DL, TII->get(AMDGPU::S_MOV_B32), OffsetReg)
966 .addImm(Offset);
967 BuildMI(*MBB, Ins, DL, TII->get(MovOpc), FIReg)
968 .addFrameIndex(FrameIdx);
969
970 if (ST.hasFlatScratchEnabled()) {
971 // FIXME: Make sure scc isn't live in.
972 BuildMI(*MBB, Ins, DL, TII->get(AMDGPU::S_ADD_I32), BaseReg)
973 .addReg(OffsetReg, RegState::Kill)
974 .addReg(FIReg)
975 .setOperandDead(3); // scc
976 return BaseReg;
977 }
978
979 TII->getAddNoCarry(*MBB, Ins, DL, BaseReg)
980 .addReg(OffsetReg, RegState::Kill)
981 .addReg(FIReg)
982 .addImm(0); // clamp bit
983
984 return BaseReg;
985}
986
988 int64_t Offset) const {
989 const SIInstrInfo *TII = ST.getInstrInfo();
990
991 switch (MI.getOpcode()) {
992 case AMDGPU::V_ADD_U32_e32:
993 case AMDGPU::V_ADD_CO_U32_e32: {
994 MachineOperand *FIOp = &MI.getOperand(2);
995 MachineOperand *ImmOp = &MI.getOperand(1);
996 if (!FIOp->isFI())
997 std::swap(FIOp, ImmOp);
998
999 if (!ImmOp->isImm()) {
1000 assert(Offset == 0);
1001 FIOp->ChangeToRegister(BaseReg, false);
1002 TII->legalizeOperandsVOP2(MI.getMF()->getRegInfo(), MI);
1003 return;
1004 }
1005
1006 int64_t TotalOffset = ImmOp->getImm() + Offset;
1007 if (TotalOffset == 0) {
1008 MI.setDesc(TII->get(AMDGPU::COPY));
1009 for (unsigned I = MI.getNumOperands() - 1; I != 1; --I)
1010 MI.removeOperand(I);
1011
1012 MI.getOperand(1).ChangeToRegister(BaseReg, false);
1013 return;
1014 }
1015
1016 ImmOp->setImm(TotalOffset);
1017
1018 MachineBasicBlock *MBB = MI.getParent();
1019 MachineFunction *MF = MBB->getParent();
1020 MachineRegisterInfo &MRI = MF->getRegInfo();
1021
1022 // FIXME: materializeFrameBaseRegister does not know the register class of
1023 // the uses of the frame index, and assumes SGPR for hasFlatScratchEnabled.
1024 // Emit a copy so we have a legal operand and hope the register coalescer
1025 // can clean it up.
1026 if (isSGPRReg(MRI, BaseReg)) {
1027 Register BaseRegVGPR =
1028 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1029 BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(AMDGPU::COPY), BaseRegVGPR)
1030 .addReg(BaseReg);
1031 MI.getOperand(2).ChangeToRegister(BaseRegVGPR, false);
1032 } else {
1033 MI.getOperand(2).ChangeToRegister(BaseReg, false);
1034 }
1035 return;
1036 }
1037 case AMDGPU::V_ADD_U32_e64:
1038 case AMDGPU::V_ADD_CO_U32_e64: {
1039 int Src0Idx = MI.getNumExplicitDefs();
1040 MachineOperand *FIOp = &MI.getOperand(Src0Idx);
1041 MachineOperand *ImmOp = &MI.getOperand(Src0Idx + 1);
1042 if (!FIOp->isFI())
1043 std::swap(FIOp, ImmOp);
1044
1045 if (!ImmOp->isImm()) {
1046 FIOp->ChangeToRegister(BaseReg, false);
1047 TII->legalizeOperandsVOP3(MI.getMF()->getRegInfo(), MI);
1048 return;
1049 }
1050
1051 int64_t TotalOffset = ImmOp->getImm() + Offset;
1052 if (TotalOffset == 0) {
1053 MI.setDesc(TII->get(AMDGPU::COPY));
1054
1055 for (unsigned I = MI.getNumOperands() - 1; I != 1; --I)
1056 MI.removeOperand(I);
1057
1058 MI.getOperand(1).ChangeToRegister(BaseReg, false);
1059 } else {
1060 FIOp->ChangeToRegister(BaseReg, false);
1061 ImmOp->setImm(TotalOffset);
1062 }
1063
1064 return;
1065 }
1066 default:
1067 break;
1068 }
1069
1070 bool IsFlat = TII->isFLATScratch(MI);
1071
1072#ifndef NDEBUG
1073 // FIXME: Is it possible to be storing a frame index to itself?
1074 bool SeenFI = false;
1075 for (const MachineOperand &MO: MI.operands()) {
1076 if (MO.isFI()) {
1077 if (SeenFI)
1078 llvm_unreachable("should not see multiple frame indices");
1079
1080 SeenFI = true;
1081 }
1082 }
1083#endif
1084
1085 MachineOperand *FIOp =
1086 TII->getNamedOperand(MI, IsFlat ? AMDGPU::OpName::saddr
1087 : AMDGPU::OpName::vaddr);
1088
1089 MachineOperand *OffsetOp = TII->getNamedOperand(MI, AMDGPU::OpName::offset);
1090 int64_t NewOffset = OffsetOp->getImm() + Offset;
1091
1092 assert(FIOp && FIOp->isFI() && "frame index must be address operand");
1093 assert(TII->isMUBUF(MI) || TII->isFLATScratch(MI));
1094
1095 if (IsFlat) {
1096 assert(TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
1098 "offset should be legal");
1099 FIOp->ChangeToRegister(BaseReg, false);
1100 OffsetOp->setImm(NewOffset);
1101 return;
1102 }
1103
1104#ifndef NDEBUG
1105 MachineOperand *SOffset = TII->getNamedOperand(MI, AMDGPU::OpName::soffset);
1106 assert(SOffset->isImm() && SOffset->getImm() == 0);
1107#endif
1108
1109 assert(TII->isLegalMUBUFImmOffset(NewOffset) && "offset should be legal");
1110
1111 FIOp->ChangeToRegister(BaseReg, false);
1112 OffsetOp->setImm(NewOffset);
1113}
1114
1116 Register BaseReg,
1117 int64_t Offset) const {
1118
1119 switch (MI->getOpcode()) {
1120 case AMDGPU::V_ADD_U32_e32:
1121 case AMDGPU::V_ADD_CO_U32_e32:
1122 return true;
1123 case AMDGPU::V_ADD_U32_e64:
1124 case AMDGPU::V_ADD_CO_U32_e64:
1125 return ST.hasVOP3Literal() || AMDGPU::isInlinableIntLiteral(Offset);
1126 default:
1127 break;
1128 }
1129
1131 return false;
1132
1133 int64_t NewOffset = Offset + getScratchInstrOffset(MI);
1134
1135 const SIInstrInfo *TII = ST.getInstrInfo();
1137 return TII->isLegalMUBUFImmOffset(NewOffset);
1138
1139 return TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
1141}
1142
1143const TargetRegisterClass *
1145 // This is inaccurate. It depends on the instruction and address space. The
1146 // only place where we should hit this is for dealing with frame indexes /
1147 // private accesses, so this is correct in that case.
1148 return &AMDGPU::VGPR_32RegClass;
1149}
1150
1151const TargetRegisterClass *
1153 return RC == &AMDGPU::SCC_CLASSRegClass ? &AMDGPU::SReg_32RegClass : RC;
1154}
1155
1157 const SIInstrInfo *TII) {
1158
1159 unsigned Op = MI.getOpcode();
1160 switch (Op) {
1161 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
1162 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
1163 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE:
1164 // FIXME: This assumes the mask is statically known and not computed at
1165 // runtime. However, some ABIs may want to compute the mask dynamically and
1166 // this will need to be updated.
1167 return llvm::popcount(
1168 (uint64_t)TII->getNamedOperand(MI, AMDGPU::OpName::mask)->getImm());
1169 case AMDGPU::SI_SPILL_S1024_SAVE:
1170 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
1171 case AMDGPU::SI_SPILL_S1024_RESTORE:
1172 case AMDGPU::SI_SPILL_V1024_SAVE:
1173 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
1174 case AMDGPU::SI_SPILL_V1024_RESTORE:
1175 case AMDGPU::SI_SPILL_A1024_SAVE:
1176 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
1177 case AMDGPU::SI_SPILL_A1024_RESTORE:
1178 case AMDGPU::SI_SPILL_AV1024_SAVE:
1179 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
1180 case AMDGPU::SI_SPILL_AV1024_RESTORE:
1181 return 32;
1182 case AMDGPU::SI_SPILL_S512_SAVE:
1183 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
1184 case AMDGPU::SI_SPILL_S512_RESTORE:
1185 case AMDGPU::SI_SPILL_V512_SAVE:
1186 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
1187 case AMDGPU::SI_SPILL_V512_RESTORE:
1188 case AMDGPU::SI_SPILL_A512_SAVE:
1189 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
1190 case AMDGPU::SI_SPILL_A512_RESTORE:
1191 case AMDGPU::SI_SPILL_AV512_SAVE:
1192 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
1193 case AMDGPU::SI_SPILL_AV512_RESTORE:
1194 return 16;
1195 case AMDGPU::SI_SPILL_S384_SAVE:
1196 case AMDGPU::SI_SPILL_S384_RESTORE:
1197 case AMDGPU::SI_SPILL_V384_SAVE:
1198 case AMDGPU::SI_SPILL_V384_RESTORE:
1199 case AMDGPU::SI_SPILL_A384_SAVE:
1200 case AMDGPU::SI_SPILL_A384_RESTORE:
1201 case AMDGPU::SI_SPILL_AV384_SAVE:
1202 case AMDGPU::SI_SPILL_AV384_RESTORE:
1203 return 12;
1204 case AMDGPU::SI_SPILL_S352_SAVE:
1205 case AMDGPU::SI_SPILL_S352_RESTORE:
1206 case AMDGPU::SI_SPILL_V352_SAVE:
1207 case AMDGPU::SI_SPILL_V352_RESTORE:
1208 case AMDGPU::SI_SPILL_A352_SAVE:
1209 case AMDGPU::SI_SPILL_A352_RESTORE:
1210 case AMDGPU::SI_SPILL_AV352_SAVE:
1211 case AMDGPU::SI_SPILL_AV352_RESTORE:
1212 return 11;
1213 case AMDGPU::SI_SPILL_S320_SAVE:
1214 case AMDGPU::SI_SPILL_S320_RESTORE:
1215 case AMDGPU::SI_SPILL_V320_SAVE:
1216 case AMDGPU::SI_SPILL_V320_RESTORE:
1217 case AMDGPU::SI_SPILL_A320_SAVE:
1218 case AMDGPU::SI_SPILL_A320_RESTORE:
1219 case AMDGPU::SI_SPILL_AV320_SAVE:
1220 case AMDGPU::SI_SPILL_AV320_RESTORE:
1221 return 10;
1222 case AMDGPU::SI_SPILL_S288_SAVE:
1223 case AMDGPU::SI_SPILL_S288_RESTORE:
1224 case AMDGPU::SI_SPILL_V288_SAVE:
1225 case AMDGPU::SI_SPILL_V288_RESTORE:
1226 case AMDGPU::SI_SPILL_A288_SAVE:
1227 case AMDGPU::SI_SPILL_A288_RESTORE:
1228 case AMDGPU::SI_SPILL_AV288_SAVE:
1229 case AMDGPU::SI_SPILL_AV288_RESTORE:
1230 return 9;
1231 case AMDGPU::SI_SPILL_S256_SAVE:
1232 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
1233 case AMDGPU::SI_SPILL_S256_RESTORE:
1234 case AMDGPU::SI_SPILL_V256_SAVE:
1235 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
1236 case AMDGPU::SI_SPILL_V256_RESTORE:
1237 case AMDGPU::SI_SPILL_A256_SAVE:
1238 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
1239 case AMDGPU::SI_SPILL_A256_RESTORE:
1240 case AMDGPU::SI_SPILL_AV256_SAVE:
1241 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
1242 case AMDGPU::SI_SPILL_AV256_RESTORE:
1243 return 8;
1244 case AMDGPU::SI_SPILL_S224_SAVE:
1245 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
1246 case AMDGPU::SI_SPILL_S224_RESTORE:
1247 case AMDGPU::SI_SPILL_V224_SAVE:
1248 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
1249 case AMDGPU::SI_SPILL_V224_RESTORE:
1250 case AMDGPU::SI_SPILL_A224_SAVE:
1251 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
1252 case AMDGPU::SI_SPILL_A224_RESTORE:
1253 case AMDGPU::SI_SPILL_AV224_SAVE:
1254 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
1255 case AMDGPU::SI_SPILL_AV224_RESTORE:
1256 return 7;
1257 case AMDGPU::SI_SPILL_S192_SAVE:
1258 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
1259 case AMDGPU::SI_SPILL_S192_RESTORE:
1260 case AMDGPU::SI_SPILL_V192_SAVE:
1261 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
1262 case AMDGPU::SI_SPILL_V192_RESTORE:
1263 case AMDGPU::SI_SPILL_A192_SAVE:
1264 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
1265 case AMDGPU::SI_SPILL_A192_RESTORE:
1266 case AMDGPU::SI_SPILL_AV192_SAVE:
1267 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
1268 case AMDGPU::SI_SPILL_AV192_RESTORE:
1269 return 6;
1270 case AMDGPU::SI_SPILL_S160_SAVE:
1271 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
1272 case AMDGPU::SI_SPILL_S160_RESTORE:
1273 case AMDGPU::SI_SPILL_V160_SAVE:
1274 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
1275 case AMDGPU::SI_SPILL_V160_RESTORE:
1276 case AMDGPU::SI_SPILL_A160_SAVE:
1277 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
1278 case AMDGPU::SI_SPILL_A160_RESTORE:
1279 case AMDGPU::SI_SPILL_AV160_SAVE:
1280 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
1281 case AMDGPU::SI_SPILL_AV160_RESTORE:
1282 return 5;
1283 case AMDGPU::SI_SPILL_S128_SAVE:
1284 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
1285 case AMDGPU::SI_SPILL_S128_RESTORE:
1286 case AMDGPU::SI_SPILL_V128_SAVE:
1287 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
1288 case AMDGPU::SI_SPILL_V128_RESTORE:
1289 case AMDGPU::SI_SPILL_A128_SAVE:
1290 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
1291 case AMDGPU::SI_SPILL_A128_RESTORE:
1292 case AMDGPU::SI_SPILL_AV128_SAVE:
1293 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
1294 case AMDGPU::SI_SPILL_AV128_RESTORE:
1295 return 4;
1296 case AMDGPU::SI_SPILL_S96_SAVE:
1297 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
1298 case AMDGPU::SI_SPILL_S96_RESTORE:
1299 case AMDGPU::SI_SPILL_V96_SAVE:
1300 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
1301 case AMDGPU::SI_SPILL_V96_RESTORE:
1302 case AMDGPU::SI_SPILL_A96_SAVE:
1303 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
1304 case AMDGPU::SI_SPILL_A96_RESTORE:
1305 case AMDGPU::SI_SPILL_AV96_SAVE:
1306 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
1307 case AMDGPU::SI_SPILL_AV96_RESTORE:
1308 return 3;
1309 case AMDGPU::SI_SPILL_S64_SAVE:
1310 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
1311 case AMDGPU::SI_SPILL_S64_RESTORE:
1312 case AMDGPU::SI_SPILL_V64_SAVE:
1313 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
1314 case AMDGPU::SI_SPILL_V64_RESTORE:
1315 case AMDGPU::SI_SPILL_A64_SAVE:
1316 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
1317 case AMDGPU::SI_SPILL_A64_RESTORE:
1318 case AMDGPU::SI_SPILL_AV64_SAVE:
1319 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
1320 case AMDGPU::SI_SPILL_AV64_RESTORE:
1321 return 2;
1322 case AMDGPU::SI_SPILL_S32_SAVE:
1323 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
1324 case AMDGPU::SI_SPILL_S32_RESTORE:
1325 case AMDGPU::SI_SPILL_V32_SAVE:
1326 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
1327 case AMDGPU::SI_SPILL_V32_RESTORE:
1328 case AMDGPU::SI_SPILL_A32_SAVE:
1329 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
1330 case AMDGPU::SI_SPILL_A32_RESTORE:
1331 case AMDGPU::SI_SPILL_AV32_SAVE:
1332 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
1333 case AMDGPU::SI_SPILL_AV32_RESTORE:
1334 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
1335 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1336 case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1337 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
1338 case AMDGPU::SI_SPILL_V16_SAVE:
1339 case AMDGPU::SI_SPILL_V16_RESTORE:
1340 return 1;
1341 default: llvm_unreachable("Invalid spill opcode");
1342 }
1343}
1344
1345static int getOffsetMUBUFStore(unsigned Opc) {
1346 switch (Opc) {
1347 case AMDGPU::BUFFER_STORE_DWORD_OFFEN:
1348 return AMDGPU::BUFFER_STORE_DWORD_OFFSET;
1349 case AMDGPU::BUFFER_STORE_BYTE_OFFEN:
1350 return AMDGPU::BUFFER_STORE_BYTE_OFFSET;
1351 case AMDGPU::BUFFER_STORE_SHORT_OFFEN:
1352 return AMDGPU::BUFFER_STORE_SHORT_OFFSET;
1353 case AMDGPU::BUFFER_STORE_DWORDX2_OFFEN:
1354 return AMDGPU::BUFFER_STORE_DWORDX2_OFFSET;
1355 case AMDGPU::BUFFER_STORE_DWORDX3_OFFEN:
1356 return AMDGPU::BUFFER_STORE_DWORDX3_OFFSET;
1357 case AMDGPU::BUFFER_STORE_DWORDX4_OFFEN:
1358 return AMDGPU::BUFFER_STORE_DWORDX4_OFFSET;
1359 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN:
1360 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET;
1361 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN:
1362 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET;
1363 default:
1364 return -1;
1365 }
1366}
1367
1368static int getOffsetMUBUFLoad(unsigned Opc) {
1369 switch (Opc) {
1370 case AMDGPU::BUFFER_LOAD_DWORD_OFFEN:
1371 return AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
1372 case AMDGPU::BUFFER_LOAD_UBYTE_OFFEN:
1373 return AMDGPU::BUFFER_LOAD_UBYTE_OFFSET;
1374 case AMDGPU::BUFFER_LOAD_SBYTE_OFFEN:
1375 return AMDGPU::BUFFER_LOAD_SBYTE_OFFSET;
1376 case AMDGPU::BUFFER_LOAD_USHORT_OFFEN:
1377 return AMDGPU::BUFFER_LOAD_USHORT_OFFSET;
1378 case AMDGPU::BUFFER_LOAD_SSHORT_OFFEN:
1379 return AMDGPU::BUFFER_LOAD_SSHORT_OFFSET;
1380 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN:
1381 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET;
1382 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN:
1383 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET;
1384 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN:
1385 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET;
1386 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN:
1387 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET;
1388 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN:
1389 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET;
1390 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN:
1391 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET;
1392 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN:
1393 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET;
1394 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN:
1395 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET;
1396 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN:
1397 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET;
1398 default:
1399 return -1;
1400 }
1401}
1402
1403static int getOffenMUBUFStore(unsigned Opc) {
1404 switch (Opc) {
1405 case AMDGPU::BUFFER_STORE_DWORD_OFFSET:
1406 return AMDGPU::BUFFER_STORE_DWORD_OFFEN;
1407 case AMDGPU::BUFFER_STORE_BYTE_OFFSET:
1408 return AMDGPU::BUFFER_STORE_BYTE_OFFEN;
1409 case AMDGPU::BUFFER_STORE_SHORT_OFFSET:
1410 return AMDGPU::BUFFER_STORE_SHORT_OFFEN;
1411 case AMDGPU::BUFFER_STORE_DWORDX2_OFFSET:
1412 return AMDGPU::BUFFER_STORE_DWORDX2_OFFEN;
1413 case AMDGPU::BUFFER_STORE_DWORDX3_OFFSET:
1414 return AMDGPU::BUFFER_STORE_DWORDX3_OFFEN;
1415 case AMDGPU::BUFFER_STORE_DWORDX4_OFFSET:
1416 return AMDGPU::BUFFER_STORE_DWORDX4_OFFEN;
1417 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET:
1418 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN;
1419 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET:
1420 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN;
1421 default:
1422 return -1;
1423 }
1424}
1425
1426static int getOffenMUBUFLoad(unsigned Opc) {
1427 switch (Opc) {
1428 case AMDGPU::BUFFER_LOAD_DWORD_OFFSET:
1429 return AMDGPU::BUFFER_LOAD_DWORD_OFFEN;
1430 case AMDGPU::BUFFER_LOAD_UBYTE_OFFSET:
1431 return AMDGPU::BUFFER_LOAD_UBYTE_OFFEN;
1432 case AMDGPU::BUFFER_LOAD_SBYTE_OFFSET:
1433 return AMDGPU::BUFFER_LOAD_SBYTE_OFFEN;
1434 case AMDGPU::BUFFER_LOAD_USHORT_OFFSET:
1435 return AMDGPU::BUFFER_LOAD_USHORT_OFFEN;
1436 case AMDGPU::BUFFER_LOAD_SSHORT_OFFSET:
1437 return AMDGPU::BUFFER_LOAD_SSHORT_OFFEN;
1438 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET:
1439 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN;
1440 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET:
1441 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN;
1442 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET:
1443 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN;
1444 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET:
1445 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN;
1446 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET:
1447 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN;
1448 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET:
1449 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN;
1450 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET:
1451 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN;
1452 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET:
1453 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN;
1454 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET:
1455 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN;
1456 default:
1457 return -1;
1458 }
1459}
1460
1463 MachineBasicBlock::iterator MI, int Index, unsigned Lane,
1464 unsigned ValueReg, bool IsKill, bool NeedsCFI) {
1465 MachineFunction *MF = MBB.getParent();
1467 const SIInstrInfo *TII = ST.getInstrInfo();
1468 const SIFrameLowering *TFL = ST.getFrameLowering();
1469
1470 MCPhysReg Reg = MFI->getVGPRToAGPRSpill(Index, Lane);
1471
1472 if (Reg == AMDGPU::NoRegister)
1473 return MachineInstrBuilder();
1474
1475 bool IsStore = MI->mayStore();
1476 MachineRegisterInfo &MRI = MF->getRegInfo();
1477 auto *TRI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
1478
1479 unsigned Dst = IsStore ? Reg : ValueReg;
1480 unsigned Src = IsStore ? ValueReg : Reg;
1481 bool IsVGPR = TRI->isVGPR(MRI, Reg);
1482 const DebugLoc &DL = MI->getDebugLoc();
1483 if (IsVGPR == TRI->isVGPR(MRI, ValueReg)) {
1484 // Spiller during regalloc may restore a spilled register to its superclass.
1485 // It could result in AGPR spills restored to VGPRs or the other way around,
1486 // making the src and dst with identical regclasses at this point. It just
1487 // needs a copy in such cases.
1488 auto CopyMIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::COPY), Dst)
1489 .addReg(Src, getKillRegState(IsKill));
1491 if (NeedsCFI)
1492 TFL->buildCFIForVRegToVRegSpill(MBB, MI, DL, Src, Dst);
1493 return CopyMIB;
1494 }
1495 unsigned Opc = (IsStore ^ IsVGPR) ? AMDGPU::V_ACCVGPR_WRITE_B32_e64
1496 : AMDGPU::V_ACCVGPR_READ_B32_e64;
1497
1498 auto MIB = BuildMI(MBB, MI, DL, TII->get(Opc), Dst)
1499 .addReg(Src, getKillRegState(IsKill));
1501 if (NeedsCFI)
1502 TFL->buildCFIForVRegToVRegSpill(MBB, MI, DL, Src, Dst);
1503 return MIB;
1504}
1505
1506// This differs from buildSpillLoadStore by only scavenging a VGPR. It does not
1507// need to handle the case where an SGPR may need to be spilled while spilling.
1509 MachineFrameInfo &MFI,
1511 int Index,
1512 int64_t Offset) {
1513 const SIInstrInfo *TII = ST.getInstrInfo();
1514 MachineBasicBlock *MBB = MI->getParent();
1515 const DebugLoc &DL = MI->getDebugLoc();
1516 bool IsStore = MI->mayStore();
1517
1518 unsigned Opc = MI->getOpcode();
1519 int LoadStoreOp = IsStore ?
1521 if (LoadStoreOp == -1)
1522 return false;
1523
1524 const MachineOperand *Reg = TII->getNamedOperand(*MI, AMDGPU::OpName::vdata);
1525 if (spillVGPRtoAGPR(ST, *MBB, MI, Index, 0, Reg->getReg(), false, false)
1526 .getInstr())
1527 return true;
1528
1529 MachineInstrBuilder NewMI =
1530 BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp))
1531 .add(*Reg)
1532 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::srsrc))
1533 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::soffset))
1534 .addImm(Offset)
1535 .addImm(0) // cpol
1536 .addImm(0) // swz
1537 .cloneMemRefs(*MI);
1538
1539 const MachineOperand *VDataIn = TII->getNamedOperand(*MI,
1540 AMDGPU::OpName::vdata_in);
1541 if (VDataIn)
1542 NewMI.add(*VDataIn);
1543 return true;
1544}
1545
1547 unsigned LoadStoreOp,
1548 unsigned EltSize) {
1549 bool IsStore = TII->get(LoadStoreOp).mayStore();
1550 bool HasVAddr = AMDGPU::hasNamedOperand(LoadStoreOp, AMDGPU::OpName::vaddr);
1551 bool UseST =
1552 !HasVAddr && !AMDGPU::hasNamedOperand(LoadStoreOp, AMDGPU::OpName::saddr);
1553
1554 // Handle block load/store first.
1555 if (TII->isBlockLoadStore(LoadStoreOp))
1556 return LoadStoreOp;
1557
1558 switch (EltSize) {
1559 case 4:
1560 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
1561 : AMDGPU::SCRATCH_LOAD_DWORD_SADDR;
1562 break;
1563 case 8:
1564 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX2_SADDR
1565 : AMDGPU::SCRATCH_LOAD_DWORDX2_SADDR;
1566 break;
1567 case 12:
1568 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX3_SADDR
1569 : AMDGPU::SCRATCH_LOAD_DWORDX3_SADDR;
1570 break;
1571 case 16:
1572 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX4_SADDR
1573 : AMDGPU::SCRATCH_LOAD_DWORDX4_SADDR;
1574 break;
1575 default:
1576 llvm_unreachable("Unexpected spill load/store size!");
1577 }
1578
1579 if (HasVAddr)
1580 LoadStoreOp = AMDGPU::getFlatScratchInstSVfromSS(LoadStoreOp);
1581 else if (UseST)
1582 LoadStoreOp = AMDGPU::getFlatScratchInstSTfromSS(LoadStoreOp);
1583
1584 return LoadStoreOp;
1585}
1586
1589 unsigned LoadStoreOp, int Index, Register ValueReg, bool IsKill,
1590 MCRegister ScratchOffsetReg, int64_t InstOffset, MachineMemOperand *MMO,
1591 RegScavenger *RS, LiveRegUnits *LiveUnits, bool NeedsCFI) const {
1592 assert((!RS || !LiveUnits) && "Only RS or LiveUnits can be set but not both");
1593
1594 MachineFunction *MF = MBB.getParent();
1595 const SIInstrInfo *TII = ST.getInstrInfo();
1596 const MachineFrameInfo &MFI = MF->getFrameInfo();
1597 const SIFrameLowering *TFL = ST.getFrameLowering();
1598 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
1599
1600 const MCInstrDesc *Desc = &TII->get(LoadStoreOp);
1601 bool IsStore = Desc->mayStore();
1602 bool IsFlat = TII->isFLATScratch(LoadStoreOp);
1603 bool IsBlock = TII->isBlockLoadStore(LoadStoreOp);
1604
1605 bool CanClobberSCC = false;
1606 bool Scavenged = false;
1607 MCRegister SOffset = ScratchOffsetReg;
1608
1609 const TargetRegisterClass *RC = getRegClassForReg(MF->getRegInfo(), ValueReg);
1610 // On gfx90a+ AGPR is a regular VGPR acceptable for loads and stores.
1611 const bool IsAGPR = !ST.hasGFX90AInsts() && isAGPRClass(RC);
1612 unsigned RegWidth = AMDGPU::getRegBitWidth(*RC) / 8;
1613
1614 // On targets with register tuple alignment requirements,
1615 // for unaligned tuples, spill the first sub-reg as a 32-bit spill,
1616 // and spill the rest as a regular aligned tuple.
1617 // eg: SPILL_V224 $vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7
1618 // will be spilt as:
1619 // SPILL_SCRATCH_DWORD $vgpr1
1620 // SPILL_SCRATCH_DWORDx4 $vgpr2_vgpr3_vgpr4_vgpr5
1621 // SPILL_SCRATCH_DWORDx2 $vgpr6_vgpr7
1622 bool IsRegMisaligned = false;
1623 if (!IsBlock && !IsAGPR && RegWidth > 4 && IsFlat) {
1624 unsigned SpillOpcode =
1625 getFlatScratchSpillOpcode(TII, LoadStoreOp, std::min(RegWidth, 16u));
1626 int VDataIdx =
1627 IsStore ? AMDGPU::getNamedOperandIdx(SpillOpcode, AMDGPU::OpName::vdata)
1628 : 0; // Restore Ops have data reg as the first (output) operand.
1629 const TargetRegisterClass *ExpectedRC =
1630 TII->getRegClass(TII->get(SpillOpcode), VDataIdx);
1631 if (!ExpectedRC->contains(ValueReg)) {
1632 unsigned NumRegs = std::min(AMDGPU::getRegBitWidth(*ExpectedRC) / 4, 4u);
1633 unsigned SubIdx = getSubRegFromChannel(0, NumRegs);
1634 const TargetRegisterClass *MatchRC =
1635 getMatchingSuperRegClass(RC, ExpectedRC, SubIdx);
1636 if (!MatchRC || !MatchRC->contains(ValueReg))
1637 IsRegMisaligned = true;
1638 }
1639 }
1640 // The first sub-register will be spilled as a 32-bit value
1641 if (IsRegMisaligned)
1642 RegWidth -= 4u;
1643 // Always use 4 byte operations for AGPRs because we need to scavenge
1644 // a temporary VGPR.
1645 // If we're using a block operation, the element should be the whole block.
1646 unsigned EltSize = IsBlock ? RegWidth
1647 : (IsFlat && !IsAGPR) ? std::min(RegWidth, 16u)
1648 : 4u;
1649 unsigned NumSubRegs = RegWidth / EltSize;
1650 unsigned Size = NumSubRegs * EltSize;
1651 unsigned RemSize = RegWidth - Size;
1652 unsigned NumRemSubRegs = RemSize ? 1 : 0;
1653 // An additional sub-register is needed to spill the misaligned component.
1654 if (IsRegMisaligned)
1655 NumSubRegs += 1;
1656 int64_t Offset = InstOffset + MFI.getObjectOffset(Index);
1657 int64_t MaterializedOffset = Offset;
1658
1659 // Maxoffset is the starting offset for the last chunk to be spilled.
1660 // In case of non-zero remainder element, max offset will be the
1661 // last address(offset + Size) after spilling all the EltSize chunks.
1662 int64_t MaxOffset = Offset + Size - (RemSize ? 0 : EltSize);
1663 int64_t ScratchOffsetRegDelta = 0;
1664 int64_t AdditionalCFIOffset = 0;
1665
1666 if (IsFlat && EltSize > 4) {
1667 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1668 Desc = &TII->get(LoadStoreOp);
1669 }
1670
1671 Align Alignment = MFI.getObjectAlign(Index);
1672 const MachinePointerInfo &BasePtrInfo = MMO->getPointerInfo();
1673
1674 assert((IsFlat || ((Offset % EltSize) == 0)) &&
1675 "unexpected VGPR spill offset");
1676
1677 // Track a VGPR to use for a constant offset we need to materialize.
1678 Register TmpOffsetVGPR;
1679
1680 // Track a VGPR to use as an intermediate value.
1681 Register TmpIntermediateVGPR;
1682 bool UseVGPROffset = false;
1683
1684 // Materialize a VGPR offset required for the given SGPR/VGPR/Immediate
1685 // combination.
1686 auto MaterializeVOffset = [&](Register SGPRBase, Register TmpVGPR,
1687 int64_t VOffset) {
1688 // We are using a VGPR offset
1689 if (IsFlat && SGPRBase) {
1690 // We only have 1 VGPR offset, or 1 SGPR offset. We don't have a free
1691 // SGPR, so perform the add as vector.
1692 // We don't need a base SGPR in the kernel.
1693
1694 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) >= 2) {
1695 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e64), TmpVGPR)
1696 .addReg(SGPRBase)
1697 .addImm(VOffset)
1698 .addImm(0); // clamp
1699 } else {
1700 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
1701 .addReg(SGPRBase);
1702 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e32), TmpVGPR)
1703 .addImm(VOffset)
1704 .addReg(TmpOffsetVGPR);
1705 }
1706 } else {
1707 assert(TmpOffsetVGPR);
1708 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
1709 .addImm(VOffset);
1710 }
1711 };
1712
1713 bool IsOffsetLegal =
1714 IsFlat ? TII->isLegalFLATOffset(MaxOffset, AMDGPUAS::PRIVATE_ADDRESS,
1716 : TII->isLegalMUBUFImmOffset(MaxOffset);
1717 if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
1718 SOffset = MCRegister();
1719
1720 // We don't have access to the register scavenger if this function is called
1721 // during PEI::scavengeFrameVirtualRegs() so use LiveUnits in this case.
1722 // TODO: Clobbering SCC is not necessary for scratch instructions in the
1723 // entry.
1724 if (RS) {
1725 SOffset = RS->scavengeRegisterBackwards(AMDGPU::SGPR_32RegClass, MI, false, 0, false);
1726
1727 // Piggy back on the liveness scan we just did see if SCC is dead.
1728 CanClobberSCC = !RS->isRegUsed(AMDGPU::SCC);
1729 } else if (LiveUnits) {
1730 CanClobberSCC = LiveUnits->available(AMDGPU::SCC);
1731 for (MCRegister Reg : AMDGPU::SGPR_32RegClass) {
1732 if (LiveUnits->available(Reg) && !MF->getRegInfo().isReserved(Reg)) {
1733 SOffset = Reg;
1734 break;
1735 }
1736 }
1737 }
1738
1739 if (ScratchOffsetReg != AMDGPU::NoRegister && !CanClobberSCC)
1740 SOffset = Register();
1741
1742 if (!SOffset) {
1743 UseVGPROffset = true;
1744
1745 if (RS) {
1746 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false, 0);
1747 } else {
1748 assert(LiveUnits);
1749 for (MCRegister Reg : AMDGPU::VGPR_32RegClass) {
1750 if (LiveUnits->available(Reg) && !MF->getRegInfo().isReserved(Reg)) {
1751 TmpOffsetVGPR = Reg;
1752 break;
1753 }
1754 }
1755 }
1756
1757 assert(TmpOffsetVGPR);
1758 } else if (!SOffset && CanClobberSCC) {
1759 // There are no free SGPRs, and since we are in the process of spilling
1760 // VGPRs too. Since we need a VGPR in order to spill SGPRs (this is true
1761 // on SI/CI and on VI it is true until we implement spilling using scalar
1762 // stores), we have no way to free up an SGPR. Our solution here is to
1763 // add the offset directly to the ScratchOffset or StackPtrOffset
1764 // register, and then subtract the offset after the spill to return the
1765 // register to it's original value.
1766
1767 // TODO: If we don't have to do an emergency stack slot spill, converting
1768 // to use the VGPR offset is fewer instructions.
1769 if (!ScratchOffsetReg)
1770 ScratchOffsetReg = FuncInfo->getStackPtrOffsetReg();
1771 SOffset = ScratchOffsetReg;
1772 ScratchOffsetRegDelta = Offset;
1773 } else {
1774 Scavenged = true;
1775 }
1776
1777 AdditionalCFIOffset = Offset;
1778 // We currently only support spilling VGPRs to EltSize boundaries, meaning
1779 // we can simplify the adjustment of Offset here to just scale with
1780 // WavefrontSize.
1781 if (!IsFlat && !UseVGPROffset)
1782 Offset *= ST.getWavefrontSize();
1783
1784 if (!UseVGPROffset && !SOffset)
1785 report_fatal_error("could not scavenge SGPR to spill in entry function");
1786
1787 if (UseVGPROffset) {
1788 // We are using a VGPR offset
1789 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, Offset);
1790 } else if (ScratchOffsetReg == AMDGPU::NoRegister) {
1791 BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_MOV_B32), SOffset).addImm(Offset);
1792 } else {
1793 assert(Offset != 0);
1794 auto Add = BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), SOffset)
1795 .addReg(ScratchOffsetReg)
1796 .addImm(Offset);
1797 Add->getOperand(3).setIsDead(); // Mark SCC as dead.
1798 }
1799
1800 Offset = 0;
1801 }
1802
1803 if (IsFlat && SOffset == AMDGPU::NoRegister) {
1804 assert(AMDGPU::getNamedOperandIdx(LoadStoreOp, AMDGPU::OpName::vaddr) < 0
1805 && "Unexpected vaddr for flat scratch with a FI operand");
1806
1807 if (UseVGPROffset) {
1808 LoadStoreOp = AMDGPU::getFlatScratchInstSVfromSS(LoadStoreOp);
1809 } else {
1810 assert(ST.hasFlatScratchSTMode());
1811 assert(!TII->isBlockLoadStore(LoadStoreOp) && "Block ops don't have ST");
1812 LoadStoreOp = AMDGPU::getFlatScratchInstSTfromSS(LoadStoreOp);
1813 }
1814
1815 Desc = &TII->get(LoadStoreOp);
1816 }
1817
1818 // Save a copy of the original element size before its potentially changed for
1819 // misaligned tuples.
1820 unsigned OrigEltSize = EltSize;
1821 for (unsigned i = 0, e = NumSubRegs + NumRemSubRegs, RegOffset = 0; i != e;
1822 ++i, RegOffset += EltSize) {
1823 if (IsRegMisaligned) {
1824 if (i == 0) {
1825 // For misaligned register tuples, spill only the first sub-reg in the
1826 // first iteration.
1827 EltSize = 4u;
1828 } else {
1829 // The misaligned register was spilt. Now the rest of the tuple is
1830 // properly aligned.
1831 IsRegMisaligned = false;
1832 EltSize = OrigEltSize;
1833 }
1834 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1835 }
1836 if (i == NumSubRegs) {
1837 EltSize = RemSize;
1838 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1839 }
1840 Desc = &TII->get(LoadStoreOp);
1841
1842 if (!IsFlat && UseVGPROffset) {
1843 int NewLoadStoreOp = IsStore ? getOffenMUBUFStore(LoadStoreOp)
1844 : getOffenMUBUFLoad(LoadStoreOp);
1845 Desc = &TII->get(NewLoadStoreOp);
1846 }
1847
1848 if (UseVGPROffset && TmpOffsetVGPR == TmpIntermediateVGPR) {
1849 // If we are spilling an AGPR beyond the range of the memory instruction
1850 // offset and need to use a VGPR offset, we ideally have at least 2
1851 // scratch VGPRs. If we don't have a second free VGPR without spilling,
1852 // recycle the VGPR used for the offset which requires resetting after
1853 // each subregister.
1854
1855 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, MaterializedOffset);
1856 }
1857
1858 unsigned NumRegs = EltSize / 4;
1859 Register SubReg = e == 1
1860 ? ValueReg
1861 : Register(getSubReg(ValueReg,
1862 getSubRegFromChannel(RegOffset / 4, NumRegs)));
1863
1864 RegState SOffsetRegState = {};
1865 RegState SrcDstRegState = getDefRegState(!IsStore);
1866 const bool IsLastSubReg = i + 1 == e;
1867 const bool IsFirstSubReg = i == 0;
1868 if (IsLastSubReg) {
1869 SOffsetRegState |= getKillRegState(Scavenged);
1870 // The last implicit use carries the "Kill" flag.
1871 SrcDstRegState |= getKillRegState(IsKill);
1872 }
1873
1874 // Make sure the whole register is defined if there are undef components by
1875 // adding an implicit def of the super-reg on the first instruction.
1876 bool NeedSuperRegDef = e > 1 && IsStore && IsFirstSubReg;
1877 bool NeedSuperRegImpOperand = e > 1;
1878
1879 // Remaining element size to spill into memory after some parts of it
1880 // spilled into either AGPRs or VGPRs.
1881 unsigned RemEltSize = EltSize;
1882
1883 // AGPRs to spill VGPRs and vice versa are allocated in a reverse order,
1884 // starting from the last lane. In case if a register cannot be completely
1885 // spilled into another register that will ensure its alignment does not
1886 // change. For targets with VGPR alignment requirement this is important
1887 // in case of flat scratch usage as we might get a scratch_load or
1888 // scratch_store of an unaligned register otherwise.
1889 for (int LaneS = (RegOffset + EltSize) / 4 - 1, Lane = LaneS,
1890 LaneE = RegOffset / 4;
1891 Lane >= LaneE; --Lane) {
1892 bool IsSubReg = e > 1 || EltSize > 4;
1893 Register Sub = IsSubReg
1894 ? Register(getSubReg(ValueReg, getSubRegFromChannel(Lane)))
1895 : ValueReg;
1896 auto MIB =
1897 spillVGPRtoAGPR(ST, MBB, MI, Index, Lane, Sub, IsKill, NeedsCFI);
1898 if (!MIB.getInstr())
1899 break;
1900 if (NeedSuperRegDef || (IsSubReg && IsStore && Lane == LaneS && IsFirstSubReg)) {
1901 MIB.addReg(ValueReg, RegState::ImplicitDefine);
1902 NeedSuperRegDef = false;
1903 }
1904 if ((IsSubReg || NeedSuperRegImpOperand) && (IsFirstSubReg || IsLastSubReg)) {
1905 NeedSuperRegImpOperand = true;
1906 RegState State = SrcDstRegState;
1907 if (!IsLastSubReg || (Lane != LaneE))
1908 State &= ~RegState::Kill;
1909 if (!IsFirstSubReg || (Lane != LaneS))
1910 State &= ~RegState::Define;
1911 MIB.addReg(ValueReg, RegState::Implicit | State);
1912 }
1913 RemEltSize -= 4;
1914 }
1915
1916 if (!RemEltSize) // Fully spilled into AGPRs.
1917 continue;
1918
1919 if (RemEltSize != EltSize) { // Partially spilled to AGPRs
1920 assert(IsFlat && EltSize > 4);
1921
1922 unsigned NumRegs = RemEltSize / 4;
1923 SubReg = Register(getSubReg(ValueReg,
1924 getSubRegFromChannel(RegOffset / 4, NumRegs)));
1925 unsigned Opc = getFlatScratchSpillOpcode(TII, LoadStoreOp, RemEltSize);
1926 Desc = &TII->get(Opc);
1927 }
1928
1929 unsigned FinalReg = SubReg;
1930
1931 if (IsAGPR) {
1932 assert(EltSize == 4);
1933
1934 if (!TmpIntermediateVGPR) {
1935 TmpIntermediateVGPR = FuncInfo->getVGPRForAGPRCopy();
1936 assert(MF->getRegInfo().isReserved(TmpIntermediateVGPR));
1937 }
1938 if (IsStore) {
1939 auto AccRead = BuildMI(MBB, MI, DL,
1940 TII->get(AMDGPU::V_ACCVGPR_READ_B32_e64),
1941 TmpIntermediateVGPR)
1942 .addReg(SubReg, getKillRegState(IsKill));
1943 if (NeedSuperRegDef)
1944 AccRead.addReg(ValueReg, RegState::ImplicitDefine);
1945 if (NeedSuperRegImpOperand && (IsFirstSubReg || IsLastSubReg))
1946 AccRead.addReg(ValueReg, RegState::Implicit);
1948 }
1949 SubReg = TmpIntermediateVGPR;
1950 } else if (UseVGPROffset) {
1951 if (!TmpOffsetVGPR) {
1952 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
1953 MI, false, 0);
1954 RS->setRegUsed(TmpOffsetVGPR);
1955 }
1956 }
1957
1958 Register FinalValueReg = ValueReg;
1959 if (LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_SADDR ||
1960 LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_ST) {
1961 // If we are loading 16-bit value with SRAMECC endabled we need a temp
1962 // 32-bit VGPR to load and extract 16-bits into the final register.
1963 ValueReg =
1964 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false, 0);
1965 SubReg = ValueReg;
1966 IsKill = false;
1967 }
1968
1969 // Create the MMO, additional set the NonVolatile flag as scratch memory
1970 // used for spills will not be used outside the thread.
1971 MachinePointerInfo PInfo = BasePtrInfo.getWithOffset(RegOffset);
1973 PInfo, MMO->getFlags() | MOThreadPrivate, RemEltSize,
1974 commonAlignment(Alignment, RegOffset));
1975
1976 auto MIB =
1977 BuildMI(MBB, MI, DL, *Desc)
1978 .addReg(SubReg, getDefRegState(!IsStore) | getKillRegState(IsKill));
1979
1980 if (UseVGPROffset) {
1981 // For an AGPR spill, we reuse the same temp VGPR for the offset and the
1982 // intermediate accvgpr_write.
1983 MIB.addReg(TmpOffsetVGPR, getKillRegState(IsLastSubReg && !IsAGPR));
1984 }
1985
1986 if (!IsFlat)
1987 MIB.addReg(FuncInfo->getScratchRSrcReg());
1988
1989 if (SOffset == AMDGPU::NoRegister) {
1990 if (!IsFlat) {
1991 if (UseVGPROffset && ScratchOffsetReg) {
1992 MIB.addReg(ScratchOffsetReg);
1993 } else {
1994 assert(FuncInfo->isBottomOfStack());
1995 MIB.addImm(0);
1996 }
1997 }
1998 } else {
1999 MIB.addReg(SOffset, SOffsetRegState);
2000 }
2001
2002 MIB.addImm(Offset + RegOffset);
2003
2004 bool LastUse = MMO->getFlags() & MOLastUse;
2005 MIB.addImm(LastUse ? AMDGPU::CPol::TH_LU : 0); // cpol
2006
2007 if (!IsFlat)
2008 MIB.addImm(0); // swz
2009 MIB.addMemOperand(NewMMO);
2010
2011 if (FinalValueReg != ValueReg) {
2012 // Extract 16-bit from the loaded 32-bit value.
2013 ValueReg = getSubReg(ValueReg, AMDGPU::lo16);
2014 MIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B16_t16_e64))
2015 .addReg(FinalValueReg, getDefRegState(true))
2016 .addImm(0)
2017 .addReg(ValueReg, getKillRegState(true))
2018 .addImm(0);
2019 ValueReg = FinalValueReg;
2020 }
2021
2022 if (IsStore && NeedsCFI) {
2023 if (TII->isBlockLoadStore(LoadStoreOp)) {
2024 assert(RegOffset == 0 &&
2025 "expected whole register block to be treated as single element");
2027 } else {
2029 MBB, MI, DebugLoc(), SubReg,
2030 (Offset + RegOffset) * ST.getWavefrontSize() + AdditionalCFIOffset);
2031 }
2032 }
2033
2034 if (!IsAGPR && NeedSuperRegDef)
2035 MIB.addReg(ValueReg, RegState::ImplicitDefine);
2036
2037 if (!IsStore && IsAGPR && TmpIntermediateVGPR != AMDGPU::NoRegister) {
2038 MIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ACCVGPR_WRITE_B32_e64),
2039 FinalReg)
2040 .addReg(TmpIntermediateVGPR, RegState::Kill);
2042 }
2043
2044 bool IsSrcDstDef = hasRegState(SrcDstRegState, RegState::Define);
2045 bool PartialReloadCopy = (RemEltSize != EltSize) && !IsStore;
2046 if (NeedSuperRegImpOperand &&
2047 (IsFirstSubReg || (IsLastSubReg && !IsSrcDstDef))) {
2048 MIB.addReg(ValueReg, RegState::Implicit | SrcDstRegState);
2049 if (PartialReloadCopy)
2050 MIB.addReg(ValueReg, RegState::Implicit);
2051 }
2052
2053 // The epilog restore of a wwm-scratch register can cause undesired
2054 // optimization during machine-cp post PrologEpilogInserter if the same
2055 // register was assigned for return value ABI lowering with a COPY
2056 // instruction. As given below, with the epilog reload, the earlier COPY
2057 // appeared to be dead during machine-cp.
2058 // ...
2059 // v0 in WWM operation, needs the WWM spill at prolog/epilog.
2060 // $vgpr0 = V_WRITELANE_B32 $sgpr20, 0, $vgpr0
2061 // ...
2062 // Epilog block:
2063 // $vgpr0 = COPY $vgpr1 // outgoing value moved to v0
2064 // ...
2065 // WWM spill restore to preserve the inactive lanes of v0.
2066 // $sgpr4_sgpr5 = S_XOR_SAVEEXEC_B64 -1
2067 // $vgpr0 = BUFFER_LOAD $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr32, 0, 0, 0
2068 // $exec = S_MOV_B64 killed $sgpr4_sgpr5
2069 // ...
2070 // SI_RETURN implicit $vgpr0
2071 // ...
2072 // To fix it, mark the same reg as a tied op for such restore instructions
2073 // so that it marks a usage for the preceding COPY.
2074 if (!IsStore && MI != MBB.end() && MI->isReturn() &&
2075 MI->readsRegister(SubReg, this)) {
2076 MIB.addReg(SubReg, RegState::Implicit);
2077 MIB->tieOperands(0, MIB->getNumOperands() - 1);
2078 }
2079
2080 // If we're building a block load, we should add artificial uses for the
2081 // CSR VGPRs that are *not* being transferred. This is because liveness
2082 // analysis is not aware of the mask, so we need to somehow inform it that
2083 // those registers are not available before the load and they should not be
2084 // scavenged.
2085 if (!IsStore && TII->isBlockLoadStore(LoadStoreOp))
2086 addImplicitUsesForBlockCSRLoad(MIB, ValueReg);
2087 }
2088
2089 if (ScratchOffsetRegDelta != 0) {
2090 // Subtract the offset we added to the ScratchOffset register.
2091 BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), SOffset)
2092 .addReg(SOffset)
2093 .addImm(-ScratchOffsetRegDelta);
2094 }
2095}
2096
2098 Register BlockReg) const {
2099 const MachineFunction *MF = MIB->getMF();
2100 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
2101 uint32_t Mask = FuncInfo->getMaskForVGPRBlockOps(BlockReg);
2102 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2103 for (unsigned RegOffset = 1; RegOffset < 32; ++RegOffset)
2104 if (!(Mask & (1 << RegOffset)) &&
2105 isCalleeSavedPhysReg(BaseVGPR + RegOffset, *MF))
2106 MIB.addUse(BaseVGPR + RegOffset, RegState::Implicit);
2107}
2108
2111 Register BlockReg,
2112 int64_t Offset) const {
2113 const MachineFunction *MF = MBB.getParent();
2114 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
2115 uint32_t Mask = FuncInfo->getMaskForVGPRBlockOps(BlockReg);
2116 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2117 for (unsigned RegOffset = 0; RegOffset < 32; ++RegOffset) {
2118 Register VGPR = BaseVGPR + RegOffset;
2119 if (Mask & (1 << RegOffset)) {
2120 assert(isCalleeSavedPhysReg(VGPR, *MF));
2121 ST.getFrameLowering()->buildCFIForVGPRToVMEMSpill(
2122 MBB, MBBI, DebugLoc(), VGPR,
2123 (Offset + RegOffset) * ST.getWavefrontSize());
2124 } else if (isCalleeSavedPhysReg(VGPR, *MF)) {
2125 // FIXME: This is a workaround for the fact that FrameLowering's
2126 // emitPrologueEntryCFI considers the block load to clobber all registers
2127 // in the block.
2128 ST.getFrameLowering()->buildCFIForSameValue(MBB, MBBI, DebugLoc(),
2129 BaseVGPR + RegOffset);
2130 }
2131 }
2132}
2133
2135 int Offset, bool IsLoad,
2136 bool IsKill) const {
2137 // Load/store VGPR
2138 MachineFrameInfo &FrameInfo = SB.MF.getFrameInfo();
2139 assert(FrameInfo.getStackID(Index) != TargetStackID::SGPRSpill);
2140
2141 Register FrameReg =
2142 FrameInfo.isFixedObjectIndex(Index) && hasBasePointer(SB.MF)
2143 ? getBaseRegister()
2144 : getFrameRegister(SB.MF);
2145
2146 Align Alignment = FrameInfo.getObjectAlign(Index);
2150 SB.EltSize, Alignment);
2151
2152 if (IsLoad) {
2153 unsigned Opc = ST.hasFlatScratchEnabled()
2154 ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2155 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2156 buildSpillLoadStore(*SB.MBB, SB.MI, SB.DL, Opc, Index, SB.TmpVGPR, false,
2157 FrameReg, (int64_t)Offset * SB.EltSize, MMO, SB.RS);
2158 } else {
2159 unsigned Opc = ST.hasFlatScratchEnabled()
2160 ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2161 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2162 buildSpillLoadStore(*SB.MBB, SB.MI, SB.DL, Opc, Index, SB.TmpVGPR, IsKill,
2163 FrameReg, (int64_t)Offset * SB.EltSize, MMO, SB.RS);
2164 // This only ever adds one VGPR spill
2165 SB.MFI.addToSpilledVGPRs(1);
2166 }
2167}
2168
2170 RegScavenger *RS, SlotIndexes *Indexes,
2171 LiveIntervals *LIS, bool OnlyToVGPR,
2172 bool SpillToPhysVGPRLane, bool NeedsCFI) const {
2173 assert(!MI->getOperand(0).isUndef() &&
2174 "undef spill should have been deleted earlier");
2175
2176 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, Index, RS);
2177
2178 ArrayRef<SpilledReg> VGPRSpills =
2179 SpillToPhysVGPRLane ? SB.MFI.getSGPRSpillToPhysicalVGPRLanes(Index)
2181 bool SpillToVGPR = !VGPRSpills.empty();
2182 if (OnlyToVGPR && !SpillToVGPR)
2183 return false;
2184
2185 const SIFrameLowering *TFL = ST.getFrameLowering();
2186
2187 assert(SpillToVGPR || (SB.SuperReg != SB.MFI.getStackPtrOffsetReg() &&
2188 SB.SuperReg != SB.MFI.getFrameOffsetReg()));
2189
2190 if (SpillToVGPR) {
2191
2192 // Since stack slot coloring pass is trying to optimize SGPR spills,
2193 // VGPR lanes (mapped from spill stack slot) may be shared for SGPR
2194 // spills of different sizes. This accounts for number of VGPR lanes alloted
2195 // equal to the largest SGPR being spilled in them.
2196 assert(SB.NumSubRegs <= VGPRSpills.size() &&
2197 "Num of SGPRs spilled should be less than or equal to num of "
2198 "the VGPR lanes.");
2199
2200 for (unsigned i = 0, e = SB.NumSubRegs; i < e; ++i) {
2201 Register SubReg =
2202 SB.NumSubRegs == 1
2203 ? SB.SuperReg
2204 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2205 SpilledReg Spill = VGPRSpills[i];
2206
2207 bool IsFirstSubreg = i == 0;
2208 bool IsLastSubreg = i == SB.NumSubRegs - 1;
2209 bool UseKill = SB.IsKill && IsLastSubreg;
2210
2211
2212 // Mark the "old value of vgpr" input undef only if this is the first sgpr
2213 // spill to this specific vgpr in the first basic block.
2214 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2215 SB.TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), Spill.VGPR)
2216 .addReg(SubReg, getKillRegState(UseKill))
2217 .addImm(Spill.Lane)
2218 .addReg(Spill.VGPR);
2219
2220 MachineInstr *CFI = nullptr;
2221 if (NeedsCFI) {
2222 if (SB.SuperReg == SB.TRI.getReturnAddressReg(SB.MF)) {
2223 if (i == e - 1)
2224 CFI = TFL->buildCFIForSGPRToVGPRSpill(*SB.MBB, MI, DebugLoc(),
2225 AMDGPU::PC_REG, VGPRSpills);
2226 } else {
2227 CFI = TFL->buildCFIForSGPRToVGPRSpill(*SB.MBB, MI, DebugLoc(), SubReg,
2228 Spill.VGPR, Spill.Lane);
2229 }
2230 }
2231
2232 if (Indexes) {
2233 if (IsFirstSubreg)
2234 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2235 else
2236 Indexes->insertMachineInstrInMaps(*MIB);
2237
2238 if (CFI)
2239 Indexes->insertMachineInstrInMaps(*CFI);
2240 }
2241
2242 if (IsFirstSubreg && SB.NumSubRegs > 1) {
2243 // We may be spilling a super-register which is only partially defined,
2244 // and need to ensure later spills think the value is defined.
2245 MIB.addReg(SB.SuperReg, RegState::ImplicitDefine);
2246 }
2247
2248 if (SB.NumSubRegs > 1 && (IsFirstSubreg || IsLastSubreg))
2249 MIB.addReg(SB.SuperReg, getKillRegState(UseKill) | RegState::Implicit);
2250
2251 // FIXME: Since this spills to another register instead of an actual
2252 // frame index, we should delete the frame index when all references to
2253 // it are fixed.
2254 }
2255 } else {
2256 SB.prepare();
2257
2258 // SubReg carries the "Kill" flag when SubReg == SB.SuperReg.
2259 RegState SubKillState = getKillRegState((SB.NumSubRegs == 1) && SB.IsKill);
2260
2261 // Per VGPR helper data
2262 auto PVD = SB.getPerVGPRData();
2263
2264 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2265 RegState TmpVGPRFlags = RegState::Undef;
2266
2267 // Write sub registers into the VGPR
2268 for (unsigned i = Offset * PVD.PerVGPR,
2269 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2270 i < e; ++i) {
2271 Register SubReg =
2272 SB.NumSubRegs == 1
2273 ? SB.SuperReg
2274 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2275
2276 MachineInstrBuilder WriteLane =
2277 BuildMI(*SB.MBB, MI, SB.DL,
2278 SB.TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), SB.TmpVGPR)
2279 .addReg(SubReg, SubKillState)
2280 .addImm(i % PVD.PerVGPR)
2281 .addReg(SB.TmpVGPR, TmpVGPRFlags);
2282 TmpVGPRFlags = {};
2283
2284 if (Indexes) {
2285 if (i == 0)
2286 Indexes->replaceMachineInstrInMaps(*MI, *WriteLane);
2287 else
2288 Indexes->insertMachineInstrInMaps(*WriteLane);
2289 }
2290
2291 // There could be undef components of a spilled super register.
2292 // TODO: Can we detect this and skip the spill?
2293 if (SB.NumSubRegs > 1) {
2294 // The last implicit use of the SB.SuperReg carries the "Kill" flag.
2295 RegState SuperKillState = {};
2296 if (i + 1 == SB.NumSubRegs)
2297 SuperKillState |= getKillRegState(SB.IsKill);
2298 WriteLane.addReg(SB.SuperReg, RegState::Implicit | SuperKillState);
2299 }
2300 }
2301
2302 // Write out VGPR
2303 SB.readWriteTmpVGPR(Offset, /*IsLoad*/ false);
2304
2305 // TODO: Implement CFI for SpillToVMEM for all scenarios.
2306 MachineInstr *CFI = nullptr;
2307 if (NeedsCFI && SB.SuperReg == SB.TRI.getReturnAddressReg(SB.MF)) {
2308 int64_t CFIOffset = (Offset * SB.EltSize +
2309 SB.MF.getFrameInfo().getObjectOffset(Index)) *
2310 ST.getWavefrontSize();
2311 CFI = TFL->buildCFIForSGPRToVMEMSpill(*SB.MBB, MI, DebugLoc(),
2312 AMDGPU::PC_REG, CFIOffset);
2313 }
2314 if (Indexes && CFI)
2315 Indexes->insertMachineInstrInMaps(*CFI);
2316 }
2317
2318 SB.restore();
2319 }
2320
2321 MI->eraseFromParent();
2323
2324 if (LIS)
2326
2327 return true;
2328}
2329
2331 RegScavenger *RS, SlotIndexes *Indexes,
2332 LiveIntervals *LIS, bool OnlyToVGPR,
2333 bool SpillToPhysVGPRLane) const {
2334 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, Index, RS);
2335
2336 ArrayRef<SpilledReg> VGPRSpills =
2337 SpillToPhysVGPRLane ? SB.MFI.getSGPRSpillToPhysicalVGPRLanes(Index)
2339 bool SpillToVGPR = !VGPRSpills.empty();
2340 if (OnlyToVGPR && !SpillToVGPR)
2341 return false;
2342
2343 if (SpillToVGPR) {
2344 for (unsigned i = 0, e = SB.NumSubRegs; i < e; ++i) {
2345 Register SubReg =
2346 SB.NumSubRegs == 1
2347 ? SB.SuperReg
2348 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2349
2350 SpilledReg Spill = VGPRSpills[i];
2351 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2352 SB.TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2353 .addReg(Spill.VGPR)
2354 .addImm(Spill.Lane);
2355 if (SB.NumSubRegs > 1 && i == 0)
2357 if (Indexes) {
2358 if (i == e - 1)
2359 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2360 else
2361 Indexes->insertMachineInstrInMaps(*MIB);
2362 }
2363 }
2364 } else {
2365 SB.prepare();
2366
2367 // Per VGPR helper data
2368 auto PVD = SB.getPerVGPRData();
2369
2370 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2371 // Load in VGPR data
2372 SB.readWriteTmpVGPR(Offset, /*IsLoad*/ true);
2373
2374 // Unpack lanes
2375 for (unsigned i = Offset * PVD.PerVGPR,
2376 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2377 i < e; ++i) {
2378 Register SubReg =
2379 SB.NumSubRegs == 1
2380 ? SB.SuperReg
2381 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2382
2383 bool LastSubReg = (i + 1 == e);
2384 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2385 SB.TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2386 .addReg(SB.TmpVGPR, getKillRegState(LastSubReg))
2387 .addImm(i);
2388 if (SB.NumSubRegs > 1 && i == 0)
2390 if (Indexes) {
2391 if (i == e - 1)
2392 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2393 else
2394 Indexes->insertMachineInstrInMaps(*MIB);
2395 }
2396 }
2397 }
2398
2399 SB.restore();
2400 }
2401
2402 MI->eraseFromParent();
2403
2404 if (LIS)
2406
2407 return true;
2408}
2409
2411 MachineBasicBlock &RestoreMBB,
2412 Register SGPR, RegScavenger *RS) const {
2413 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, SGPR, false, 0,
2414 RS);
2415 SB.prepare();
2416 // Generate the spill of SGPR to SB.TmpVGPR.
2417 RegState SubKillState = getKillRegState((SB.NumSubRegs == 1) && SB.IsKill);
2418 auto PVD = SB.getPerVGPRData();
2419 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2420 RegState TmpVGPRFlags = RegState::Undef;
2421 // Write sub registers into the VGPR
2422 for (unsigned i = Offset * PVD.PerVGPR,
2423 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2424 i < e; ++i) {
2425 Register SubReg =
2426 SB.NumSubRegs == 1
2427 ? SB.SuperReg
2428 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2429
2430 MachineInstrBuilder WriteLane =
2431 BuildMI(*SB.MBB, MI, SB.DL, SB.TII.get(AMDGPU::V_WRITELANE_B32),
2432 SB.TmpVGPR)
2433 .addReg(SubReg, SubKillState)
2434 .addImm(i % PVD.PerVGPR)
2435 .addReg(SB.TmpVGPR, TmpVGPRFlags);
2436 TmpVGPRFlags = {};
2437 // There could be undef components of a spilled super register.
2438 // TODO: Can we detect this and skip the spill?
2439 if (SB.NumSubRegs > 1) {
2440 // The last implicit use of the SB.SuperReg carries the "Kill" flag.
2441 RegState SuperKillState = {};
2442 if (i + 1 == SB.NumSubRegs)
2443 SuperKillState |= getKillRegState(SB.IsKill);
2444 WriteLane.addReg(SB.SuperReg, RegState::Implicit | SuperKillState);
2445 }
2446 }
2447 // Don't need to write VGPR out.
2448 }
2449
2450 // Restore clobbered registers in the specified restore block.
2451 MI = RestoreMBB.end();
2452 SB.setMI(&RestoreMBB, MI);
2453 // Generate the restore of SGPR from SB.TmpVGPR.
2454 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2455 // Don't need to load VGPR in.
2456 // Unpack lanes
2457 for (unsigned i = Offset * PVD.PerVGPR,
2458 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2459 i < e; ++i) {
2460 Register SubReg =
2461 SB.NumSubRegs == 1
2462 ? SB.SuperReg
2463 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2464
2465 assert(SubReg.isPhysical());
2466 bool LastSubReg = (i + 1 == e);
2467 auto MIB = BuildMI(*SB.MBB, MI, SB.DL, SB.TII.get(AMDGPU::V_READLANE_B32),
2468 SubReg)
2469 .addReg(SB.TmpVGPR, getKillRegState(LastSubReg))
2470 .addImm(i);
2471 if (SB.NumSubRegs > 1 && i == 0)
2473 }
2474 }
2475 SB.restore();
2476
2478 return false;
2479}
2480
2481/// Special case of eliminateFrameIndex. Returns true if the SGPR was spilled to
2482/// a VGPR and the stack slot can be safely eliminated when all other users are
2483/// handled.
2486 SlotIndexes *Indexes, LiveIntervals *LIS, bool SpillToPhysVGPRLane) const {
2487 bool NeedsCFI = false;
2488 switch (MI->getOpcode()) {
2489 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2490 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2491 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2492 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2493 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2494 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2495 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2496 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2497 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2498 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
2499 NeedsCFI = true;
2500 [[fallthrough]];
2501 case AMDGPU::SI_SPILL_S1024_SAVE:
2502 case AMDGPU::SI_SPILL_S512_SAVE:
2503 case AMDGPU::SI_SPILL_S384_SAVE:
2504 case AMDGPU::SI_SPILL_S352_SAVE:
2505 case AMDGPU::SI_SPILL_S320_SAVE:
2506 case AMDGPU::SI_SPILL_S288_SAVE:
2507 case AMDGPU::SI_SPILL_S256_SAVE:
2508 case AMDGPU::SI_SPILL_S224_SAVE:
2509 case AMDGPU::SI_SPILL_S192_SAVE:
2510 case AMDGPU::SI_SPILL_S160_SAVE:
2511 case AMDGPU::SI_SPILL_S128_SAVE:
2512 case AMDGPU::SI_SPILL_S96_SAVE:
2513 case AMDGPU::SI_SPILL_S64_SAVE:
2514 case AMDGPU::SI_SPILL_S32_SAVE:
2515 return spillSGPR(MI, FI, RS, Indexes, LIS, true, SpillToPhysVGPRLane,
2516 NeedsCFI);
2517 case AMDGPU::SI_SPILL_S1024_RESTORE:
2518 case AMDGPU::SI_SPILL_S512_RESTORE:
2519 case AMDGPU::SI_SPILL_S384_RESTORE:
2520 case AMDGPU::SI_SPILL_S352_RESTORE:
2521 case AMDGPU::SI_SPILL_S320_RESTORE:
2522 case AMDGPU::SI_SPILL_S288_RESTORE:
2523 case AMDGPU::SI_SPILL_S256_RESTORE:
2524 case AMDGPU::SI_SPILL_S224_RESTORE:
2525 case AMDGPU::SI_SPILL_S192_RESTORE:
2526 case AMDGPU::SI_SPILL_S160_RESTORE:
2527 case AMDGPU::SI_SPILL_S128_RESTORE:
2528 case AMDGPU::SI_SPILL_S96_RESTORE:
2529 case AMDGPU::SI_SPILL_S64_RESTORE:
2530 case AMDGPU::SI_SPILL_S32_RESTORE:
2531 return restoreSGPR(MI, FI, RS, Indexes, LIS, true, SpillToPhysVGPRLane);
2532 default:
2533 llvm_unreachable("not an SGPR spill instruction");
2534 }
2535}
2536
2538 int SPAdj, unsigned FIOperandNum,
2539 RegScavenger *RS) const {
2540 MachineFunction *MF = MI->getMF();
2541 MachineBasicBlock *MBB = MI->getParent();
2543 MachineFrameInfo &FrameInfo = MF->getFrameInfo();
2544 const SIInstrInfo *TII = ST.getInstrInfo();
2545 const DebugLoc &DL = MI->getDebugLoc();
2546
2547 assert(SPAdj == 0 && "unhandled SP adjustment in call sequence?");
2548
2550 "unreserved scratch RSRC register");
2551
2552 MachineOperand *FIOp = &MI->getOperand(FIOperandNum);
2553 int Index = MI->getOperand(FIOperandNum).getIndex();
2554
2555 Register FrameReg = FrameInfo.isFixedObjectIndex(Index) && hasBasePointer(*MF)
2556 ? getBaseRegister()
2557 : getFrameRegister(*MF);
2558
2559 bool NeedsCFI = false;
2560
2561 switch (MI->getOpcode()) {
2562 // SGPR register spill
2563 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2564 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2565 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2566 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2567 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2568 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2569 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2570 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2571 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2572 case AMDGPU::SI_SPILL_S32_CFI_SAVE: {
2573 NeedsCFI = true;
2574 [[fallthrough]];
2575 }
2576 case AMDGPU::SI_SPILL_S1024_SAVE:
2577 case AMDGPU::SI_SPILL_S512_SAVE:
2578 case AMDGPU::SI_SPILL_S384_SAVE:
2579 case AMDGPU::SI_SPILL_S352_SAVE:
2580 case AMDGPU::SI_SPILL_S320_SAVE:
2581 case AMDGPU::SI_SPILL_S288_SAVE:
2582 case AMDGPU::SI_SPILL_S256_SAVE:
2583 case AMDGPU::SI_SPILL_S224_SAVE:
2584 case AMDGPU::SI_SPILL_S192_SAVE:
2585 case AMDGPU::SI_SPILL_S160_SAVE:
2586 case AMDGPU::SI_SPILL_S128_SAVE:
2587 case AMDGPU::SI_SPILL_S96_SAVE:
2588 case AMDGPU::SI_SPILL_S64_SAVE:
2589 case AMDGPU::SI_SPILL_S32_SAVE: {
2590 return spillSGPR(MI, Index, RS, nullptr, nullptr,
2591 FrameInfo.getStackID(Index) == TargetStackID::SGPRSpill,
2592 false, NeedsCFI);
2593 }
2594
2595 // SGPR register restore
2596 case AMDGPU::SI_SPILL_S1024_RESTORE:
2597 case AMDGPU::SI_SPILL_S512_RESTORE:
2598 case AMDGPU::SI_SPILL_S384_RESTORE:
2599 case AMDGPU::SI_SPILL_S352_RESTORE:
2600 case AMDGPU::SI_SPILL_S320_RESTORE:
2601 case AMDGPU::SI_SPILL_S288_RESTORE:
2602 case AMDGPU::SI_SPILL_S256_RESTORE:
2603 case AMDGPU::SI_SPILL_S224_RESTORE:
2604 case AMDGPU::SI_SPILL_S192_RESTORE:
2605 case AMDGPU::SI_SPILL_S160_RESTORE:
2606 case AMDGPU::SI_SPILL_S128_RESTORE:
2607 case AMDGPU::SI_SPILL_S96_RESTORE:
2608 case AMDGPU::SI_SPILL_S64_RESTORE:
2609 case AMDGPU::SI_SPILL_S32_RESTORE: {
2610 return restoreSGPR(MI, Index, RS, nullptr, nullptr,
2611 FrameInfo.getStackID(Index) ==
2613 }
2614
2615 // VGPR register spill
2616 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
2617 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
2618 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
2619 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
2620 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
2621 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
2622 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
2623 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
2624 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
2625 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
2626 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
2627 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
2628 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
2629 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
2630 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
2631 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
2632 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
2633 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
2634 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
2635 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
2636 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
2637 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
2638 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
2639 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
2640 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
2641 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
2642 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
2643 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
2644 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
2645 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
2646 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
2647 NeedsCFI = true;
2648 [[fallthrough]];
2649 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
2650 case AMDGPU::SI_SPILL_V1024_SAVE:
2651 case AMDGPU::SI_SPILL_V512_SAVE:
2652 case AMDGPU::SI_SPILL_V384_SAVE:
2653 case AMDGPU::SI_SPILL_V352_SAVE:
2654 case AMDGPU::SI_SPILL_V320_SAVE:
2655 case AMDGPU::SI_SPILL_V288_SAVE:
2656 case AMDGPU::SI_SPILL_V256_SAVE:
2657 case AMDGPU::SI_SPILL_V224_SAVE:
2658 case AMDGPU::SI_SPILL_V192_SAVE:
2659 case AMDGPU::SI_SPILL_V160_SAVE:
2660 case AMDGPU::SI_SPILL_V128_SAVE:
2661 case AMDGPU::SI_SPILL_V96_SAVE:
2662 case AMDGPU::SI_SPILL_V64_SAVE:
2663 case AMDGPU::SI_SPILL_V32_SAVE:
2664 case AMDGPU::SI_SPILL_V16_SAVE:
2665 case AMDGPU::SI_SPILL_A1024_SAVE:
2666 case AMDGPU::SI_SPILL_A512_SAVE:
2667 case AMDGPU::SI_SPILL_A384_SAVE:
2668 case AMDGPU::SI_SPILL_A352_SAVE:
2669 case AMDGPU::SI_SPILL_A320_SAVE:
2670 case AMDGPU::SI_SPILL_A288_SAVE:
2671 case AMDGPU::SI_SPILL_A256_SAVE:
2672 case AMDGPU::SI_SPILL_A224_SAVE:
2673 case AMDGPU::SI_SPILL_A192_SAVE:
2674 case AMDGPU::SI_SPILL_A160_SAVE:
2675 case AMDGPU::SI_SPILL_A128_SAVE:
2676 case AMDGPU::SI_SPILL_A96_SAVE:
2677 case AMDGPU::SI_SPILL_A64_SAVE:
2678 case AMDGPU::SI_SPILL_A32_SAVE:
2679 case AMDGPU::SI_SPILL_AV1024_SAVE:
2680 case AMDGPU::SI_SPILL_AV512_SAVE:
2681 case AMDGPU::SI_SPILL_AV384_SAVE:
2682 case AMDGPU::SI_SPILL_AV352_SAVE:
2683 case AMDGPU::SI_SPILL_AV320_SAVE:
2684 case AMDGPU::SI_SPILL_AV288_SAVE:
2685 case AMDGPU::SI_SPILL_AV256_SAVE:
2686 case AMDGPU::SI_SPILL_AV224_SAVE:
2687 case AMDGPU::SI_SPILL_AV192_SAVE:
2688 case AMDGPU::SI_SPILL_AV160_SAVE:
2689 case AMDGPU::SI_SPILL_AV128_SAVE:
2690 case AMDGPU::SI_SPILL_AV96_SAVE:
2691 case AMDGPU::SI_SPILL_AV64_SAVE:
2692 case AMDGPU::SI_SPILL_AV32_SAVE:
2693 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2694 case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
2695 assert(
2696 MI->getOpcode() != AMDGPU::SI_BLOCK_SPILL_V1024_SAVE &&
2697 "block spill does not currenty support spilling non-CSR registers");
2698
2699 if (MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE)
2700 // Put mask into M0.
2701 BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_MOV_B32),
2702 AMDGPU::M0)
2703 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::mask));
2704
2705 const MachineOperand *VData = TII->getNamedOperand(*MI,
2706 AMDGPU::OpName::vdata);
2707 if (VData->isUndef()) {
2708 MI->eraseFromParent();
2709 return true;
2710 }
2711
2712 assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==
2713 MFI->getStackPtrOffsetReg());
2714
2715 unsigned Opc;
2716 if (MI->getOpcode() == AMDGPU::SI_SPILL_V16_SAVE) {
2717 assert(ST.hasFlatScratchEnabled() && "Flat Scratch is not enabled!");
2718 Opc = AMDGPU::SCRATCH_STORE_SHORT_SADDR_t16;
2719 } else {
2720 Opc = MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE
2721 ? AMDGPU::SCRATCH_STORE_BLOCK_SADDR
2722 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2723 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2724 }
2725
2726 auto *MBB = MI->getParent();
2727 bool IsWWMRegSpill = TII->isWWMRegSpillOpcode(MI->getOpcode());
2728 if (IsWWMRegSpill) {
2729 TII->insertScratchExecCopy(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy(),
2730 RS->isRegUsed(AMDGPU::SCC));
2731 }
2733 *MBB, MI, DL, Opc, Index, VData->getReg(), VData->isKill(), FrameReg,
2734 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(),
2735 *MI->memoperands_begin(), RS, nullptr, NeedsCFI);
2737 if (IsWWMRegSpill)
2738 TII->restoreExec(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy());
2739
2740 MI->eraseFromParent();
2741 return true;
2742 }
2743 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE: {
2744 // Put mask into M0.
2745 BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_MOV_B32),
2746 AMDGPU::M0)
2747 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::mask));
2748 [[fallthrough]];
2749 }
2750 case AMDGPU::SI_SPILL_V16_RESTORE:
2751 case AMDGPU::SI_SPILL_V32_RESTORE:
2752 case AMDGPU::SI_SPILL_V64_RESTORE:
2753 case AMDGPU::SI_SPILL_V96_RESTORE:
2754 case AMDGPU::SI_SPILL_V128_RESTORE:
2755 case AMDGPU::SI_SPILL_V160_RESTORE:
2756 case AMDGPU::SI_SPILL_V192_RESTORE:
2757 case AMDGPU::SI_SPILL_V224_RESTORE:
2758 case AMDGPU::SI_SPILL_V256_RESTORE:
2759 case AMDGPU::SI_SPILL_V288_RESTORE:
2760 case AMDGPU::SI_SPILL_V320_RESTORE:
2761 case AMDGPU::SI_SPILL_V352_RESTORE:
2762 case AMDGPU::SI_SPILL_V384_RESTORE:
2763 case AMDGPU::SI_SPILL_V512_RESTORE:
2764 case AMDGPU::SI_SPILL_V1024_RESTORE:
2765 case AMDGPU::SI_SPILL_A32_RESTORE:
2766 case AMDGPU::SI_SPILL_A64_RESTORE:
2767 case AMDGPU::SI_SPILL_A96_RESTORE:
2768 case AMDGPU::SI_SPILL_A128_RESTORE:
2769 case AMDGPU::SI_SPILL_A160_RESTORE:
2770 case AMDGPU::SI_SPILL_A192_RESTORE:
2771 case AMDGPU::SI_SPILL_A224_RESTORE:
2772 case AMDGPU::SI_SPILL_A256_RESTORE:
2773 case AMDGPU::SI_SPILL_A288_RESTORE:
2774 case AMDGPU::SI_SPILL_A320_RESTORE:
2775 case AMDGPU::SI_SPILL_A352_RESTORE:
2776 case AMDGPU::SI_SPILL_A384_RESTORE:
2777 case AMDGPU::SI_SPILL_A512_RESTORE:
2778 case AMDGPU::SI_SPILL_A1024_RESTORE:
2779 case AMDGPU::SI_SPILL_AV32_RESTORE:
2780 case AMDGPU::SI_SPILL_AV64_RESTORE:
2781 case AMDGPU::SI_SPILL_AV96_RESTORE:
2782 case AMDGPU::SI_SPILL_AV128_RESTORE:
2783 case AMDGPU::SI_SPILL_AV160_RESTORE:
2784 case AMDGPU::SI_SPILL_AV192_RESTORE:
2785 case AMDGPU::SI_SPILL_AV224_RESTORE:
2786 case AMDGPU::SI_SPILL_AV256_RESTORE:
2787 case AMDGPU::SI_SPILL_AV288_RESTORE:
2788 case AMDGPU::SI_SPILL_AV320_RESTORE:
2789 case AMDGPU::SI_SPILL_AV352_RESTORE:
2790 case AMDGPU::SI_SPILL_AV384_RESTORE:
2791 case AMDGPU::SI_SPILL_AV512_RESTORE:
2792 case AMDGPU::SI_SPILL_AV1024_RESTORE:
2793 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2794 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
2795 const MachineOperand *VData = TII->getNamedOperand(*MI,
2796 AMDGPU::OpName::vdata);
2797 assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==
2798 MFI->getStackPtrOffsetReg());
2799
2800 unsigned Opc;
2801 if (MI->getOpcode() == AMDGPU::SI_SPILL_V16_RESTORE) {
2802 assert(ST.hasFlatScratchEnabled() && "Flat Scratch is not enabled!");
2803 Opc = ST.d16PreservesUnusedBits()
2804 ? AMDGPU::SCRATCH_LOAD_SHORT_D16_SADDR_t16
2805 : AMDGPU::SCRATCH_LOAD_USHORT_SADDR;
2806 } else {
2807 Opc = MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE
2808 ? AMDGPU::SCRATCH_LOAD_BLOCK_SADDR
2809 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2810 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2811 }
2812
2813 auto *MBB = MI->getParent();
2814 bool IsWWMRegSpill = TII->isWWMRegSpillOpcode(MI->getOpcode());
2815 if (IsWWMRegSpill) {
2816 TII->insertScratchExecCopy(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy(),
2817 RS->isRegUsed(AMDGPU::SCC));
2818 }
2819
2821 *MBB, MI, DL, Opc, Index, VData->getReg(), VData->isKill(), FrameReg,
2822 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(),
2823 *MI->memoperands_begin(), RS);
2824
2825 if (IsWWMRegSpill)
2826 TII->restoreExec(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy());
2827
2828 MI->eraseFromParent();
2829 return true;
2830 }
2831 case AMDGPU::V_ADD_U32_e32:
2832 case AMDGPU::V_ADD_U32_e64:
2833 case AMDGPU::V_ADD_CO_U32_e32:
2834 case AMDGPU::V_ADD_CO_U32_e64: {
2835 // TODO: Handle sub, and, or.
2836 unsigned NumDefs = MI->getNumExplicitDefs();
2837 unsigned Src0Idx = NumDefs;
2838
2839 bool HasClamp = false;
2840 MachineOperand *VCCOp = nullptr;
2841
2842 switch (MI->getOpcode()) {
2843 case AMDGPU::V_ADD_U32_e32:
2844 break;
2845 case AMDGPU::V_ADD_U32_e64:
2846 HasClamp = MI->getOperand(3).getImm();
2847 break;
2848 case AMDGPU::V_ADD_CO_U32_e32:
2849 VCCOp = &MI->getOperand(3);
2850 break;
2851 case AMDGPU::V_ADD_CO_U32_e64:
2852 VCCOp = &MI->getOperand(1);
2853 HasClamp = MI->getOperand(4).getImm();
2854 break;
2855 default:
2856 break;
2857 }
2858 bool DeadVCC = !VCCOp || VCCOp->isDead();
2859 MachineOperand &DstOp = MI->getOperand(0);
2860 Register DstReg = DstOp.getReg();
2861
2862 unsigned OtherOpIdx =
2863 FIOperandNum == Src0Idx ? FIOperandNum + 1 : Src0Idx;
2864 MachineOperand *OtherOp = &MI->getOperand(OtherOpIdx);
2865
2866 unsigned Src1Idx = Src0Idx + 1;
2867 Register MaterializedReg = FrameReg;
2868 Register ScavengedVGPR;
2869
2870 int64_t Offset = FrameInfo.getObjectOffset(Index);
2871 // For the non-immediate case, we could fall through to the default
2872 // handling, but we do an in-place update of the result register here to
2873 // avoid scavenging another register.
2874 if (OtherOp->isImm()) {
2875 int64_t TotalOffset = OtherOp->getImm() + Offset;
2876
2877 if (!ST.hasVOP3Literal() && SIInstrInfo::isVOP3(*MI) &&
2878 !AMDGPU::isInlinableIntLiteral(TotalOffset)) {
2879 // If we can't support a VOP3 literal in the VALU instruction, we
2880 // can't specially fold into the add.
2881 // TODO: Handle VOP3->VOP2 shrink to support the fold.
2882 break;
2883 }
2884
2885 OtherOp->setImm(TotalOffset);
2886 Offset = 0;
2887 }
2888
2889 if (FrameReg && !ST.hasFlatScratchEnabled()) {
2890 // We should just do an in-place update of the result register. However,
2891 // the value there may also be used by the add, in which case we need a
2892 // temporary register.
2893 //
2894 // FIXME: The scavenger is not finding the result register in the
2895 // common case where the add does not read the register.
2896
2897 ScavengedVGPR = RS->scavengeRegisterBackwards(
2898 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false, /*SPAdj=*/0);
2899
2900 // TODO: If we have a free SGPR, it's sometimes better to use a scalar
2901 // shift.
2902 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64))
2903 .addDef(ScavengedVGPR, RegState::Renamable)
2904 .addImm(ST.getWavefrontSizeLog2())
2905 .addReg(FrameReg);
2906 MaterializedReg = ScavengedVGPR;
2907 }
2908
2909 if ((!OtherOp->isImm() || OtherOp->getImm() != 0) && MaterializedReg) {
2910 if (ST.hasFlatScratchEnabled() &&
2911 !TII->isOperandLegal(*MI, Src1Idx, OtherOp)) {
2912 // We didn't need the shift above, so we have an SGPR for the frame
2913 // register, but may have a VGPR only operand.
2914 //
2915 // TODO: On gfx10+, we can easily change the opcode to the e64 version
2916 // and use the higher constant bus restriction to avoid this copy.
2917
2918 if (!ScavengedVGPR) {
2919 ScavengedVGPR = RS->scavengeRegisterBackwards(
2920 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false,
2921 /*SPAdj=*/0);
2922 }
2923
2924 assert(ScavengedVGPR != DstReg);
2925
2926 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), ScavengedVGPR)
2927 .addReg(MaterializedReg,
2928 getKillRegState(MaterializedReg != FrameReg));
2929 MaterializedReg = ScavengedVGPR;
2930 }
2931
2932 // TODO: In the flat scratch case, if this is an add of an SGPR, and SCC
2933 // is not live, we could use a scalar add + vector add instead of 2
2934 // vector adds.
2935 auto AddI32 = BuildMI(*MBB, *MI, DL, TII->get(MI->getOpcode()))
2936 .addDef(DstReg, RegState::Renamable);
2937 if (NumDefs == 2)
2938 AddI32.add(MI->getOperand(1));
2939
2940 RegState MaterializedRegFlags =
2941 getKillRegState(MaterializedReg != FrameReg);
2942
2943 if (isVGPRClass(getPhysRegBaseClass(MaterializedReg))) {
2944 // If we know we have a VGPR already, it's more likely the other
2945 // operand is a legal vsrc0.
2946 AddI32
2947 .add(*OtherOp)
2948 .addReg(MaterializedReg, MaterializedRegFlags);
2949 } else {
2950 // Commute operands to avoid violating VOP2 restrictions. This will
2951 // typically happen when using scratch.
2952 AddI32
2953 .addReg(MaterializedReg, MaterializedRegFlags)
2954 .add(*OtherOp);
2955 }
2956
2957 if (MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
2958 MI->getOpcode() == AMDGPU::V_ADD_U32_e64)
2959 AddI32.addImm(0); // clamp
2960
2961 if (MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e32)
2962 AddI32.setOperandDead(3); // Dead vcc
2963
2964 MaterializedReg = DstReg;
2965
2966 OtherOp->ChangeToRegister(MaterializedReg, false);
2967 OtherOp->setIsKill(true);
2969 Offset = 0;
2970 } else if (Offset != 0) {
2971 assert(!MaterializedReg);
2973 Offset = 0;
2974 } else {
2975 if (DeadVCC && !HasClamp) {
2976 assert(Offset == 0);
2977
2978 // TODO: Losing kills and implicit operands. Just mutate to copy and
2979 // let lowerCopy deal with it?
2980 if (OtherOp->isReg() && OtherOp->getReg() == DstReg) {
2981 // Folded to an identity copy.
2982 MI->eraseFromParent();
2983 return true;
2984 }
2985
2986 // The immediate value should be in OtherOp
2987 MI->setDesc(TII->get(AMDGPU::V_MOV_B32_e32));
2988 MI->removeOperand(FIOperandNum);
2989
2990 unsigned NumOps = MI->getNumOperands();
2991 for (unsigned I = NumOps - 2; I >= NumDefs + 1; --I)
2992 MI->removeOperand(I);
2993
2994 if (NumDefs == 2)
2995 MI->removeOperand(1);
2996
2997 // The code below can't deal with a mov.
2998 return true;
2999 }
3000
3001 // This folded to a constant, but we have to keep the add around for
3002 // pointless implicit defs or clamp modifier.
3003 FIOp->ChangeToImmediate(0);
3004 }
3005
3006 // Try to improve legality by commuting.
3007 if (!TII->isOperandLegal(*MI, Src1Idx) && TII->commuteInstruction(*MI)) {
3008 std::swap(FIOp, OtherOp);
3009 std::swap(FIOperandNum, OtherOpIdx);
3010 }
3011
3012 // We need at most one mov to satisfy the operand constraints. Prefer to
3013 // move the FI operand first, as it may be a literal in a VOP3
3014 // instruction.
3015 for (unsigned SrcIdx : {FIOperandNum, OtherOpIdx}) {
3016 if (!TII->isOperandLegal(*MI, SrcIdx)) {
3017 // If commuting didn't make the operands legal, we need to materialize
3018 // in a register.
3019 // TODO: Can use SGPR on gfx10+ in some cases.
3020 if (!ScavengedVGPR) {
3021 ScavengedVGPR = RS->scavengeRegisterBackwards(
3022 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false,
3023 /*SPAdj=*/0);
3024 }
3025
3026 assert(ScavengedVGPR != DstReg);
3027
3028 MachineOperand &Src = MI->getOperand(SrcIdx);
3029 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), ScavengedVGPR)
3030 .add(Src);
3031
3032 Src.ChangeToRegister(ScavengedVGPR, false);
3033 Src.setIsKill(true);
3034 break;
3035 }
3036 }
3037
3038 // Fold out add of 0 case that can appear in kernels.
3039 if (FIOp->isImm() && FIOp->getImm() == 0 && DeadVCC && !HasClamp) {
3040 if (OtherOp->isReg() && OtherOp->getReg() != DstReg) {
3041 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::COPY), DstReg).add(*OtherOp);
3042 }
3043
3044 MI->eraseFromParent();
3045 }
3046
3047 return true;
3048 }
3049 case AMDGPU::S_ADD_I32:
3050 case AMDGPU::S_ADD_U32: {
3051 // TODO: Handle s_or_b32, s_and_b32.
3052 unsigned OtherOpIdx = FIOperandNum == 1 ? 2 : 1;
3053 MachineOperand &OtherOp = MI->getOperand(OtherOpIdx);
3054
3055 assert(FrameReg || MFI->isBottomOfStack());
3056
3057 MachineOperand &DstOp = MI->getOperand(0);
3058 const DebugLoc &DL = MI->getDebugLoc();
3059 Register MaterializedReg = FrameReg;
3060
3061 // Defend against live scc, which should never happen in practice.
3062 bool DeadSCC = MI->getOperand(3).isDead();
3063
3064 Register TmpReg;
3065
3066 // FIXME: Scavenger should figure out that the result register is
3067 // available. Also should do this for the v_add case.
3068 if (OtherOp.isReg() && OtherOp.getReg() != DstOp.getReg())
3069 TmpReg = DstOp.getReg();
3070
3071 if (FrameReg && !ST.hasFlatScratchEnabled()) {
3072 // FIXME: In the common case where the add does not also read its result
3073 // (i.e. this isn't a reg += fi), it's not finding the dest reg as
3074 // available.
3075 if (!TmpReg)
3076 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3077 MI, /*RestoreAfter=*/false, 0,
3078 /*AllowSpill=*/false);
3079 if (TmpReg) {
3080 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::S_LSHR_B32))
3081 .addDef(TmpReg, RegState::Renamable)
3082 .addReg(FrameReg)
3083 .addImm(ST.getWavefrontSizeLog2())
3084 .setOperandDead(3); // Set SCC dead
3085 }
3086 MaterializedReg = TmpReg;
3087 }
3088
3089 int64_t Offset = FrameInfo.getObjectOffset(Index);
3090
3091 // For the non-immediate case, we could fall through to the default
3092 // handling, but we do an in-place update of the result register here to
3093 // avoid scavenging another register.
3094 if (OtherOp.isImm()) {
3095 OtherOp.setImm(OtherOp.getImm() + Offset);
3096 Offset = 0;
3097
3098 if (MaterializedReg)
3099 FIOp->ChangeToRegister(MaterializedReg, false);
3100 else
3101 FIOp->ChangeToImmediate(0);
3102 } else if (MaterializedReg) {
3103 // If we can't fold the other operand, do another increment.
3104 Register DstReg = DstOp.getReg();
3105
3106 if (!TmpReg && MaterializedReg == FrameReg) {
3107 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3108 MI, /*RestoreAfter=*/false, 0,
3109 /*AllowSpill=*/false);
3110 DstReg = TmpReg;
3111 }
3112
3113 if (TmpReg) {
3114 auto AddI32 = BuildMI(*MBB, *MI, DL, MI->getDesc())
3115 .addDef(DstReg, RegState::Renamable)
3116 .addReg(MaterializedReg, RegState::Kill)
3117 .add(OtherOp);
3118 if (DeadSCC)
3119 AddI32.setOperandDead(3);
3120
3121 MaterializedReg = DstReg;
3122
3123 OtherOp.ChangeToRegister(MaterializedReg, false);
3124 OtherOp.setIsKill(true);
3125 OtherOp.setIsRenamable(true);
3126 }
3128 } else {
3129 // If we don't have any other offset to apply, we can just directly
3130 // interpret the frame index as the offset.
3132 }
3133
3134 if (DeadSCC && OtherOp.isImm() && OtherOp.getImm() == 0) {
3135 assert(Offset == 0);
3136 MI->removeOperand(3);
3137 MI->removeOperand(OtherOpIdx);
3138 MachineOperand &Src = MI->getOperand(1);
3139 MI->setDesc(TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3140 } else if (DeadSCC && FIOp->isImm() && FIOp->getImm() == 0) {
3141 assert(Offset == 0);
3142 MI->removeOperand(3);
3143 MI->removeOperand(FIOperandNum);
3144 MachineOperand &Src = MI->getOperand(1);
3145 MI->setDesc(TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3146 }
3147
3148 assert(!FIOp->isFI());
3149 return true;
3150 }
3151 default: {
3152 break;
3153 }
3154 }
3155
3156 int64_t Offset = FrameInfo.getObjectOffset(Index);
3157 if (ST.hasFlatScratchEnabled()) {
3158 if (TII->isFLATScratch(*MI)) {
3159 assert(
3160 (int16_t)FIOperandNum ==
3161 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::saddr));
3162
3163 // The offset is always swizzled, just replace it
3164 if (FrameReg)
3165 FIOp->ChangeToRegister(FrameReg, false);
3166
3168 TII->getNamedOperand(*MI, AMDGPU::OpName::offset);
3169 int64_t NewOffset = Offset + OffsetOp->getImm();
3170 if (TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
3172 OffsetOp->setImm(NewOffset);
3173 if (FrameReg)
3174 return false;
3175 Offset = 0;
3176 }
3177
3178 if (!Offset) {
3179 unsigned Opc = MI->getOpcode();
3180 int NewOpc = -1;
3181 if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vaddr)) {
3183 } else if (ST.hasFlatScratchSTMode()) {
3184 // On GFX10 we have ST mode to use no registers for an address.
3185 // Otherwise we need to materialize 0 into an SGPR.
3187 }
3188
3189 if (NewOpc != -1) {
3190 // removeOperand doesn't fixup tied operand indexes as it goes, so
3191 // it asserts. Untie vdst_in for now and retie them afterwards.
3192 int VDstIn =
3193 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst_in);
3194 bool TiedVDst = VDstIn != -1 && MI->getOperand(VDstIn).isReg() &&
3195 MI->getOperand(VDstIn).isTied();
3196 if (TiedVDst)
3197 MI->untieRegOperand(VDstIn);
3198
3199 MI->removeOperand(
3200 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::saddr));
3201
3202 if (TiedVDst) {
3203 int NewVDst =
3204 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
3205 int NewVDstIn =
3206 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
3207 assert(NewVDst != -1 && NewVDstIn != -1 && "Must be tied!");
3208 MI->tieOperands(NewVDst, NewVDstIn);
3209 }
3210 MI->setDesc(TII->get(NewOpc));
3211 return false;
3212 }
3213 }
3214 }
3215
3216 if (!FrameReg) {
3218 if (TII->isImmOperandLegal(*MI, FIOperandNum, *FIOp))
3219 return false;
3220 }
3221
3222 // We need to use register here. Check if we can use an SGPR or need
3223 // a VGPR.
3224 FIOp->ChangeToRegister(AMDGPU::M0, false);
3225 bool UseSGPR = TII->isOperandLegal(*MI, FIOperandNum, FIOp);
3226
3227 if (!Offset && FrameReg && UseSGPR) {
3228 FIOp->setReg(FrameReg);
3229 return false;
3230 }
3231
3232 const TargetRegisterClass *RC =
3233 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3234
3235 Register TmpReg =
3236 RS->scavengeRegisterBackwards(*RC, MI, false, 0, !UseSGPR);
3237 FIOp->setReg(TmpReg);
3238 FIOp->setIsKill();
3239
3240 if ((!FrameReg || !Offset) && TmpReg) {
3241 unsigned Opc = UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
3242 auto MIB = BuildMI(*MBB, MI, DL, TII->get(Opc), TmpReg);
3243 if (FrameReg)
3244 MIB.addReg(FrameReg);
3245 else
3246 MIB.addImm(Offset);
3247
3248 return false;
3249 }
3250
3251 bool NeedSaveSCC = (RS->isRegUsed(AMDGPU::SCC) &&
3252 !MI->definesRegister(AMDGPU::SCC, /*TRI=*/nullptr)) ||
3253 MI->readsRegister(AMDGPU::SCC, /*TRI=*/nullptr);
3254
3255 Register TmpSReg =
3256 UseSGPR ? TmpReg
3257 : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3258 MI, false, 0, !UseSGPR);
3259
3260 // If no SGPR was scavenged but a frame register is available, fall
3261 // through to reuse it as the temporary (computed in place, restored
3262 // after). Only bail out when there is no frame register, or a VGPR
3263 // operand is needed but none could be scavenged.
3264 if ((!TmpSReg && !FrameReg) || (!TmpReg && !UseSGPR)) {
3265 int SVOpcode = AMDGPU::getFlatScratchInstSVfromSS(MI->getOpcode());
3266 if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
3267 // SV form encodes only the offset in vaddr; an SS-form scratch op
3268 // keeps its FI in the SGPR saddr, so this is only reached with no
3269 // frame register.
3270 assert(!FrameReg &&
3271 "SV-form fallback cannot encode a frame register");
3272 Register TmpVGPR = RS->scavengeRegisterBackwards(
3273 AMDGPU::VGPR_32RegClass, MI, false, 0, /*AllowSpill=*/true);
3274
3275 // Fold as much of the constant offset as possible into the SV form
3276 // instruction's immediate offset field, and materialize the
3277 // remainder (plus the frame register, if any) into the scavenged
3278 // VGPR used as the vaddr.
3279 int64_t FullOffset =
3280 Offset +
3281 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm();
3282 auto [ImmOffset, RemainderOffset] =
3283 TII->splitFlatOffset(FullOffset, AMDGPUAS::PRIVATE_ADDRESS,
3285 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
3286 .addImm(RemainderOffset);
3287 BuildMI(*MBB, MI, DL, TII->get(SVOpcode))
3288 .add(MI->getOperand(0)) // $vdata
3289 .addReg(TmpVGPR) // $vaddr
3290 .addImm(ImmOffset) // $offset
3291 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::cpol));
3292 MI->eraseFromParent();
3293 return true;
3294 }
3295 report_fatal_error("Cannot scavenge register in FI elimination!");
3296 }
3297
3298 if (!TmpSReg) {
3299 // Use frame register and restore it after.
3300 TmpSReg = FrameReg;
3301 FIOp->setReg(FrameReg);
3302 FIOp->setIsKill(false);
3303 }
3304
3305 if (NeedSaveSCC) {
3306 assert(!(Offset & 0x1) && "Flat scratch offset must be aligned!");
3307 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADDC_U32), TmpSReg)
3308 .addReg(FrameReg)
3309 .addImm(Offset);
3310 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_BITCMP1_B32))
3311 .addReg(TmpSReg)
3312 .addImm(0);
3313 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_BITSET0_B32), TmpSReg)
3314 .addImm(0)
3315 .addReg(TmpSReg);
3316 } else {
3317 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), TmpSReg)
3318 .addReg(FrameReg)
3319 .addImm(Offset);
3320 }
3321
3322 if (!UseSGPR)
3323 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
3324 .addReg(TmpSReg, RegState::Kill);
3325
3326 if (TmpSReg == FrameReg) {
3327 // Undo frame register modification.
3328 if (NeedSaveSCC &&
3329 !MI->registerDefIsDead(AMDGPU::SCC, /*TRI=*/nullptr)) {
3331 BuildMI(*MBB, std::next(MI), DL, TII->get(AMDGPU::S_ADDC_U32),
3332 TmpSReg)
3333 .addReg(FrameReg)
3334 .addImm(-Offset);
3335 I = BuildMI(*MBB, std::next(I), DL, TII->get(AMDGPU::S_BITCMP1_B32))
3336 .addReg(TmpSReg)
3337 .addImm(0);
3338 BuildMI(*MBB, std::next(I), DL, TII->get(AMDGPU::S_BITSET0_B32),
3339 TmpSReg)
3340 .addImm(0)
3341 .addReg(TmpSReg);
3342 } else {
3343 BuildMI(*MBB, std::next(MI), DL, TII->get(AMDGPU::S_ADD_I32),
3344 FrameReg)
3345 .addReg(FrameReg)
3346 .addImm(-Offset);
3347 }
3348 }
3349
3350 return false;
3351 }
3352
3353 bool IsMUBUF = TII->isMUBUF(*MI);
3354
3355 if (!IsMUBUF && !MFI->isBottomOfStack()) {
3356 // Convert to a swizzled stack address by scaling by the wave size.
3357 // In an entry function/kernel the offset is already swizzled.
3358 bool IsSALU = isSGPRClass(TII->getRegClass(MI->getDesc(), FIOperandNum));
3359 bool LiveSCC = RS->isRegUsed(AMDGPU::SCC) &&
3360 !MI->definesRegister(AMDGPU::SCC, /*TRI=*/nullptr);
3361 const TargetRegisterClass *RC = IsSALU && !LiveSCC
3362 ? &AMDGPU::SReg_32RegClass
3363 : &AMDGPU::VGPR_32RegClass;
3364 bool IsCopy = MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
3365 MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
3366 MI->getOpcode() == AMDGPU::S_MOV_B32;
3367 Register ResultReg =
3368 IsCopy ? MI->getOperand(0).getReg()
3369 : RS->scavengeRegisterBackwards(*RC, MI, false, 0);
3370
3371 int64_t Offset = FrameInfo.getObjectOffset(Index);
3372
3373 // The carry-out lane of Add is unused, so it is safe to write with
3374 // S_MOV_B32 even into a VGPR.
3375 auto MaterializeCarryOutOffset = [&](MachineInstrBuilder &Add) {
3376 Register ConstOffsetReg =
3377 isWave32 ? Add.getReg(1)
3378 : Register(getSubReg(Add.getReg(1), AMDGPU::sub0));
3379 BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::S_MOV_B32), ConstOffsetReg)
3380 .addImm(Offset);
3381 return ConstOffsetReg;
3382 };
3383
3384 if (Offset == 0) {
3385 unsigned OpCode =
3386 IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
3387 Register TmpResultReg = ResultReg;
3388 if (IsSALU && LiveSCC) {
3389 TmpResultReg = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
3390 MI, false, 0);
3391 }
3392
3393 auto Shift = BuildMI(*MBB, MI, DL, TII->get(OpCode), TmpResultReg);
3394 if (OpCode == AMDGPU::V_LSHRREV_B32_e64)
3395 // For V_LSHRREV, the operands are reversed (the shift count goes
3396 // first).
3397 Shift.addImm(ST.getWavefrontSizeLog2()).addReg(FrameReg);
3398 else
3399 Shift.addReg(FrameReg).addImm(ST.getWavefrontSizeLog2());
3400 if (IsSALU && !LiveSCC)
3401 Shift.getInstr()->getOperand(3).setIsDead(); // Mark SCC as dead.
3402 if (IsSALU && LiveSCC) {
3403 Register NewDest;
3404 if (IsCopy) {
3405 assert(ResultReg.isPhysical());
3406 NewDest = ResultReg;
3407 } else {
3408 NewDest = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3409 Shift, false, 0);
3410 }
3411 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), NewDest)
3412 .addReg(TmpResultReg);
3413 ResultReg = NewDest;
3414 }
3415 } else {
3417 if (!IsSALU) {
3418 if ((MIB = TII->getAddNoCarry(*MBB, MI, DL, ResultReg, *RS)) !=
3419 nullptr) {
3420 // Reuse ResultReg in intermediate step.
3421 Register ScaledReg = ResultReg;
3422
3423 BuildMI(*MBB, *MIB, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3424 ScaledReg)
3425 .addImm(ST.getWavefrontSizeLog2())
3426 .addReg(FrameReg);
3427
3428 const bool IsVOP2 = MIB->getOpcode() == AMDGPU::V_ADD_U32_e32;
3429
3430 // TODO: Fold if use instruction is another add of a constant.
3431 if (IsVOP2 ||
3432 AMDGPU::isInlinableLiteral32(Offset, ST.hasInv2PiInlineImm())) {
3433 // FIXME: This can fail
3434 MIB.addImm(Offset);
3435 MIB.addReg(ScaledReg, RegState::Kill);
3436 if (!IsVOP2)
3437 MIB.addImm(0); // clamp bit
3438 } else {
3439 assert(MIB->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 &&
3440 "Need to reuse carry out register");
3441
3442 MIB.addReg(MaterializeCarryOutOffset(MIB), RegState::Kill);
3443 MIB.addReg(ScaledReg, RegState::Kill);
3444 MIB.addImm(0); // clamp bit
3445 }
3446 }
3447 }
3448 if (!MIB || IsSALU) {
3449 // We have to produce a carry out, and there isn't a free SGPR pair
3450 // for it. We can keep the whole computation on the SALU to avoid
3451 // clobbering an additional register at the cost of an extra mov.
3452
3453 // We may have 1 free scratch SGPR even though a carry out is
3454 // unavailable. Only one additional mov is needed.
3455 Register TmpScaledReg = IsCopy && IsSALU
3456 ? ResultReg
3457 : RS->scavengeRegisterBackwards(
3458 AMDGPU::SReg_32_XM0RegClass, MI,
3459 false, 0, /*AllowSpill=*/false);
3460 Register ScaledReg = TmpScaledReg.isValid() ? TmpScaledReg : FrameReg;
3461 Register TmpResultReg = ScaledReg;
3462
3463 if (!LiveSCC) {
3464 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_LSHR_B32), TmpResultReg)
3465 .addReg(FrameReg)
3466 .addImm(ST.getWavefrontSizeLog2());
3467 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), TmpResultReg)
3468 .addReg(TmpResultReg, RegState::Kill)
3469 .addImm(Offset);
3470 } else {
3471 TmpResultReg = RS->scavengeRegisterBackwards(
3472 AMDGPU::VGPR_32RegClass, MI, false, 0, /*AllowSpill=*/true);
3473
3475 if ((Add = TII->getAddNoCarry(*MBB, MI, DL, TmpResultReg, *RS))) {
3476 BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3477 TmpResultReg)
3478 .addImm(ST.getWavefrontSizeLog2())
3479 .addReg(FrameReg);
3480 if (Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
3481 Add.addReg(MaterializeCarryOutOffset(Add), RegState::Kill)
3482 .addReg(TmpResultReg, RegState::Kill)
3483 .addImm(0);
3484 } else
3485 Add.addImm(Offset).addReg(TmpResultReg, RegState::Kill);
3486 } else {
3487 assert(Offset > 0 && isUInt<24>(2 * ST.getMaxWaveScratchSize()) &&
3488 "offset is unsafe for v_mad_u32_u24");
3489
3490 // We start with a frame pointer with a wave space value, and
3491 // an offset in lane-space. We are materializing a lane space
3492 // value. We can either do a right shift of the frame pointer
3493 // to get to lane space, or a left shift of the offset to get
3494 // to wavespace. We can right shift after the computation to
3495 // get back to the desired per-lane value. We are using the
3496 // mad_u32_u24 primarily as an add with no carry out clobber.
3497 bool IsInlinableLiteral =
3498 AMDGPU::isInlinableLiteral32(Offset, ST.hasInv2PiInlineImm());
3499 if (!IsInlinableLiteral) {
3500 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32),
3501 TmpResultReg)
3502 .addImm(Offset);
3503 }
3504
3505 Add = BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MAD_U32_U24_e64),
3506 TmpResultReg);
3507
3508 if (!IsInlinableLiteral) {
3509 Add.addReg(TmpResultReg, RegState::Kill);
3510 } else {
3511 // We fold the offset into mad itself if its inlinable.
3512 Add.addImm(Offset);
3513 }
3514 Add.addImm(ST.getWavefrontSize()).addReg(FrameReg).addImm(0);
3515 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3516 TmpResultReg)
3517 .addImm(ST.getWavefrontSizeLog2())
3518 .addReg(TmpResultReg);
3519 }
3520
3521 Register NewDest;
3522 if (IsCopy) {
3523 NewDest = ResultReg;
3524 } else {
3525 NewDest = RS->scavengeRegisterBackwards(
3526 AMDGPU::SReg_32_XM0RegClass, *Add, false, 0,
3527 /*AllowSpill=*/true);
3528 }
3529
3530 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
3531 NewDest)
3532 .addReg(TmpResultReg);
3533 ResultReg = NewDest;
3534 }
3535 if (!IsSALU)
3536 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::COPY), ResultReg)
3537 .addReg(TmpResultReg, RegState::Kill);
3538 // If there were truly no free SGPRs, we need to undo everything.
3539 if (!TmpScaledReg.isValid()) {
3540 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), ScaledReg)
3541 .addReg(ScaledReg, RegState::Kill)
3542 .addImm(-Offset);
3543 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_LSHL_B32), ScaledReg)
3544 .addReg(FrameReg)
3545 .addImm(ST.getWavefrontSizeLog2());
3546 }
3547 }
3548 }
3549
3550 // Don't introduce an extra copy if we're just materializing in a mov.
3551 if (IsCopy) {
3552 MI->eraseFromParent();
3553 return true;
3554 }
3555 FIOp->ChangeToRegister(ResultReg, false, false, true);
3556 return false;
3557 }
3558
3559 if (IsMUBUF) {
3560 // Disable offen so we don't need a 0 vgpr base.
3561 assert(
3562 static_cast<int>(FIOperandNum) ==
3563 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::vaddr));
3564
3565 auto &SOffset = *TII->getNamedOperand(*MI, AMDGPU::OpName::soffset);
3566 assert((SOffset.isImm() && SOffset.getImm() == 0));
3567
3568 if (FrameReg != AMDGPU::NoRegister)
3569 SOffset.ChangeToRegister(FrameReg, false);
3570
3571 int64_t Offset = FrameInfo.getObjectOffset(Index);
3572 int64_t OldImm =
3573 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm();
3574 int64_t NewOffset = OldImm + Offset;
3575
3576 if (TII->isLegalMUBUFImmOffset(NewOffset) &&
3577 buildMUBUFOffsetLoadStore(ST, FrameInfo, MI, Index, NewOffset)) {
3578 MI->eraseFromParent();
3579 return true;
3580 }
3581 }
3582
3583 // If the offset is simply too big, don't convert to a scratch wave offset
3584 // relative index.
3585
3587 if (!TII->isImmOperandLegal(*MI, FIOperandNum, *FIOp)) {
3588 Register TmpReg =
3589 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false, 0);
3590 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
3591 .addImm(Offset);
3592 FIOp->ChangeToRegister(TmpReg, false, false, true);
3593 }
3594
3595 return false;
3596}
3597
3601
3603 return getEncodingValue(Reg) & AMDGPU::HWEncoding::REG_IDX_MASK;
3604}
3605
3606static const TargetRegisterClass *
3608 if (BitWidth == 64)
3609 return &AMDGPU::VReg_64RegClass;
3610 if (BitWidth == 96)
3611 return &AMDGPU::VReg_96RegClass;
3612 if (BitWidth == 128)
3613 return &AMDGPU::VReg_128RegClass;
3614 if (BitWidth == 160)
3615 return &AMDGPU::VReg_160RegClass;
3616 if (BitWidth == 192)
3617 return &AMDGPU::VReg_192RegClass;
3618 if (BitWidth == 224)
3619 return &AMDGPU::VReg_224RegClass;
3620 if (BitWidth == 256)
3621 return &AMDGPU::VReg_256RegClass;
3622 if (BitWidth == 288)
3623 return &AMDGPU::VReg_288RegClass;
3624 if (BitWidth == 320)
3625 return &AMDGPU::VReg_320RegClass;
3626 if (BitWidth == 352)
3627 return &AMDGPU::VReg_352RegClass;
3628 if (BitWidth == 384)
3629 return &AMDGPU::VReg_384RegClass;
3630 if (BitWidth == 512)
3631 return &AMDGPU::VReg_512RegClass;
3632 if (BitWidth == 1024)
3633 return &AMDGPU::VReg_1024RegClass;
3634
3635 return nullptr;
3636}
3637
3638static const TargetRegisterClass *
3640 if (BitWidth == 64)
3641 return &AMDGPU::VReg_64_Align2RegClass;
3642 if (BitWidth == 96)
3643 return &AMDGPU::VReg_96_Align2RegClass;
3644 if (BitWidth == 128)
3645 return &AMDGPU::VReg_128_Align2RegClass;
3646 if (BitWidth == 160)
3647 return &AMDGPU::VReg_160_Align2RegClass;
3648 if (BitWidth == 192)
3649 return &AMDGPU::VReg_192_Align2RegClass;
3650 if (BitWidth == 224)
3651 return &AMDGPU::VReg_224_Align2RegClass;
3652 if (BitWidth == 256)
3653 return &AMDGPU::VReg_256_Align2RegClass;
3654 if (BitWidth == 288)
3655 return &AMDGPU::VReg_288_Align2RegClass;
3656 if (BitWidth == 320)
3657 return &AMDGPU::VReg_320_Align2RegClass;
3658 if (BitWidth == 352)
3659 return &AMDGPU::VReg_352_Align2RegClass;
3660 if (BitWidth == 384)
3661 return &AMDGPU::VReg_384_Align2RegClass;
3662 if (BitWidth == 512)
3663 return &AMDGPU::VReg_512_Align2RegClass;
3664 if (BitWidth == 1024)
3665 return &AMDGPU::VReg_1024_Align2RegClass;
3666
3667 return nullptr;
3668}
3669
3670const TargetRegisterClass *
3672 if (BitWidth == 1)
3673 return &AMDGPU::VReg_1RegClass;
3674 if (BitWidth == 16)
3675 return &AMDGPU::VGPR_16RegClass;
3676 if (BitWidth == 32)
3677 return &AMDGPU::VGPR_32RegClass;
3678 return ST.needsAlignedVGPRs() ? getAlignedVGPRClassForBitWidth(BitWidth)
3680}
3681
3682const TargetRegisterClass *
3684 if (BitWidth <= 32)
3685 return &AMDGPU::VGPR_32_Lo256RegClass;
3686 if (BitWidth <= 64)
3687 return &AMDGPU::VReg_64_Lo256_Align2RegClass;
3688 if (BitWidth <= 96)
3689 return &AMDGPU::VReg_96_Lo256_Align2RegClass;
3690 if (BitWidth <= 128)
3691 return &AMDGPU::VReg_128_Lo256_Align2RegClass;
3692 if (BitWidth <= 160)
3693 return &AMDGPU::VReg_160_Lo256_Align2RegClass;
3694 if (BitWidth <= 192)
3695 return &AMDGPU::VReg_192_Lo256_Align2RegClass;
3696 if (BitWidth <= 224)
3697 return &AMDGPU::VReg_224_Lo256_Align2RegClass;
3698 if (BitWidth <= 256)
3699 return &AMDGPU::VReg_256_Lo256_Align2RegClass;
3700 if (BitWidth <= 288)
3701 return &AMDGPU::VReg_288_Lo256_Align2RegClass;
3702 if (BitWidth <= 320)
3703 return &AMDGPU::VReg_320_Lo256_Align2RegClass;
3704 if (BitWidth <= 352)
3705 return &AMDGPU::VReg_352_Lo256_Align2RegClass;
3706 if (BitWidth <= 384)
3707 return &AMDGPU::VReg_384_Lo256_Align2RegClass;
3708 if (BitWidth <= 512)
3709 return &AMDGPU::VReg_512_Lo256_Align2RegClass;
3710 if (BitWidth <= 1024)
3711 return &AMDGPU::VReg_1024_Lo256_Align2RegClass;
3712
3713 return nullptr;
3714}
3715
3716static const TargetRegisterClass *
3718 if (BitWidth == 64)
3719 return &AMDGPU::AReg_64RegClass;
3720 if (BitWidth == 96)
3721 return &AMDGPU::AReg_96RegClass;
3722 if (BitWidth == 128)
3723 return &AMDGPU::AReg_128RegClass;
3724 if (BitWidth == 160)
3725 return &AMDGPU::AReg_160RegClass;
3726 if (BitWidth == 192)
3727 return &AMDGPU::AReg_192RegClass;
3728 if (BitWidth == 224)
3729 return &AMDGPU::AReg_224RegClass;
3730 if (BitWidth == 256)
3731 return &AMDGPU::AReg_256RegClass;
3732 if (BitWidth == 288)
3733 return &AMDGPU::AReg_288RegClass;
3734 if (BitWidth == 320)
3735 return &AMDGPU::AReg_320RegClass;
3736 if (BitWidth == 352)
3737 return &AMDGPU::AReg_352RegClass;
3738 if (BitWidth == 384)
3739 return &AMDGPU::AReg_384RegClass;
3740 if (BitWidth == 512)
3741 return &AMDGPU::AReg_512RegClass;
3742 if (BitWidth == 1024)
3743 return &AMDGPU::AReg_1024RegClass;
3744
3745 return nullptr;
3746}
3747
3748static const TargetRegisterClass *
3750 if (BitWidth == 64)
3751 return &AMDGPU::AReg_64_Align2RegClass;
3752 if (BitWidth == 96)
3753 return &AMDGPU::AReg_96_Align2RegClass;
3754 if (BitWidth == 128)
3755 return &AMDGPU::AReg_128_Align2RegClass;
3756 if (BitWidth == 160)
3757 return &AMDGPU::AReg_160_Align2RegClass;
3758 if (BitWidth == 192)
3759 return &AMDGPU::AReg_192_Align2RegClass;
3760 if (BitWidth == 224)
3761 return &AMDGPU::AReg_224_Align2RegClass;
3762 if (BitWidth == 256)
3763 return &AMDGPU::AReg_256_Align2RegClass;
3764 if (BitWidth == 288)
3765 return &AMDGPU::AReg_288_Align2RegClass;
3766 if (BitWidth == 320)
3767 return &AMDGPU::AReg_320_Align2RegClass;
3768 if (BitWidth == 352)
3769 return &AMDGPU::AReg_352_Align2RegClass;
3770 if (BitWidth == 384)
3771 return &AMDGPU::AReg_384_Align2RegClass;
3772 if (BitWidth == 512)
3773 return &AMDGPU::AReg_512_Align2RegClass;
3774 if (BitWidth == 1024)
3775 return &AMDGPU::AReg_1024_Align2RegClass;
3776
3777 return nullptr;
3778}
3779
3780const TargetRegisterClass *
3782 if (BitWidth == 16)
3783 return &AMDGPU::AGPR_LO16RegClass;
3784 if (BitWidth == 32)
3785 return &AMDGPU::AGPR_32RegClass;
3786 return ST.needsAlignedVGPRs() ? getAlignedAGPRClassForBitWidth(BitWidth)
3788}
3789
3790static const TargetRegisterClass *
3792 if (BitWidth == 64)
3793 return &AMDGPU::AV_64RegClass;
3794 if (BitWidth == 96)
3795 return &AMDGPU::AV_96RegClass;
3796 if (BitWidth == 128)
3797 return &AMDGPU::AV_128RegClass;
3798 if (BitWidth == 160)
3799 return &AMDGPU::AV_160RegClass;
3800 if (BitWidth == 192)
3801 return &AMDGPU::AV_192RegClass;
3802 if (BitWidth == 224)
3803 return &AMDGPU::AV_224RegClass;
3804 if (BitWidth == 256)
3805 return &AMDGPU::AV_256RegClass;
3806 if (BitWidth == 288)
3807 return &AMDGPU::AV_288RegClass;
3808 if (BitWidth == 320)
3809 return &AMDGPU::AV_320RegClass;
3810 if (BitWidth == 352)
3811 return &AMDGPU::AV_352RegClass;
3812 if (BitWidth == 384)
3813 return &AMDGPU::AV_384RegClass;
3814 if (BitWidth == 512)
3815 return &AMDGPU::AV_512RegClass;
3816 if (BitWidth == 1024)
3817 return &AMDGPU::AV_1024RegClass;
3818
3819 return nullptr;
3820}
3821
3822static const TargetRegisterClass *
3824 if (BitWidth == 64)
3825 return &AMDGPU::AV_64_Align2RegClass;
3826 if (BitWidth == 96)
3827 return &AMDGPU::AV_96_Align2RegClass;
3828 if (BitWidth == 128)
3829 return &AMDGPU::AV_128_Align2RegClass;
3830 if (BitWidth == 160)
3831 return &AMDGPU::AV_160_Align2RegClass;
3832 if (BitWidth == 192)
3833 return &AMDGPU::AV_192_Align2RegClass;
3834 if (BitWidth == 224)
3835 return &AMDGPU::AV_224_Align2RegClass;
3836 if (BitWidth == 256)
3837 return &AMDGPU::AV_256_Align2RegClass;
3838 if (BitWidth == 288)
3839 return &AMDGPU::AV_288_Align2RegClass;
3840 if (BitWidth == 320)
3841 return &AMDGPU::AV_320_Align2RegClass;
3842 if (BitWidth == 352)
3843 return &AMDGPU::AV_352_Align2RegClass;
3844 if (BitWidth == 384)
3845 return &AMDGPU::AV_384_Align2RegClass;
3846 if (BitWidth == 512)
3847 return &AMDGPU::AV_512_Align2RegClass;
3848 if (BitWidth == 1024)
3849 return &AMDGPU::AV_1024_Align2RegClass;
3850
3851 return nullptr;
3852}
3853
3854const TargetRegisterClass *
3856 if (BitWidth == 32)
3857 return &AMDGPU::AV_32RegClass;
3858 return ST.needsAlignedVGPRs()
3861}
3862
3863const TargetRegisterClass *
3865 // TODO: In principle this should use AV classes for gfx908 too. This is
3866 // limited to 90a+ to avoid regressing special case copy optimizations which
3867 // need new handling. The core issue is that it's not possible to directly
3868 // copy between AGPRs on gfx908, and the current optimizations around that
3869 // expect to see copies to VGPR.
3870 return ST.hasGFX90AInsts() ? getVectorSuperClassForBitWidth(BitWidth)
3872}
3873
3874const TargetRegisterClass *
3876 if (BitWidth == 16 || BitWidth == 32)
3877 return &AMDGPU::SReg_32RegClass;
3878 if (BitWidth == 64)
3879 return &AMDGPU::SReg_64RegClass;
3880 if (BitWidth == 96)
3881 return &AMDGPU::SGPR_96RegClass;
3882 if (BitWidth == 128)
3883 return &AMDGPU::SGPR_128RegClass;
3884 if (BitWidth == 160)
3885 return &AMDGPU::SGPR_160RegClass;
3886 if (BitWidth == 192)
3887 return &AMDGPU::SGPR_192RegClass;
3888 if (BitWidth == 224)
3889 return &AMDGPU::SGPR_224RegClass;
3890 if (BitWidth == 256)
3891 return &AMDGPU::SGPR_256RegClass;
3892 if (BitWidth == 288)
3893 return &AMDGPU::SGPR_288RegClass;
3894 if (BitWidth == 320)
3895 return &AMDGPU::SGPR_320RegClass;
3896 if (BitWidth == 352)
3897 return &AMDGPU::SGPR_352RegClass;
3898 if (BitWidth == 384)
3899 return &AMDGPU::SGPR_384RegClass;
3900 if (BitWidth == 512)
3901 return &AMDGPU::SGPR_512RegClass;
3902 if (BitWidth == 1024)
3903 return &AMDGPU::SGPR_1024RegClass;
3904
3905 return nullptr;
3906}
3907
3909 Register Reg) const {
3910 const TargetRegisterClass *RC;
3911 if (Reg.isVirtual())
3912 RC = MRI.getRegClass(Reg);
3913 else
3914 RC = getPhysRegBaseClass(Reg);
3915 return RC && isSGPRClass(RC);
3916}
3917
3918const TargetRegisterClass *
3920 unsigned Size = getRegSizeInBits(*SRC);
3921
3922 switch (SRC->getID()) {
3923 default:
3924 break;
3925 case AMDGPU::VS_32_Lo256RegClassID:
3926 case AMDGPU::VS_64_Lo256RegClassID:
3927 return getAllocatableClass(getAlignedLo256VGPRClassForBitWidth(Size));
3928 }
3929
3930 const TargetRegisterClass *VRC =
3931 getAllocatableClass(getVGPRClassForBitWidth(Size));
3932 assert(VRC && "Invalid register class size");
3933 return VRC;
3934}
3935
3936const TargetRegisterClass *
3938 unsigned Size = getRegSizeInBits(*SRC);
3940 assert(ARC && "Invalid register class size");
3941 return ARC;
3942}
3943
3944const TargetRegisterClass *
3946 unsigned Size = getRegSizeInBits(*SRC);
3948 assert(ARC && "Invalid register class size");
3949 return ARC;
3950}
3951
3952const TargetRegisterClass *
3954 unsigned Size = getRegSizeInBits(*VRC);
3955 if (Size == 32)
3956 return &AMDGPU::SGPR_32RegClass;
3958 assert(SRC && "Invalid register class size");
3959 return SRC;
3960}
3961
3962const TargetRegisterClass *
3964 const TargetRegisterClass *SubRC,
3965 unsigned SubIdx) const {
3966 // Ensure this subregister index is aligned in the super register.
3967 const TargetRegisterClass *MatchRC =
3968 getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
3969 return MatchRC && MatchRC->hasSubClassEq(SuperRC) ? MatchRC : nullptr;
3970}
3971
3972bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const {
3975 return !ST.hasMFMAInlineLiteralBug();
3976
3977 return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
3978 OpType <= AMDGPU::OPERAND_SRC_LAST;
3979}
3980
3981bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const {
3982 // TODO: 64-bit operands have extending behavior from 32-bit literal.
3983 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
3985}
3986
3987/// Returns a lowest register that is not used at any point in the function.
3988/// If all registers are used, then this function will return
3989/// AMDGPU::NoRegister. If \p ReserveHighestRegister = true, then return
3990/// highest unused register.
3992 const MachineRegisterInfo &MRI, const TargetRegisterClass *RC,
3993 const MachineFunction &MF, bool ReserveHighestRegister) const {
3994 // Never offer VCC as an unused register.
3995 auto isVCC = [](MCRegister Reg) {
3996 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::VCC_HI;
3997 };
3998
3999 if (ReserveHighestRegister) {
4000 for (MCRegister Reg : reverse(*RC))
4001 if (MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4002 return Reg;
4003 } else {
4004 for (MCRegister Reg : *RC)
4005 if (MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4006 return Reg;
4007 }
4008 return MCRegister();
4009}
4010
4012 const RegisterBankInfo &RBI,
4013 Register Reg) const {
4014 auto *RB = RBI.getRegBank(Reg, MRI, *this);
4015 if (!RB)
4016 return false;
4017
4018 return !RBI.isDivergentRegBank(RB);
4019}
4020
4022 unsigned EltSize) const {
4023 const unsigned RegBitWidth = AMDGPU::getRegBitWidth(*RC);
4024 assert(RegBitWidth >= 32 && RegBitWidth <= 1024 && EltSize >= 2);
4025
4026 const unsigned RegHalves = RegBitWidth / 16;
4027 const unsigned EltHalves = EltSize / 2;
4028 assert(RegSplitParts.size() + 1 >= EltHalves);
4029
4030 const std::vector<int16_t> &Parts = RegSplitParts[EltHalves - 1];
4031 const unsigned NumParts = RegHalves / EltHalves;
4032
4033 return ArrayRef(Parts.data(), NumParts);
4034}
4035
4038 Register Reg) const {
4039 return Reg.isVirtual() ? MRI.getRegClass(Reg) : getPhysRegBaseClass(Reg);
4040}
4041
4042const TargetRegisterClass *
4044 const MachineOperand &MO) const {
4045 const TargetRegisterClass *SrcRC = getRegClassForReg(MRI, MO.getReg());
4046 return getSubRegisterClass(SrcRC, MO.getSubReg());
4047}
4048
4050 Register Reg) const {
4051 const TargetRegisterClass *RC = getRegClassForReg(MRI, Reg);
4052 // Registers without classes are unaddressable, SGPR-like registers.
4053 return RC && isVGPRClass(RC);
4054}
4055
4057 Register Reg) const {
4058 const TargetRegisterClass *RC = getRegClassForReg(MRI, Reg);
4059
4060 // Registers without classes are unaddressable, SGPR-like registers.
4061 return RC && isAGPRClass(RC);
4062}
4063
4065 MachineFunction &MF) const {
4066 unsigned MinOcc = ST.getOccupancyWithWorkGroupSizes(MF).first;
4067 switch (RC->getID()) {
4068 default:
4069 return AMDGPUGenRegisterInfo::getRegPressureLimit(RC, MF);
4070 case AMDGPU::VGPR_32RegClassID:
4071 return std::min(
4072 ST.getMaxNumVGPRs(
4073 MinOcc,
4075 ST.getMaxNumVGPRs(MF));
4076 case AMDGPU::SGPR_32RegClassID:
4077 case AMDGPU::SGPR_LO16RegClassID:
4078 return std::min(ST.getMaxNumSGPRs(MinOcc, true), ST.getMaxNumSGPRs(MF));
4079 }
4080}
4081
4083 unsigned Idx) const {
4084 switch (static_cast<AMDGPU::RegisterPressureSets>(Idx)) {
4085 case AMDGPU::RegisterPressureSets::VGPR_32:
4086 case AMDGPU::RegisterPressureSets::AGPR_32:
4087 return getRegPressureLimit(&AMDGPU::VGPR_32RegClass,
4088 const_cast<MachineFunction &>(MF));
4089 case AMDGPU::RegisterPressureSets::SReg_32:
4090 return getRegPressureLimit(&AMDGPU::SGPR_32RegClass,
4091 const_cast<MachineFunction &>(MF));
4092 }
4093
4094 llvm_unreachable("Unexpected register pressure set!");
4095}
4096
4097const int *SIRegisterInfo::getRegUnitPressureSets(MCRegUnit RegUnit) const {
4098 static const int Empty[] = { -1 };
4099
4100 if (RegPressureIgnoredUnits[static_cast<unsigned>(RegUnit)])
4101 return Empty;
4102
4103 return AMDGPUGenRegisterInfo::getRegUnitPressureSets(RegUnit);
4104}
4105
4107 ArrayRef<MCPhysReg> Order,
4109 const MachineFunction &MF,
4110 const VirtRegMap *VRM,
4111 const LiveRegMatrix *Matrix) const {
4112
4113 const MachineRegisterInfo &MRI = MF.getRegInfo();
4114 const SIRegisterInfo *TRI = ST.getRegisterInfo();
4115
4116 std::pair<unsigned, Register> Hint = MRI.getRegAllocationHint(VirtReg);
4117
4118 switch (Hint.first) {
4119 case AMDGPURI::Size32: {
4120 Register Paired = Hint.second;
4121 assert(Paired);
4122 Register PairedPhys;
4123 if (Paired.isPhysical()) {
4124 PairedPhys =
4125 getMatchingSuperReg(Paired, AMDGPU::lo16, &AMDGPU::VGPR_32RegClass);
4126 } else if (VRM && VRM->hasPhys(Paired)) {
4127 PairedPhys = getMatchingSuperReg(VRM->getPhys(Paired), AMDGPU::lo16,
4128 &AMDGPU::VGPR_32RegClass);
4129 }
4130
4131 // Prefer the paired physreg.
4132 if (PairedPhys)
4133 // isLo(Paired) is implicitly true here from the API of
4134 // getMatchingSuperReg.
4135 Hints.push_back(PairedPhys);
4136 return false;
4137 }
4138 case AMDGPURI::Size16: {
4139 Register Paired = Hint.second;
4140 assert(Paired);
4141 Register PairedPhys;
4142 if (Paired.isPhysical()) {
4143 PairedPhys = TRI->getSubReg(Paired, AMDGPU::lo16);
4144 } else if (VRM && VRM->hasPhys(Paired)) {
4145 PairedPhys = TRI->getSubReg(VRM->getPhys(Paired), AMDGPU::lo16);
4146 }
4147
4148 // First prefer the paired physreg.
4149 if (PairedPhys)
4150 Hints.push_back(PairedPhys);
4151 else {
4152 // Add all the lo16 physregs.
4153 // When the Paired operand has not yet been assigned a physreg it is
4154 // better to try putting VirtReg in a lo16 register, because possibly
4155 // later Paired can be assigned to the overlapping register and the COPY
4156 // can be eliminated.
4157 for (MCPhysReg PhysReg : Order) {
4158 if (PhysReg == PairedPhys || AMDGPU::isHi16Reg(PhysReg, *this))
4159 continue;
4160 if (AMDGPU::VGPR_16RegClass.contains(PhysReg) &&
4161 !MRI.isReserved(PhysReg))
4162 Hints.push_back(PhysReg);
4163 }
4164 }
4165 return false;
4166 }
4167 default:
4168 return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
4169 VRM);
4170 }
4171}
4172
4174 // Not a callee saved register.
4175 return AMDGPU::SGPR30_SGPR31;
4176}
4177
4178const TargetRegisterClass *
4180 const RegisterBank &RB) const {
4181 switch (RB.getID()) {
4182 case AMDGPU::VGPRRegBankID:
4184 std::max(ST.useRealTrue16Insts() ? 16u : 32u, Size));
4185 case AMDGPU::VCCRegBankID:
4186 assert(Size == 1);
4187 return getWaveMaskRegClass();
4188 case AMDGPU::SGPRRegBankID:
4189 return getSGPRClassForBitWidth(std::max(32u, Size));
4190 case AMDGPU::AGPRRegBankID:
4191 return getAGPRClassForBitWidth(std::max(32u, Size));
4192 default:
4193 llvm_unreachable("unknown register bank");
4194 }
4195}
4196
4198 Register Reg, const MachineRegisterInfo &MRI) const {
4199 const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg);
4200 if (const RegisterBank *RB = dyn_cast<const RegisterBank *>(RCOrRB))
4201 return getRegClassForTypeOnBank(MRI.getType(Reg), *RB);
4202
4203 if (const auto *RC = dyn_cast<const TargetRegisterClass *>(RCOrRB))
4204 return getAllocatableClass(RC);
4205
4206 return nullptr;
4207}
4208
4210 return isWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC;
4211}
4212
4214 return isWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
4215}
4216
4218 // VGPR tuples have an alignment requirement on gfx90a variants.
4219 return ST.needsAlignedVGPRs() ? &AMDGPU::VReg_64_Align2RegClass
4220 : &AMDGPU::VReg_64RegClass;
4221}
4222
4223// Find reaching register definition
4227 LiveIntervals *LIS) const {
4228 auto &MDT = LIS->getDomTree();
4229 SlotIndex UseIdx = LIS->getInstructionIndex(Use);
4230 SlotIndex DefIdx;
4231
4232 if (Reg.isVirtual()) {
4233 if (!LIS->hasInterval(Reg))
4234 return nullptr;
4235 LiveInterval &LI = LIS->getInterval(Reg);
4236 LaneBitmask SubLanes = SubReg ? getSubRegIndexLaneMask(SubReg)
4237 : MRI.getMaxLaneMaskForVReg(Reg);
4238 VNInfo *V = nullptr;
4239 if (LI.hasSubRanges()) {
4240 for (auto &S : LI.subranges()) {
4241 if ((S.LaneMask & SubLanes) == SubLanes) {
4242 V = S.getVNInfoAt(UseIdx);
4243 break;
4244 }
4245 }
4246 } else {
4247 V = LI.getVNInfoAt(UseIdx);
4248 }
4249 if (!V)
4250 return nullptr;
4251 DefIdx = V->def;
4252 } else {
4253 // Find last def.
4254 for (MCRegUnit Unit : regunits(Reg.asMCReg())) {
4255 LiveRange &LR = LIS->getRegUnit(Unit);
4256 if (VNInfo *V = LR.getVNInfoAt(UseIdx)) {
4257 if (!DefIdx.isValid() ||
4258 MDT.dominates(LIS->getInstructionFromIndex(DefIdx),
4259 LIS->getInstructionFromIndex(V->def)))
4260 DefIdx = V->def;
4261 } else {
4262 return nullptr;
4263 }
4264 }
4265 }
4266
4267 MachineInstr *Def = LIS->getInstructionFromIndex(DefIdx);
4268
4269 if (!Def || !MDT.dominates(Def, &Use))
4270 return nullptr;
4271
4272 assert(Def->modifiesRegister(Reg, this));
4273
4274 return Def;
4275}
4276
4278 assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
4279
4280 for (const TargetRegisterClass *RC :
4281 {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
4282 &AMDGPU::AGPR_32RegClass}) {
4283 if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
4284 return Super;
4285 }
4286 if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::hi16,
4287 &AMDGPU::VGPR_32RegClass)) {
4288 return Super;
4289 }
4290
4291 return AMDGPU::NoRegister;
4292}
4293
4295 if (!ST.needsAlignedVGPRs())
4296 return true;
4297
4298 if (isVGPRClass(&RC))
4299 return RC.hasSuperClassEq(getVGPRClassForBitWidth(getRegSizeInBits(RC)));
4300 if (isAGPRClass(&RC))
4301 return RC.hasSuperClassEq(getAGPRClassForBitWidth(getRegSizeInBits(RC)));
4302 if (isVectorSuperClass(&RC))
4303 return RC.hasSuperClassEq(
4304 getVectorSuperClassForBitWidth(getRegSizeInBits(RC)));
4305
4306 assert(&RC != &AMDGPU::VS_64RegClass);
4307
4308 return true;
4309}
4310
4313 return ArrayRef(AMDGPU::SGPR_128RegClass.begin(), ST.getMaxNumSGPRs(MF) / 4);
4314}
4315
4318 return ArrayRef(AMDGPU::SGPR_64RegClass.begin(), ST.getMaxNumSGPRs(MF) / 2);
4319}
4320
4323 return ArrayRef(AMDGPU::SGPR_32RegClass.begin(), ST.getMaxNumSGPRs(MF));
4324}
4325
4326unsigned
4328 unsigned SubReg) const {
4329 switch (RC->TSFlags & SIRCFlags::RegKindMask) {
4330 case SIRCFlags::HasSGPR:
4331 return std::min(128u, getSubRegIdxSize(SubReg));
4332 case SIRCFlags::HasAGPR:
4333 case SIRCFlags::HasVGPR:
4335 return std::min(32u, getSubRegIdxSize(SubReg));
4336 default:
4337 break;
4338 }
4339 return 0;
4340}
4341
4343 const TargetRegisterClass &RC,
4344 bool IncludeCalls) const {
4345 unsigned NumArchVGPRs = ST.getAddressableNumArchVGPRs();
4347 (RC.getID() == AMDGPU::VGPR_32RegClassID)
4348 ? RC.getRegisters().take_front(NumArchVGPRs)
4349 : RC.getRegisters();
4350 for (MCPhysReg Reg : reverse(Registers)) {
4351 if (Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
4352 MRI.isPhysRegUsed(Reg, /*SkipRegMaskTest=*/!IncludeCalls))
4353 return getHWRegIndex(Reg) + 1;
4354 }
4355 return 0;
4356}
4357
4360 const MachineFunction &MF) const {
4362 const SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
4363 if (FuncInfo->checkFlag(Reg, AMDGPU::VirtRegFlag::WWM_REG))
4364 RegFlags.push_back("WWM_REG");
4365 return RegFlags;
4366}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Live Register Matrix
A set of register units.
#define I(x, y, z)
Definition MD5.cpp:57
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
if(PassOpts->AAPipeline)
This file declares the machine register scavenger class.
SI Pre allocate WWM Registers
static MachineInstrBuilder spillVGPRtoAGPR(const GCNSubtarget &ST, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, int Index, unsigned Lane, unsigned ValueReg, bool IsKill, bool NeedsCFI)
static int getOffenMUBUFStore(unsigned Opc)
static const TargetRegisterClass * getAnyAGPRClassForBitWidth(unsigned BitWidth)
static int getOffsetMUBUFLoad(unsigned Opc)
static const std::array< unsigned, 17 > SubRegFromChannelTableWidthMap
static unsigned getNumSubRegsForSpillOp(const MachineInstr &MI, const SIInstrInfo *TII)
static void emitUnsupportedError(const Function &Fn, const MachineInstr &MI, const Twine &ErrMsg)
static const TargetRegisterClass * getAlignedAGPRClassForBitWidth(unsigned BitWidth)
static bool buildMUBUFOffsetLoadStore(const GCNSubtarget &ST, MachineFrameInfo &MFI, MachineBasicBlock::iterator MI, int Index, int64_t Offset)
static cl::opt< bool > EnableSpillCFISavedRegs("amdgpu-spill-cfi-saved-regs", cl::desc("Enable spilling the registers required for CFI emission"), cl::ReallyHidden, cl::init(false), cl::ZeroOrMore)
static unsigned getFlatScratchSpillOpcode(const SIInstrInfo *TII, unsigned LoadStoreOp, unsigned EltSize)
static const TargetRegisterClass * getAlignedVGPRClassForBitWidth(unsigned BitWidth)
static int getOffsetMUBUFStore(unsigned Opc)
static const TargetRegisterClass * getAnyVGPRClassForBitWidth(unsigned BitWidth)
static cl::opt< unsigned > StressSGPRLimit("amdgpu-stress-sgpr", cl::Hidden, cl::init(0), cl::desc("Limit SGPRs to N registers by reserving the rest"))
static cl::opt< bool > EnableSpillSGPRToVGPR("amdgpu-spill-sgpr-to-vgpr", cl::desc("Enable spilling SGPRs to VGPRs"), cl::ReallyHidden, cl::init(true))
static const TargetRegisterClass * getAlignedVectorSuperClassForBitWidth(unsigned BitWidth)
static const TargetRegisterClass * getAnyVectorSuperClassForBitWidth(unsigned BitWidth)
static cl::opt< unsigned > StressAGPRLimit("amdgpu-stress-agpr", cl::Hidden, cl::init(0), cl::desc("Limit AGPRs to N registers by reserving the rest"))
static cl::opt< unsigned > StressVGPRLimit("amdgpu-stress-vgpr", cl::Hidden, cl::init(0), cl::desc("Limit VGPRs to N registers by reserving the rest"))
static bool isFIPlusImmOrVGPR(const SIRegisterInfo &TRI, const MachineInstr &MI)
static int getOffenMUBUFLoad(unsigned Opc)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static const char * getRegisterName(MCRegister Reg)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
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
bool empty() const
Returns whether there are no bits in this bitvector.
Definition BitVector.h:175
A debug info location.
Definition DebugLoc.h:126
Diagnostic information for unsupported feature in backend.
Register getReg() const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:353
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
bool hasInterval(Register Reg) const
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
MachineDominatorTree & getDomTree()
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
This class represents the liveness of a register, stack slot, etc.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
unsigned getID() const
getID() - Return the register class ID number.
ArrayRef< MCPhysReg > getRegisters() const
const uint8_t TSFlags
Configurable target specific flags.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition MCRegister.h:77
Generic base class for all target subtargets.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasCalls() const
Return true if the current function has any function calls.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void setAsmPrinterFlag(AsmPrinterFlagTy Flag)
Set a flag for the AsmPrinter.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
void setImm(int64_t immVal)
int64_t getImm() const
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
void setIsKill(bool Val=true)
LLVM_ABI void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
std::pair< unsigned, Register > getRegAllocationHint(Register VReg) const
getRegAllocationHint - Return the register allocation hint for the specified virtual register.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Holds all the information related to register banks.
virtual bool isDivergentRegBank(const RegisterBank *RB) const
Returns true if the register bank is considered divergent.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
MachineInstr * buildCFIForSGPRToVMEMSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister SGPR, int64_t Offset) const
Create a CFI index describing a spill of a SGPR to VMEM and build a MachineInstr around it.
MachineInstr * buildCFIForVRegToVRegSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCRegister Reg, const MCRegister RegCopy) const
Create a CFI index describing a spill of the VGPR/AGPR Reg to another VGPR/AGPR RegCopy and build a M...
MachineInstr * buildCFIForVGPRToVMEMSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister VGPR, int64_t Offset) const
Create a CFI index describing a spill of a VGPR to VMEM and build a MachineInstr around it.
MachineInstr * buildCFIForSGPRToVGPRSpill(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCRegister SGPR, const MCRegister VGPR, const int Lane) const
Create a CFI index describing a spill of an SGPR to a single lane of a VGPR and build a MachineInstr ...
static bool isFLATScratch(const MachineInstr &MI)
static bool isMUBUF(const MachineInstr &MI)
static bool isVOP3(const MCInstrDesc &Desc)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
MCPhysReg getVGPRToAGPRSpill(int FrameIndex, unsigned Lane) const
Register getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses.
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToVirtualVGPRLanes(int FrameIndex) const
uint32_t getMaskForVGPRBlockOps(Register RegisterBlock) const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToPhysicalVGPRLanes(int FrameIndex) const
bool checkFlag(Register Reg, uint8_t Flag) const
const ReservedRegSet & getWWMReservedRegs() const
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
int64_t getScratchInstrOffset(const MachineInstr *MI) const
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
const TargetRegisterClass * getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, const TargetRegisterClass *SubRC, unsigned SubIdx) const
Returns a register class which is compatible with SuperRC, such that a subregister exists with class ...
ArrayRef< MCPhysReg > getAllSGPR64(const MachineFunction &MF) const
Return all SGPR64 which satisfy the waves per execution unit requirement of the subtarget.
MCRegister findUnusedRegister(const MachineRegisterInfo &MRI, const TargetRegisterClass *RC, const MachineFunction &MF, bool ReserveHighestVGPR=false) const
Returns a lowest register that is not used at any point in the function.
static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs=1)
MCPhysReg get32BitRegister(MCPhysReg Reg) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
void buildSpillLoadStore(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned LoadStoreOp, int Index, Register ValueReg, bool ValueIsKill, MCRegister ScratchOffsetReg, int64_t InstrOffset, MachineMemOperand *MMO, RegScavenger *RS, LiveRegUnits *LiveUnits=nullptr, bool NeedsCFI=false) const
bool requiresFrameIndexReplacementScavenging(const MachineFunction &MF) const override
bool shouldRealignStack(const MachineFunction &MF) const override
bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool OnlyToVGPR=false, bool SpillToPhysVGPRLane=false) const
bool isProperlyAlignedRC(const TargetRegisterClass &RC) const
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
Register getFrameRegister(const MachineFunction &MF) const override
LLVM_READONLY const TargetRegisterClass * getVectorSuperClassForBitWidth(unsigned BitWidth) const
bool spillEmergencySGPR(MachineBasicBlock::iterator MI, MachineBasicBlock &RestoreMBB, Register SGPR, RegScavenger *RS) const
SIRegisterInfo(const GCNSubtarget &ST)
const uint32_t * getAllVGPRRegMask() const
MCRegister getReturnAddressReg(const MachineFunction &MF) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
bool hasBasePointer(const MachineFunction &MF) const
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
Returns a legal register class to copy a register in the specified class to or from.
ArrayRef< int16_t > getRegSplitParts(const TargetRegisterClass *RC, unsigned EltSize) const
ArrayRef< MCPhysReg > getAllSGPR32(const MachineFunction &MF) const
Return all SGPR32 which satisfy the waves per execution unit requirement of the subtarget.
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const
Return the end register initially reserved for the scratch buffer in case spilling is needed.
bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool SpillToPhysVGPRLane=false) const
Special case of eliminateFrameIndex.
bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
LLVM_READONLY const TargetRegisterClass * getAGPRClassForBitWidth(unsigned BitWidth) const
static bool isChainScratchRegister(Register VGPR)
bool requiresRegisterScavenging(const MachineFunction &Fn) const override
bool opCanUseInlineConstant(unsigned OpType) const
const TargetRegisterClass * getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const
bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI, Register Reg) const override
const uint32_t * getNoPreservedMask() const override
StringRef getRegAsmName(MCRegister Reg) const override
const uint32_t * getAllAllocatableSRegMask() const
MCRegister getAlignedHighSGPRForRC(const MachineFunction &MF, const unsigned Align, const TargetRegisterClass *RC) const
Return the largest available SGPR aligned to Align for the register class RC.
void buildCFIForBlockCSRStore(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register BlockReg, int64_t Offset) const
const TargetRegisterClass * getRegClassForReg(const MachineRegisterInfo &MRI, Register Reg) const
unsigned getHWRegIndex(MCRegister Reg) const
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
const uint32_t * getAllVectorRegMask() const
const TargetRegisterClass * getEquivalentAGPRClass(const TargetRegisterClass *SRC) const
static LLVM_READONLY const TargetRegisterClass * getSGPRClassForBitWidth(unsigned BitWidth)
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
const TargetRegisterClass * getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const
bool opCanUseLiteralConstant(unsigned OpType) const
Register getBaseRegister() const
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
LLVM_READONLY const TargetRegisterClass * getAlignedLo256VGPRClassForBitWidth(unsigned BitWidth) const
LLVM_READONLY const TargetRegisterClass * getVGPRClassForBitWidth(unsigned BitWidth) const
const TargetRegisterClass * getEquivalentAVClass(const TargetRegisterClass *SRC) const
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
static bool isVGPRClass(const TargetRegisterClass *RC)
MachineInstr * findReachingDef(Register Reg, unsigned SubReg, MachineInstr &Use, MachineRegisterInfo &MRI, LiveIntervals *LIS) const
bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const
const TargetRegisterClass * getEquivalentSGPRClass(const TargetRegisterClass *VRC) const
SmallVector< StringLiteral > getVRegFlagsOfReg(Register Reg, const MachineFunction &MF) const override
LLVM_READONLY const TargetRegisterClass * getDefaultVectorSuperClassForBitWidth(unsigned BitWidth) const
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
ArrayRef< MCPhysReg > getAllSGPR128(const MachineFunction &MF) const
Return all SGPR128 which satisfy the waves per execution unit requirement of the subtarget.
unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
const TargetRegisterClass * getRegClassForOperandReg(const MachineRegisterInfo &MRI, const MachineOperand &MO) const
void addImplicitUsesForBlockCSRLoad(MachineInstrBuilder &MIB, Register BlockReg) const
unsigned getNumUsedPhysRegs(const MachineRegisterInfo &MRI, const TargetRegisterClass &RC, bool IncludeCalls=true) const
const uint32_t * getAllAGPRRegMask() const
const int * getRegUnitPressureSets(MCRegUnit RegUnit) const override
bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, SlotIndexes *Indexes=nullptr, LiveIntervals *LIS=nullptr, bool OnlyToVGPR=false, bool SpillToPhysVGPRLane=false, bool NeedsCFI=false) const
If OnlyToVGPR is true, this will only succeed if this manages to find a free VGPR lane to spill.
MCRegister getExec() const
MCRegister getVCC() const
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
bool isVectorSuperClass(const TargetRegisterClass *RC) const
const TargetRegisterClass * getWaveMaskRegClass() const
unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC, unsigned SubReg) const
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override
const TargetRegisterClass * getVGPR64Class() const
void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset, bool IsLoad, bool IsKill=true) const
bool isCFISavedRegsSpillEnabled() const
static bool isSGPRClass(const TargetRegisterClass *RC)
static bool isAGPRClass(const TargetRegisterClass *RC)
const TargetRegisterClass * getConstrainedRegClassForReg(Register Reg, const MachineRegisterInfo &MRI) const override
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
bool isValid() const
Returns true if this is a valid index.
SlotIndexes pass.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
SlotIndex replaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in maps used by register allocat...
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const
Returns the largest super class of RC that is legal to use in the current sub-target and has the same...
virtual bool shouldRealignStack(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
VNInfo - Value Number Information.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition VirtRegMap.h:91
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Definition VirtRegMap.h:87
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ PRIVATE_ADDRESS
Address space for private memory.
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
@ OPERAND_REG_IMM_FIRST
Definition SIDefines.h:483
@ OPERAND_REG_INLINE_AC_FIRST
Definition SIDefines.h:489
@ OPERAND_REG_INLINE_AC_LAST
Definition SIDefines.h:490
@ OPERAND_REG_IMM_LAST
Definition SIDefines.h:484
LLVM_READONLY int32_t getFlatScratchInstSVfromSVS(uint32_t Opcode)
LLVM_READONLY int32_t getFlatScratchInstSVfromSS(uint32_t Opcode)
LLVM_READONLY int32_t getFlatScratchInstSTfromSS(uint32_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition CallingConv.h:47
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
@ Renamable
Register that may be renamed.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:541
Op::Description Desc
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
@ HasSGPR
Definition SIDefines.h:29
@ HasVGPR
Definition SIDefines.h:27
@ RegKindMask
Definition SIDefines.h:32
@ HasAGPR
Definition SIDefines.h:28
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
constexpr bool hasRegState(RegState Value, RegState Test)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ Sub
Subtraction of integers.
@ Add
Sum of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
void call_once(once_flag &flag, Function &&F, Args &&... ArgList)
Execute the function specified as a parameter once.
Definition Threading.h:86
constexpr unsigned BitWidth
static const MachineMemOperand::Flags MOLastUse
Mark the MMO of a load as the last use.
Definition SIInstrInfo.h:50
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
static const MachineMemOperand::Flags MOThreadPrivate
Mark the MMO of accesses to memory locations that are never written to by other threads.
Definition SIInstrInfo.h:65
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
void setMI(MachineBasicBlock *NewMBB, MachineBasicBlock::iterator NewMI)
ArrayRef< int16_t > SplitParts
SIMachineFunctionInfo & MFI
SGPRSpillBuilder(const SIRegisterInfo &TRI, const SIInstrInfo &TII, bool IsWave32, MachineBasicBlock::iterator MI, int Index, RegScavenger *RS)
SGPRSpillBuilder(const SIRegisterInfo &TRI, const SIInstrInfo &TII, bool IsWave32, MachineBasicBlock::iterator MI, Register Reg, bool IsKill, int Index, RegScavenger *RS)
MachineBasicBlock::iterator MI
void readWriteTmpVGPR(unsigned Offset, bool IsLoad)
const SIRegisterInfo & TRI
MachineBasicBlock * MBB
const SIInstrInfo & TII
The llvm::once_flag structure.
Definition Threading.h:67