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 return RC == &AMDGPU::SCC_CLASSRegClass ? &AMDGPU::SReg_32RegClass : RC;
1146}
1147
1149 const SIInstrInfo *TII) {
1150
1151 unsigned Op = MI.getOpcode();
1152 switch (Op) {
1153 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
1154 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
1155 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE:
1156 // FIXME: This assumes the mask is statically known and not computed at
1157 // runtime. However, some ABIs may want to compute the mask dynamically and
1158 // this will need to be updated.
1159 return llvm::popcount(
1160 (uint64_t)TII->getNamedOperand(MI, AMDGPU::OpName::mask)->getImm());
1161 case AMDGPU::SI_SPILL_S1024_SAVE:
1162 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
1163 case AMDGPU::SI_SPILL_S1024_RESTORE:
1164 case AMDGPU::SI_SPILL_V1024_SAVE:
1165 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
1166 case AMDGPU::SI_SPILL_V1024_RESTORE:
1167 case AMDGPU::SI_SPILL_A1024_SAVE:
1168 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
1169 case AMDGPU::SI_SPILL_A1024_RESTORE:
1170 case AMDGPU::SI_SPILL_AV1024_SAVE:
1171 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
1172 case AMDGPU::SI_SPILL_AV1024_RESTORE:
1173 return 32;
1174 case AMDGPU::SI_SPILL_S512_SAVE:
1175 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
1176 case AMDGPU::SI_SPILL_S512_RESTORE:
1177 case AMDGPU::SI_SPILL_V512_SAVE:
1178 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
1179 case AMDGPU::SI_SPILL_V512_RESTORE:
1180 case AMDGPU::SI_SPILL_A512_SAVE:
1181 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
1182 case AMDGPU::SI_SPILL_A512_RESTORE:
1183 case AMDGPU::SI_SPILL_AV512_SAVE:
1184 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
1185 case AMDGPU::SI_SPILL_AV512_RESTORE:
1186 return 16;
1187 case AMDGPU::SI_SPILL_S384_SAVE:
1188 case AMDGPU::SI_SPILL_S384_RESTORE:
1189 case AMDGPU::SI_SPILL_V384_SAVE:
1190 case AMDGPU::SI_SPILL_V384_RESTORE:
1191 case AMDGPU::SI_SPILL_A384_SAVE:
1192 case AMDGPU::SI_SPILL_A384_RESTORE:
1193 case AMDGPU::SI_SPILL_AV384_SAVE:
1194 case AMDGPU::SI_SPILL_AV384_RESTORE:
1195 return 12;
1196 case AMDGPU::SI_SPILL_S352_SAVE:
1197 case AMDGPU::SI_SPILL_S352_RESTORE:
1198 case AMDGPU::SI_SPILL_V352_SAVE:
1199 case AMDGPU::SI_SPILL_V352_RESTORE:
1200 case AMDGPU::SI_SPILL_A352_SAVE:
1201 case AMDGPU::SI_SPILL_A352_RESTORE:
1202 case AMDGPU::SI_SPILL_AV352_SAVE:
1203 case AMDGPU::SI_SPILL_AV352_RESTORE:
1204 return 11;
1205 case AMDGPU::SI_SPILL_S320_SAVE:
1206 case AMDGPU::SI_SPILL_S320_RESTORE:
1207 case AMDGPU::SI_SPILL_V320_SAVE:
1208 case AMDGPU::SI_SPILL_V320_RESTORE:
1209 case AMDGPU::SI_SPILL_A320_SAVE:
1210 case AMDGPU::SI_SPILL_A320_RESTORE:
1211 case AMDGPU::SI_SPILL_AV320_SAVE:
1212 case AMDGPU::SI_SPILL_AV320_RESTORE:
1213 return 10;
1214 case AMDGPU::SI_SPILL_S288_SAVE:
1215 case AMDGPU::SI_SPILL_S288_RESTORE:
1216 case AMDGPU::SI_SPILL_V288_SAVE:
1217 case AMDGPU::SI_SPILL_V288_RESTORE:
1218 case AMDGPU::SI_SPILL_A288_SAVE:
1219 case AMDGPU::SI_SPILL_A288_RESTORE:
1220 case AMDGPU::SI_SPILL_AV288_SAVE:
1221 case AMDGPU::SI_SPILL_AV288_RESTORE:
1222 return 9;
1223 case AMDGPU::SI_SPILL_S256_SAVE:
1224 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
1225 case AMDGPU::SI_SPILL_S256_RESTORE:
1226 case AMDGPU::SI_SPILL_V256_SAVE:
1227 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
1228 case AMDGPU::SI_SPILL_V256_RESTORE:
1229 case AMDGPU::SI_SPILL_A256_SAVE:
1230 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
1231 case AMDGPU::SI_SPILL_A256_RESTORE:
1232 case AMDGPU::SI_SPILL_AV256_SAVE:
1233 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
1234 case AMDGPU::SI_SPILL_AV256_RESTORE:
1235 return 8;
1236 case AMDGPU::SI_SPILL_S224_SAVE:
1237 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
1238 case AMDGPU::SI_SPILL_S224_RESTORE:
1239 case AMDGPU::SI_SPILL_V224_SAVE:
1240 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
1241 case AMDGPU::SI_SPILL_V224_RESTORE:
1242 case AMDGPU::SI_SPILL_A224_SAVE:
1243 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
1244 case AMDGPU::SI_SPILL_A224_RESTORE:
1245 case AMDGPU::SI_SPILL_AV224_SAVE:
1246 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
1247 case AMDGPU::SI_SPILL_AV224_RESTORE:
1248 return 7;
1249 case AMDGPU::SI_SPILL_S192_SAVE:
1250 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
1251 case AMDGPU::SI_SPILL_S192_RESTORE:
1252 case AMDGPU::SI_SPILL_V192_SAVE:
1253 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
1254 case AMDGPU::SI_SPILL_V192_RESTORE:
1255 case AMDGPU::SI_SPILL_A192_SAVE:
1256 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
1257 case AMDGPU::SI_SPILL_A192_RESTORE:
1258 case AMDGPU::SI_SPILL_AV192_SAVE:
1259 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
1260 case AMDGPU::SI_SPILL_AV192_RESTORE:
1261 return 6;
1262 case AMDGPU::SI_SPILL_S160_SAVE:
1263 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
1264 case AMDGPU::SI_SPILL_S160_RESTORE:
1265 case AMDGPU::SI_SPILL_V160_SAVE:
1266 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
1267 case AMDGPU::SI_SPILL_V160_RESTORE:
1268 case AMDGPU::SI_SPILL_A160_SAVE:
1269 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
1270 case AMDGPU::SI_SPILL_A160_RESTORE:
1271 case AMDGPU::SI_SPILL_AV160_SAVE:
1272 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
1273 case AMDGPU::SI_SPILL_AV160_RESTORE:
1274 return 5;
1275 case AMDGPU::SI_SPILL_S128_SAVE:
1276 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
1277 case AMDGPU::SI_SPILL_S128_RESTORE:
1278 case AMDGPU::SI_SPILL_V128_SAVE:
1279 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
1280 case AMDGPU::SI_SPILL_V128_RESTORE:
1281 case AMDGPU::SI_SPILL_A128_SAVE:
1282 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
1283 case AMDGPU::SI_SPILL_A128_RESTORE:
1284 case AMDGPU::SI_SPILL_AV128_SAVE:
1285 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
1286 case AMDGPU::SI_SPILL_AV128_RESTORE:
1287 return 4;
1288 case AMDGPU::SI_SPILL_S96_SAVE:
1289 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
1290 case AMDGPU::SI_SPILL_S96_RESTORE:
1291 case AMDGPU::SI_SPILL_V96_SAVE:
1292 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
1293 case AMDGPU::SI_SPILL_V96_RESTORE:
1294 case AMDGPU::SI_SPILL_A96_SAVE:
1295 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
1296 case AMDGPU::SI_SPILL_A96_RESTORE:
1297 case AMDGPU::SI_SPILL_AV96_SAVE:
1298 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
1299 case AMDGPU::SI_SPILL_AV96_RESTORE:
1300 return 3;
1301 case AMDGPU::SI_SPILL_S64_SAVE:
1302 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
1303 case AMDGPU::SI_SPILL_S64_RESTORE:
1304 case AMDGPU::SI_SPILL_V64_SAVE:
1305 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
1306 case AMDGPU::SI_SPILL_V64_RESTORE:
1307 case AMDGPU::SI_SPILL_A64_SAVE:
1308 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
1309 case AMDGPU::SI_SPILL_A64_RESTORE:
1310 case AMDGPU::SI_SPILL_AV64_SAVE:
1311 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
1312 case AMDGPU::SI_SPILL_AV64_RESTORE:
1313 return 2;
1314 case AMDGPU::SI_SPILL_S32_SAVE:
1315 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
1316 case AMDGPU::SI_SPILL_S32_RESTORE:
1317 case AMDGPU::SI_SPILL_V32_SAVE:
1318 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
1319 case AMDGPU::SI_SPILL_V32_RESTORE:
1320 case AMDGPU::SI_SPILL_A32_SAVE:
1321 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
1322 case AMDGPU::SI_SPILL_A32_RESTORE:
1323 case AMDGPU::SI_SPILL_AV32_SAVE:
1324 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
1325 case AMDGPU::SI_SPILL_AV32_RESTORE:
1326 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
1327 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1328 case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1329 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
1330 case AMDGPU::SI_SPILL_V16_SAVE:
1331 case AMDGPU::SI_SPILL_V16_RESTORE:
1332 return 1;
1333 default: llvm_unreachable("Invalid spill opcode");
1334 }
1335}
1336
1337static int getOffsetMUBUFStore(unsigned Opc) {
1338 switch (Opc) {
1339 case AMDGPU::BUFFER_STORE_DWORD_OFFEN:
1340 return AMDGPU::BUFFER_STORE_DWORD_OFFSET;
1341 case AMDGPU::BUFFER_STORE_BYTE_OFFEN:
1342 return AMDGPU::BUFFER_STORE_BYTE_OFFSET;
1343 case AMDGPU::BUFFER_STORE_SHORT_OFFEN:
1344 return AMDGPU::BUFFER_STORE_SHORT_OFFSET;
1345 case AMDGPU::BUFFER_STORE_DWORDX2_OFFEN:
1346 return AMDGPU::BUFFER_STORE_DWORDX2_OFFSET;
1347 case AMDGPU::BUFFER_STORE_DWORDX3_OFFEN:
1348 return AMDGPU::BUFFER_STORE_DWORDX3_OFFSET;
1349 case AMDGPU::BUFFER_STORE_DWORDX4_OFFEN:
1350 return AMDGPU::BUFFER_STORE_DWORDX4_OFFSET;
1351 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN:
1352 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET;
1353 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN:
1354 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET;
1355 default:
1356 return -1;
1357 }
1358}
1359
1360static int getOffsetMUBUFLoad(unsigned Opc) {
1361 switch (Opc) {
1362 case AMDGPU::BUFFER_LOAD_DWORD_OFFEN:
1363 return AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
1364 case AMDGPU::BUFFER_LOAD_UBYTE_OFFEN:
1365 return AMDGPU::BUFFER_LOAD_UBYTE_OFFSET;
1366 case AMDGPU::BUFFER_LOAD_SBYTE_OFFEN:
1367 return AMDGPU::BUFFER_LOAD_SBYTE_OFFSET;
1368 case AMDGPU::BUFFER_LOAD_USHORT_OFFEN:
1369 return AMDGPU::BUFFER_LOAD_USHORT_OFFSET;
1370 case AMDGPU::BUFFER_LOAD_SSHORT_OFFEN:
1371 return AMDGPU::BUFFER_LOAD_SSHORT_OFFSET;
1372 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN:
1373 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET;
1374 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN:
1375 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET;
1376 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN:
1377 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET;
1378 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN:
1379 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET;
1380 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN:
1381 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET;
1382 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN:
1383 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET;
1384 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN:
1385 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET;
1386 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN:
1387 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET;
1388 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN:
1389 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET;
1390 default:
1391 return -1;
1392 }
1393}
1394
1395static int getOffenMUBUFStore(unsigned Opc) {
1396 switch (Opc) {
1397 case AMDGPU::BUFFER_STORE_DWORD_OFFSET:
1398 return AMDGPU::BUFFER_STORE_DWORD_OFFEN;
1399 case AMDGPU::BUFFER_STORE_BYTE_OFFSET:
1400 return AMDGPU::BUFFER_STORE_BYTE_OFFEN;
1401 case AMDGPU::BUFFER_STORE_SHORT_OFFSET:
1402 return AMDGPU::BUFFER_STORE_SHORT_OFFEN;
1403 case AMDGPU::BUFFER_STORE_DWORDX2_OFFSET:
1404 return AMDGPU::BUFFER_STORE_DWORDX2_OFFEN;
1405 case AMDGPU::BUFFER_STORE_DWORDX3_OFFSET:
1406 return AMDGPU::BUFFER_STORE_DWORDX3_OFFEN;
1407 case AMDGPU::BUFFER_STORE_DWORDX4_OFFSET:
1408 return AMDGPU::BUFFER_STORE_DWORDX4_OFFEN;
1409 case AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFSET:
1410 return AMDGPU::BUFFER_STORE_SHORT_D16_HI_OFFEN;
1411 case AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFSET:
1412 return AMDGPU::BUFFER_STORE_BYTE_D16_HI_OFFEN;
1413 default:
1414 return -1;
1415 }
1416}
1417
1418static int getOffenMUBUFLoad(unsigned Opc) {
1419 switch (Opc) {
1420 case AMDGPU::BUFFER_LOAD_DWORD_OFFSET:
1421 return AMDGPU::BUFFER_LOAD_DWORD_OFFEN;
1422 case AMDGPU::BUFFER_LOAD_UBYTE_OFFSET:
1423 return AMDGPU::BUFFER_LOAD_UBYTE_OFFEN;
1424 case AMDGPU::BUFFER_LOAD_SBYTE_OFFSET:
1425 return AMDGPU::BUFFER_LOAD_SBYTE_OFFEN;
1426 case AMDGPU::BUFFER_LOAD_USHORT_OFFSET:
1427 return AMDGPU::BUFFER_LOAD_USHORT_OFFEN;
1428 case AMDGPU::BUFFER_LOAD_SSHORT_OFFSET:
1429 return AMDGPU::BUFFER_LOAD_SSHORT_OFFEN;
1430 case AMDGPU::BUFFER_LOAD_DWORDX2_OFFSET:
1431 return AMDGPU::BUFFER_LOAD_DWORDX2_OFFEN;
1432 case AMDGPU::BUFFER_LOAD_DWORDX3_OFFSET:
1433 return AMDGPU::BUFFER_LOAD_DWORDX3_OFFEN;
1434 case AMDGPU::BUFFER_LOAD_DWORDX4_OFFSET:
1435 return AMDGPU::BUFFER_LOAD_DWORDX4_OFFEN;
1436 case AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFSET:
1437 return AMDGPU::BUFFER_LOAD_UBYTE_D16_OFFEN;
1438 case AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFSET:
1439 return AMDGPU::BUFFER_LOAD_UBYTE_D16_HI_OFFEN;
1440 case AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFSET:
1441 return AMDGPU::BUFFER_LOAD_SBYTE_D16_OFFEN;
1442 case AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFSET:
1443 return AMDGPU::BUFFER_LOAD_SBYTE_D16_HI_OFFEN;
1444 case AMDGPU::BUFFER_LOAD_SHORT_D16_OFFSET:
1445 return AMDGPU::BUFFER_LOAD_SHORT_D16_OFFEN;
1446 case AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFSET:
1447 return AMDGPU::BUFFER_LOAD_SHORT_D16_HI_OFFEN;
1448 default:
1449 return -1;
1450 }
1451}
1452
1455 MachineBasicBlock::iterator MI, int Index, unsigned Lane,
1456 unsigned ValueReg, bool IsKill, bool NeedsCFI) {
1457 MachineFunction *MF = MBB.getParent();
1459 const SIInstrInfo *TII = ST.getInstrInfo();
1460 const SIFrameLowering *TFL = ST.getFrameLowering();
1461
1462 MCPhysReg Reg = MFI->getVGPRToAGPRSpill(Index, Lane);
1463
1464 if (Reg == AMDGPU::NoRegister)
1465 return MachineInstrBuilder();
1466
1467 bool IsStore = MI->mayStore();
1468 MachineRegisterInfo &MRI = MF->getRegInfo();
1469 auto *TRI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
1470
1471 unsigned Dst = IsStore ? Reg : ValueReg;
1472 unsigned Src = IsStore ? ValueReg : Reg;
1473 bool IsVGPR = TRI->isVGPR(MRI, Reg);
1474 const DebugLoc &DL = MI->getDebugLoc();
1475 if (IsVGPR == TRI->isVGPR(MRI, ValueReg)) {
1476 // Spiller during regalloc may restore a spilled register to its superclass.
1477 // It could result in AGPR spills restored to VGPRs or the other way around,
1478 // making the src and dst with identical regclasses at this point. It just
1479 // needs a copy in such cases.
1480 auto CopyMIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::COPY), Dst)
1481 .addReg(Src, getKillRegState(IsKill));
1483 if (NeedsCFI)
1484 TFL->buildCFIForVRegToVRegSpill(MBB, MI, DL, Src, Dst);
1485 return CopyMIB;
1486 }
1487 unsigned Opc = (IsStore ^ IsVGPR) ? AMDGPU::V_ACCVGPR_WRITE_B32_e64
1488 : AMDGPU::V_ACCVGPR_READ_B32_e64;
1489
1490 auto MIB = BuildMI(MBB, MI, DL, TII->get(Opc), Dst)
1491 .addReg(Src, getKillRegState(IsKill));
1493 if (NeedsCFI)
1494 TFL->buildCFIForVRegToVRegSpill(MBB, MI, DL, Src, Dst);
1495 return MIB;
1496}
1497
1498// This differs from buildSpillLoadStore by only scavenging a VGPR. It does not
1499// need to handle the case where an SGPR may need to be spilled while spilling.
1501 MachineFrameInfo &MFI,
1503 int Index,
1504 int64_t Offset) {
1505 const SIInstrInfo *TII = ST.getInstrInfo();
1506 MachineBasicBlock *MBB = MI->getParent();
1507 const DebugLoc &DL = MI->getDebugLoc();
1508 bool IsStore = MI->mayStore();
1509
1510 unsigned Opc = MI->getOpcode();
1511 int LoadStoreOp = IsStore ?
1513 if (LoadStoreOp == -1)
1514 return false;
1515
1516 const MachineOperand *Reg = TII->getNamedOperand(*MI, AMDGPU::OpName::vdata);
1517 if (spillVGPRtoAGPR(ST, *MBB, MI, Index, 0, Reg->getReg(), false, false)
1518 .getInstr())
1519 return true;
1520
1521 MachineInstrBuilder NewMI =
1522 BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp))
1523 .add(*Reg)
1524 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::srsrc))
1525 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::soffset))
1526 .addImm(Offset)
1527 .addImm(0) // cpol
1528 .addImm(0) // swz
1529 .cloneMemRefs(*MI);
1530
1531 const MachineOperand *VDataIn = TII->getNamedOperand(*MI,
1532 AMDGPU::OpName::vdata_in);
1533 if (VDataIn)
1534 NewMI.add(*VDataIn);
1535 return true;
1536}
1537
1539 unsigned LoadStoreOp,
1540 unsigned EltSize) {
1541 bool IsStore = TII->get(LoadStoreOp).mayStore();
1542 bool HasVAddr = AMDGPU::hasNamedOperand(LoadStoreOp, AMDGPU::OpName::vaddr);
1543 bool UseST =
1544 !HasVAddr && !AMDGPU::hasNamedOperand(LoadStoreOp, AMDGPU::OpName::saddr);
1545
1546 // Handle block load/store first.
1547 if (TII->isBlockLoadStore(LoadStoreOp))
1548 return LoadStoreOp;
1549
1550 switch (EltSize) {
1551 case 4:
1552 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
1553 : AMDGPU::SCRATCH_LOAD_DWORD_SADDR;
1554 break;
1555 case 8:
1556 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX2_SADDR
1557 : AMDGPU::SCRATCH_LOAD_DWORDX2_SADDR;
1558 break;
1559 case 12:
1560 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX3_SADDR
1561 : AMDGPU::SCRATCH_LOAD_DWORDX3_SADDR;
1562 break;
1563 case 16:
1564 LoadStoreOp = IsStore ? AMDGPU::SCRATCH_STORE_DWORDX4_SADDR
1565 : AMDGPU::SCRATCH_LOAD_DWORDX4_SADDR;
1566 break;
1567 default:
1568 llvm_unreachable("Unexpected spill load/store size!");
1569 }
1570
1571 if (HasVAddr)
1572 LoadStoreOp = AMDGPU::getFlatScratchInstSVfromSS(LoadStoreOp);
1573 else if (UseST)
1574 LoadStoreOp = AMDGPU::getFlatScratchInstSTfromSS(LoadStoreOp);
1575
1576 return LoadStoreOp;
1577}
1578
1581 unsigned LoadStoreOp, int Index, Register ValueReg, bool IsKill,
1582 MCRegister ScratchOffsetReg, int64_t InstOffset, MachineMemOperand *MMO,
1583 RegScavenger *RS, LiveRegUnits *LiveUnits, bool NeedsCFI) const {
1584 assert((!RS || !LiveUnits) && "Only RS or LiveUnits can be set but not both");
1585
1586 MachineFunction *MF = MBB.getParent();
1587 const SIInstrInfo *TII = ST.getInstrInfo();
1588 const MachineFrameInfo &MFI = MF->getFrameInfo();
1589 const SIFrameLowering *TFL = ST.getFrameLowering();
1590 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
1591
1592 const MCInstrDesc *Desc = &TII->get(LoadStoreOp);
1593 bool IsStore = Desc->mayStore();
1594 bool IsFlat = TII->isFLATScratch(LoadStoreOp);
1595 bool IsBlock = TII->isBlockLoadStore(LoadStoreOp);
1596
1597 bool CanClobberSCC = false;
1598 bool Scavenged = false;
1599 MCRegister SOffset = ScratchOffsetReg;
1600
1601 const TargetRegisterClass *RC = getRegClassForReg(MF->getRegInfo(), ValueReg);
1602 // On gfx90a+ AGPR is a regular VGPR acceptable for loads and stores.
1603 const bool IsAGPR = !ST.hasGFX90AInsts() && isAGPRClass(RC);
1604 unsigned RegWidth = AMDGPU::getRegBitWidth(*RC) / 8;
1605
1606 // On targets with register tuple alignment requirements,
1607 // for unaligned tuples, spill the first sub-reg as a 32-bit spill,
1608 // and spill the rest as a regular aligned tuple.
1609 // eg: SPILL_V224 $vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7
1610 // will be spilt as:
1611 // SPILL_SCRATCH_DWORD $vgpr1
1612 // SPILL_SCRATCH_DWORDx4 $vgpr2_vgpr3_vgpr4_vgpr5
1613 // SPILL_SCRATCH_DWORDx2 $vgpr6_vgpr7
1614 bool IsRegMisaligned = false;
1615 if (!IsBlock && !IsAGPR && RegWidth > 4 && IsFlat) {
1616 unsigned SpillOpcode =
1617 getFlatScratchSpillOpcode(TII, LoadStoreOp, std::min(RegWidth, 16u));
1618 int VDataIdx =
1619 IsStore ? AMDGPU::getNamedOperandIdx(SpillOpcode, AMDGPU::OpName::vdata)
1620 : 0; // Restore Ops have data reg as the first (output) operand.
1621 const TargetRegisterClass *ExpectedRC =
1622 TII->getRegClass(TII->get(SpillOpcode), VDataIdx);
1623 if (!ExpectedRC->contains(ValueReg)) {
1624 unsigned NumRegs = std::min(AMDGPU::getRegBitWidth(*ExpectedRC) / 4, 4u);
1625 unsigned SubIdx = getSubRegFromChannel(0, NumRegs);
1626 const TargetRegisterClass *MatchRC =
1627 getMatchingSuperRegClass(RC, ExpectedRC, SubIdx);
1628 if (!MatchRC || !MatchRC->contains(ValueReg))
1629 IsRegMisaligned = true;
1630 }
1631 }
1632 // The first sub-register will be spilled as a 32-bit value
1633 if (IsRegMisaligned)
1634 RegWidth -= 4u;
1635 // Always use 4 byte operations for AGPRs because we need to scavenge
1636 // a temporary VGPR.
1637 // If we're using a block operation, the element should be the whole block.
1638 unsigned EltSize = IsBlock ? RegWidth
1639 : (IsFlat && !IsAGPR) ? std::min(RegWidth, 16u)
1640 : 4u;
1641 unsigned NumSubRegs = RegWidth / EltSize;
1642 unsigned Size = NumSubRegs * EltSize;
1643 unsigned RemSize = RegWidth - Size;
1644 unsigned NumRemSubRegs = RemSize ? 1 : 0;
1645 // An additional sub-register is needed to spill the misaligned component.
1646 if (IsRegMisaligned)
1647 NumSubRegs += 1;
1648 int64_t Offset = InstOffset + MFI.getObjectOffset(Index);
1649 int64_t MaterializedOffset = Offset;
1650
1651 // Maxoffset is the starting offset for the last chunk to be spilled.
1652 // In case of non-zero remainder element, max offset will be the
1653 // last address(offset + Size) after spilling all the EltSize chunks.
1654 int64_t MaxOffset = Offset + Size - (RemSize ? 0 : EltSize);
1655 int64_t ScratchOffsetRegDelta = 0;
1656 int64_t AdditionalCFIOffset = 0;
1657
1658 if (IsFlat && EltSize > 4) {
1659 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1660 Desc = &TII->get(LoadStoreOp);
1661 }
1662
1663 Align Alignment = MFI.getObjectAlign(Index);
1664 const MachinePointerInfo &BasePtrInfo = MMO->getPointerInfo();
1665
1666 assert((IsFlat || ((Offset % EltSize) == 0)) &&
1667 "unexpected VGPR spill offset");
1668
1669 // Track a VGPR to use for a constant offset we need to materialize.
1670 Register TmpOffsetVGPR;
1671
1672 // Track a VGPR to use as an intermediate value.
1673 Register TmpIntermediateVGPR;
1674 bool UseVGPROffset = false;
1675
1676 // Materialize a VGPR offset required for the given SGPR/VGPR/Immediate
1677 // combination.
1678 auto MaterializeVOffset = [&](Register SGPRBase, Register TmpVGPR,
1679 int64_t VOffset) {
1680 // We are using a VGPR offset
1681 if (IsFlat && SGPRBase) {
1682 // We only have 1 VGPR offset, or 1 SGPR offset. We don't have a free
1683 // SGPR, so perform the add as vector.
1684 // We don't need a base SGPR in the kernel.
1685
1686 if (ST.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) >= 2) {
1687 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e64), TmpVGPR)
1688 .addReg(SGPRBase)
1689 .addImm(VOffset)
1690 .addImm(0); // clamp
1691 } else {
1692 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
1693 .addReg(SGPRBase);
1694 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e32), TmpVGPR)
1695 .addImm(VOffset)
1696 .addReg(TmpOffsetVGPR);
1697 }
1698 } else {
1699 assert(TmpOffsetVGPR);
1700 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpVGPR)
1701 .addImm(VOffset);
1702 }
1703 };
1704
1705 bool IsOffsetLegal =
1706 IsFlat ? TII->isLegalFLATOffset(MaxOffset, AMDGPUAS::PRIVATE_ADDRESS,
1708 : TII->isLegalMUBUFImmOffset(MaxOffset);
1709 if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
1710 SOffset = MCRegister();
1711
1712 // We don't have access to the register scavenger if this function is called
1713 // during PEI::scavengeFrameVirtualRegs() so use LiveUnits in this case.
1714 // TODO: Clobbering SCC is not necessary for scratch instructions in the
1715 // entry.
1716 if (RS) {
1717 SOffset = RS->scavengeRegisterBackwards(AMDGPU::SGPR_32RegClass, MI, false, 0, false);
1718
1719 // Piggy back on the liveness scan we just did see if SCC is dead.
1720 CanClobberSCC = !RS->isRegUsed(AMDGPU::SCC);
1721 } else if (LiveUnits) {
1722 CanClobberSCC = LiveUnits->available(AMDGPU::SCC);
1723 for (MCRegister Reg : AMDGPU::SGPR_32RegClass) {
1724 if (LiveUnits->available(Reg) && !MF->getRegInfo().isReserved(Reg)) {
1725 SOffset = Reg;
1726 break;
1727 }
1728 }
1729 }
1730
1731 if (ScratchOffsetReg != AMDGPU::NoRegister && !CanClobberSCC)
1732 SOffset = Register();
1733
1734 if (!SOffset) {
1735 UseVGPROffset = true;
1736
1737 if (RS) {
1738 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false, 0);
1739 } else {
1740 assert(LiveUnits);
1741 for (MCRegister Reg : AMDGPU::VGPR_32RegClass) {
1742 if (LiveUnits->available(Reg) && !MF->getRegInfo().isReserved(Reg)) {
1743 TmpOffsetVGPR = Reg;
1744 break;
1745 }
1746 }
1747 }
1748
1749 assert(TmpOffsetVGPR);
1750 } else if (!SOffset && CanClobberSCC) {
1751 // There are no free SGPRs, and since we are in the process of spilling
1752 // VGPRs too. Since we need a VGPR in order to spill SGPRs (this is true
1753 // on SI/CI and on VI it is true until we implement spilling using scalar
1754 // stores), we have no way to free up an SGPR. Our solution here is to
1755 // add the offset directly to the ScratchOffset or StackPtrOffset
1756 // register, and then subtract the offset after the spill to return the
1757 // register to it's original value.
1758
1759 // TODO: If we don't have to do an emergency stack slot spill, converting
1760 // to use the VGPR offset is fewer instructions.
1761 if (!ScratchOffsetReg)
1762 ScratchOffsetReg = FuncInfo->getStackPtrOffsetReg();
1763 SOffset = ScratchOffsetReg;
1764 ScratchOffsetRegDelta = Offset;
1765 } else {
1766 Scavenged = true;
1767 }
1768
1769 AdditionalCFIOffset = Offset;
1770 // We currently only support spilling VGPRs to EltSize boundaries, meaning
1771 // we can simplify the adjustment of Offset here to just scale with
1772 // WavefrontSize.
1773 if (!IsFlat && !UseVGPROffset)
1774 Offset *= ST.getWavefrontSize();
1775
1776 if (!UseVGPROffset && !SOffset)
1777 report_fatal_error("could not scavenge SGPR to spill in entry function");
1778
1779 if (UseVGPROffset) {
1780 // We are using a VGPR offset
1781 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, Offset);
1782 } else if (ScratchOffsetReg == AMDGPU::NoRegister) {
1783 BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_MOV_B32), SOffset).addImm(Offset);
1784 } else {
1785 assert(Offset != 0);
1786 auto Add = BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), SOffset)
1787 .addReg(ScratchOffsetReg)
1788 .addImm(Offset);
1789 Add->getOperand(3).setIsDead(); // Mark SCC as dead.
1790 }
1791
1792 Offset = 0;
1793 }
1794
1795 if (IsFlat && SOffset == AMDGPU::NoRegister) {
1796 assert(AMDGPU::getNamedOperandIdx(LoadStoreOp, AMDGPU::OpName::vaddr) < 0
1797 && "Unexpected vaddr for flat scratch with a FI operand");
1798
1799 if (UseVGPROffset) {
1800 LoadStoreOp = AMDGPU::getFlatScratchInstSVfromSS(LoadStoreOp);
1801 } else {
1802 assert(ST.hasFlatScratchSTMode());
1803 assert(!TII->isBlockLoadStore(LoadStoreOp) && "Block ops don't have ST");
1804 LoadStoreOp = AMDGPU::getFlatScratchInstSTfromSS(LoadStoreOp);
1805 }
1806
1807 Desc = &TII->get(LoadStoreOp);
1808 }
1809
1810 // Save a copy of the original element size before its potentially changed for
1811 // misaligned tuples.
1812 unsigned OrigEltSize = EltSize;
1813 for (unsigned i = 0, e = NumSubRegs + NumRemSubRegs, RegOffset = 0; i != e;
1814 ++i, RegOffset += EltSize) {
1815 if (IsRegMisaligned) {
1816 if (i == 0) {
1817 // For misaligned register tuples, spill only the first sub-reg in the
1818 // first iteration.
1819 EltSize = 4u;
1820 } else {
1821 // The misaligned register was spilt. Now the rest of the tuple is
1822 // properly aligned.
1823 IsRegMisaligned = false;
1824 EltSize = OrigEltSize;
1825 }
1826 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1827 }
1828 if (i == NumSubRegs) {
1829 EltSize = RemSize;
1830 LoadStoreOp = getFlatScratchSpillOpcode(TII, LoadStoreOp, EltSize);
1831 }
1832 Desc = &TII->get(LoadStoreOp);
1833
1834 if (!IsFlat && UseVGPROffset) {
1835 int NewLoadStoreOp = IsStore ? getOffenMUBUFStore(LoadStoreOp)
1836 : getOffenMUBUFLoad(LoadStoreOp);
1837 Desc = &TII->get(NewLoadStoreOp);
1838 }
1839
1840 if (UseVGPROffset && TmpOffsetVGPR == TmpIntermediateVGPR) {
1841 // If we are spilling an AGPR beyond the range of the memory instruction
1842 // offset and need to use a VGPR offset, we ideally have at least 2
1843 // scratch VGPRs. If we don't have a second free VGPR without spilling,
1844 // recycle the VGPR used for the offset which requires resetting after
1845 // each subregister.
1846
1847 MaterializeVOffset(ScratchOffsetReg, TmpOffsetVGPR, MaterializedOffset);
1848 }
1849
1850 unsigned NumRegs = EltSize / 4;
1851 Register SubReg = e == 1
1852 ? ValueReg
1853 : Register(getSubReg(ValueReg,
1854 getSubRegFromChannel(RegOffset / 4, NumRegs)));
1855
1856 RegState SOffsetRegState = {};
1857 RegState SrcDstRegState = getDefRegState(!IsStore);
1858 const bool IsLastSubReg = i + 1 == e;
1859 const bool IsFirstSubReg = i == 0;
1860 if (IsLastSubReg) {
1861 SOffsetRegState |= getKillRegState(Scavenged);
1862 // The last implicit use carries the "Kill" flag.
1863 SrcDstRegState |= getKillRegState(IsKill);
1864 }
1865
1866 // Make sure the whole register is defined if there are undef components by
1867 // adding an implicit def of the super-reg on the first instruction.
1868 bool NeedSuperRegDef = e > 1 && IsStore && IsFirstSubReg;
1869 bool NeedSuperRegImpOperand = e > 1;
1870
1871 // Remaining element size to spill into memory after some parts of it
1872 // spilled into either AGPRs or VGPRs.
1873 unsigned RemEltSize = EltSize;
1874
1875 // AGPRs to spill VGPRs and vice versa are allocated in a reverse order,
1876 // starting from the last lane. In case if a register cannot be completely
1877 // spilled into another register that will ensure its alignment does not
1878 // change. For targets with VGPR alignment requirement this is important
1879 // in case of flat scratch usage as we might get a scratch_load or
1880 // scratch_store of an unaligned register otherwise.
1881 for (int LaneS = (RegOffset + EltSize) / 4 - 1, Lane = LaneS,
1882 LaneE = RegOffset / 4;
1883 Lane >= LaneE; --Lane) {
1884 bool IsSubReg = e > 1 || EltSize > 4;
1885 Register Sub = IsSubReg
1886 ? Register(getSubReg(ValueReg, getSubRegFromChannel(Lane)))
1887 : ValueReg;
1888 auto MIB =
1889 spillVGPRtoAGPR(ST, MBB, MI, Index, Lane, Sub, IsKill, NeedsCFI);
1890 if (!MIB.getInstr())
1891 break;
1892 if (NeedSuperRegDef || (IsSubReg && IsStore && Lane == LaneS && IsFirstSubReg)) {
1893 MIB.addReg(ValueReg, RegState::ImplicitDefine);
1894 NeedSuperRegDef = false;
1895 }
1896 if ((IsSubReg || NeedSuperRegImpOperand) && (IsFirstSubReg || IsLastSubReg)) {
1897 NeedSuperRegImpOperand = true;
1898 RegState State = SrcDstRegState;
1899 if (!IsLastSubReg || (Lane != LaneE))
1900 State &= ~RegState::Kill;
1901 if (!IsFirstSubReg || (Lane != LaneS))
1902 State &= ~RegState::Define;
1903 MIB.addReg(ValueReg, RegState::Implicit | State);
1904 }
1905 RemEltSize -= 4;
1906 }
1907
1908 if (!RemEltSize) // Fully spilled into AGPRs.
1909 continue;
1910
1911 if (RemEltSize != EltSize) { // Partially spilled to AGPRs
1912 assert(IsFlat && EltSize > 4);
1913
1914 unsigned NumRegs = RemEltSize / 4;
1915 SubReg = Register(getSubReg(ValueReg,
1916 getSubRegFromChannel(RegOffset / 4, NumRegs)));
1917 unsigned Opc = getFlatScratchSpillOpcode(TII, LoadStoreOp, RemEltSize);
1918 Desc = &TII->get(Opc);
1919 }
1920
1921 unsigned FinalReg = SubReg;
1922
1923 if (IsAGPR) {
1924 assert(EltSize == 4);
1925
1926 if (!TmpIntermediateVGPR) {
1927 TmpIntermediateVGPR = FuncInfo->getVGPRForAGPRCopy();
1928 assert(MF->getRegInfo().isReserved(TmpIntermediateVGPR));
1929 }
1930 if (IsStore) {
1931 auto AccRead = BuildMI(MBB, MI, DL,
1932 TII->get(AMDGPU::V_ACCVGPR_READ_B32_e64),
1933 TmpIntermediateVGPR)
1934 .addReg(SubReg, getKillRegState(IsKill));
1935 if (NeedSuperRegDef)
1936 AccRead.addReg(ValueReg, RegState::ImplicitDefine);
1937 if (NeedSuperRegImpOperand && (IsFirstSubReg || IsLastSubReg))
1938 AccRead.addReg(ValueReg, RegState::Implicit);
1940 }
1941 SubReg = TmpIntermediateVGPR;
1942 } else if (UseVGPROffset) {
1943 if (!TmpOffsetVGPR) {
1944 TmpOffsetVGPR = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
1945 MI, false, 0);
1946 RS->setRegUsed(TmpOffsetVGPR);
1947 }
1948 }
1949
1950 Register FinalValueReg = ValueReg;
1951 if (LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_SADDR ||
1952 LoadStoreOp == AMDGPU::SCRATCH_LOAD_USHORT_ST) {
1953 // If we are loading 16-bit value with SRAMECC endabled we need a temp
1954 // 32-bit VGPR to load and extract 16-bits into the final register.
1955 ValueReg =
1956 RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI, false, 0);
1957 SubReg = ValueReg;
1958 IsKill = false;
1959 }
1960
1961 // Create the MMO, additional set the NonVolatile flag as scratch memory
1962 // used for spills will not be used outside the thread.
1963 MachinePointerInfo PInfo = BasePtrInfo.getWithOffset(RegOffset);
1965 PInfo, MMO->getFlags() | MOThreadPrivate, RemEltSize,
1966 commonAlignment(Alignment, RegOffset));
1967
1968 auto MIB =
1969 BuildMI(MBB, MI, DL, *Desc)
1970 .addReg(SubReg, getDefRegState(!IsStore) | getKillRegState(IsKill));
1971
1972 if (UseVGPROffset) {
1973 // For an AGPR spill, we reuse the same temp VGPR for the offset and the
1974 // intermediate accvgpr_write.
1975 MIB.addReg(TmpOffsetVGPR, getKillRegState(IsLastSubReg && !IsAGPR));
1976 }
1977
1978 if (!IsFlat)
1979 MIB.addReg(FuncInfo->getScratchRSrcReg());
1980
1981 if (SOffset == AMDGPU::NoRegister) {
1982 if (!IsFlat) {
1983 if (UseVGPROffset && ScratchOffsetReg) {
1984 MIB.addReg(ScratchOffsetReg);
1985 } else {
1986 assert(FuncInfo->isBottomOfStack());
1987 MIB.addImm(0);
1988 }
1989 }
1990 } else {
1991 MIB.addReg(SOffset, SOffsetRegState);
1992 }
1993
1994 MIB.addImm(Offset + RegOffset);
1995
1996 bool LastUse = MMO->getFlags() & MOLastUse;
1997 MIB.addImm(LastUse ? AMDGPU::CPol::TH_LU : 0); // cpol
1998
1999 if (!IsFlat)
2000 MIB.addImm(0); // swz
2001 MIB.addMemOperand(NewMMO);
2002
2003 if (FinalValueReg != ValueReg) {
2004 // Extract 16-bit from the loaded 32-bit value.
2005 ValueReg = getSubReg(ValueReg, AMDGPU::lo16);
2006 MIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_MOV_B16_t16_e64))
2007 .addReg(FinalValueReg, getDefRegState(true))
2008 .addImm(0)
2009 .addReg(ValueReg, getKillRegState(true))
2010 .addImm(0);
2011 ValueReg = FinalValueReg;
2012 }
2013
2014 if (IsStore && NeedsCFI) {
2015 if (TII->isBlockLoadStore(LoadStoreOp)) {
2016 assert(RegOffset == 0 &&
2017 "expected whole register block to be treated as single element");
2019 } else {
2021 MBB, MI, DebugLoc(), SubReg,
2022 (Offset + RegOffset) * ST.getWavefrontSize() + AdditionalCFIOffset);
2023 }
2024 }
2025
2026 if (!IsAGPR && NeedSuperRegDef)
2027 MIB.addReg(ValueReg, RegState::ImplicitDefine);
2028
2029 if (!IsStore && IsAGPR && TmpIntermediateVGPR != AMDGPU::NoRegister) {
2030 MIB = BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_ACCVGPR_WRITE_B32_e64),
2031 FinalReg)
2032 .addReg(TmpIntermediateVGPR, RegState::Kill);
2034 }
2035
2036 bool IsSrcDstDef = hasRegState(SrcDstRegState, RegState::Define);
2037 bool PartialReloadCopy = (RemEltSize != EltSize) && !IsStore;
2038 if (NeedSuperRegImpOperand &&
2039 (IsFirstSubReg || (IsLastSubReg && !IsSrcDstDef))) {
2040 MIB.addReg(ValueReg, RegState::Implicit | SrcDstRegState);
2041 if (PartialReloadCopy)
2042 MIB.addReg(ValueReg, RegState::Implicit);
2043 }
2044
2045 // The epilog restore of a wwm-scratch register can cause undesired
2046 // optimization during machine-cp post PrologEpilogInserter if the same
2047 // register was assigned for return value ABI lowering with a COPY
2048 // instruction. As given below, with the epilog reload, the earlier COPY
2049 // appeared to be dead during machine-cp.
2050 // ...
2051 // v0 in WWM operation, needs the WWM spill at prolog/epilog.
2052 // $vgpr0 = V_WRITELANE_B32 $sgpr20, 0, $vgpr0
2053 // ...
2054 // Epilog block:
2055 // $vgpr0 = COPY $vgpr1 // outgoing value moved to v0
2056 // ...
2057 // WWM spill restore to preserve the inactive lanes of v0.
2058 // $sgpr4_sgpr5 = S_XOR_SAVEEXEC_B64 -1
2059 // $vgpr0 = BUFFER_LOAD $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr32, 0, 0, 0
2060 // $exec = S_MOV_B64 killed $sgpr4_sgpr5
2061 // ...
2062 // SI_RETURN implicit $vgpr0
2063 // ...
2064 // To fix it, mark the same reg as a tied op for such restore instructions
2065 // so that it marks a usage for the preceding COPY.
2066 if (!IsStore && MI != MBB.end() && MI->isReturn() &&
2067 MI->readsRegister(SubReg, this)) {
2068 MIB.addReg(SubReg, RegState::Implicit);
2069 MIB->tieOperands(0, MIB->getNumOperands() - 1);
2070 }
2071
2072 // If we're building a block load, we should add artificial uses for the
2073 // CSR VGPRs that are *not* being transferred. This is because liveness
2074 // analysis is not aware of the mask, so we need to somehow inform it that
2075 // those registers are not available before the load and they should not be
2076 // scavenged.
2077 if (!IsStore && TII->isBlockLoadStore(LoadStoreOp))
2078 addImplicitUsesForBlockCSRLoad(MIB, ValueReg);
2079 }
2080
2081 if (ScratchOffsetRegDelta != 0) {
2082 // Subtract the offset we added to the ScratchOffset register.
2083 BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), SOffset)
2084 .addReg(SOffset)
2085 .addImm(-ScratchOffsetRegDelta);
2086 }
2087}
2088
2090 Register BlockReg) const {
2091 const MachineFunction *MF = MIB->getMF();
2092 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
2093 uint32_t Mask = FuncInfo->getMaskForVGPRBlockOps(BlockReg);
2094 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2095 for (unsigned RegOffset = 1; RegOffset < 32; ++RegOffset)
2096 if (!(Mask & (1 << RegOffset)) &&
2097 isCalleeSavedPhysReg(BaseVGPR + RegOffset, *MF))
2098 MIB.addUse(BaseVGPR + RegOffset, RegState::Implicit);
2099}
2100
2103 Register BlockReg,
2104 int64_t Offset) const {
2105 const MachineFunction *MF = MBB.getParent();
2106 const SIMachineFunctionInfo *FuncInfo = MF->getInfo<SIMachineFunctionInfo>();
2107 uint32_t Mask = FuncInfo->getMaskForVGPRBlockOps(BlockReg);
2108 Register BaseVGPR = getSubReg(BlockReg, AMDGPU::sub0);
2109 for (unsigned RegOffset = 0; RegOffset < 32; ++RegOffset) {
2110 Register VGPR = BaseVGPR + RegOffset;
2111 if (Mask & (1 << RegOffset)) {
2112 assert(isCalleeSavedPhysReg(VGPR, *MF));
2113 ST.getFrameLowering()->buildCFIForVGPRToVMEMSpill(
2114 MBB, MBBI, DebugLoc(), VGPR,
2115 (Offset + RegOffset) * ST.getWavefrontSize());
2116 } else if (isCalleeSavedPhysReg(VGPR, *MF)) {
2117 // FIXME: This is a workaround for the fact that FrameLowering's
2118 // emitPrologueEntryCFI considers the block load to clobber all registers
2119 // in the block.
2120 ST.getFrameLowering()->buildCFIForSameValue(MBB, MBBI, DebugLoc(),
2121 BaseVGPR + RegOffset);
2122 }
2123 }
2124}
2125
2127 int Offset, bool IsLoad,
2128 bool IsKill) const {
2129 // Load/store VGPR
2130 MachineFrameInfo &FrameInfo = SB.MF.getFrameInfo();
2131 assert(FrameInfo.getStackID(Index) != TargetStackID::SGPRSpill);
2132
2133 Register FrameReg =
2134 FrameInfo.isFixedObjectIndex(Index) && hasBasePointer(SB.MF)
2135 ? getBaseRegister()
2136 : getFrameRegister(SB.MF);
2137
2138 Align Alignment = FrameInfo.getObjectAlign(Index);
2142 SB.EltSize, Alignment);
2143
2144 if (IsLoad) {
2145 unsigned Opc = ST.hasFlatScratchEnabled()
2146 ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2147 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2148 buildSpillLoadStore(*SB.MBB, SB.MI, SB.DL, Opc, Index, SB.TmpVGPR, false,
2149 FrameReg, (int64_t)Offset * SB.EltSize, MMO, SB.RS);
2150 } else {
2151 unsigned Opc = ST.hasFlatScratchEnabled()
2152 ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2153 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2154 buildSpillLoadStore(*SB.MBB, SB.MI, SB.DL, Opc, Index, SB.TmpVGPR, IsKill,
2155 FrameReg, (int64_t)Offset * SB.EltSize, MMO, SB.RS);
2156 // This only ever adds one VGPR spill
2157 SB.MFI.addToSpilledVGPRs(1);
2158 }
2159}
2160
2162 RegScavenger *RS, SlotIndexes *Indexes,
2163 LiveIntervals *LIS, bool OnlyToVGPR,
2164 bool SpillToPhysVGPRLane, bool NeedsCFI) const {
2165 assert(!MI->getOperand(0).isUndef() &&
2166 "undef spill should have been deleted earlier");
2167
2168 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, Index, RS);
2169
2170 ArrayRef<SpilledReg> VGPRSpills =
2171 SpillToPhysVGPRLane ? SB.MFI.getSGPRSpillToPhysicalVGPRLanes(Index)
2173 bool SpillToVGPR = !VGPRSpills.empty();
2174 if (OnlyToVGPR && !SpillToVGPR)
2175 return false;
2176
2177 const SIFrameLowering *TFL = ST.getFrameLowering();
2178
2179 assert(SpillToVGPR || (SB.SuperReg != SB.MFI.getStackPtrOffsetReg() &&
2180 SB.SuperReg != SB.MFI.getFrameOffsetReg()));
2181
2182 if (SpillToVGPR) {
2183
2184 // Since stack slot coloring pass is trying to optimize SGPR spills,
2185 // VGPR lanes (mapped from spill stack slot) may be shared for SGPR
2186 // spills of different sizes. This accounts for number of VGPR lanes alloted
2187 // equal to the largest SGPR being spilled in them.
2188 assert(SB.NumSubRegs <= VGPRSpills.size() &&
2189 "Num of SGPRs spilled should be less than or equal to num of "
2190 "the VGPR lanes.");
2191
2192 for (unsigned i = 0, e = SB.NumSubRegs; i < e; ++i) {
2193 Register SubReg =
2194 SB.NumSubRegs == 1
2195 ? SB.SuperReg
2196 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2197 SpilledReg Spill = VGPRSpills[i];
2198
2199 bool IsFirstSubreg = i == 0;
2200 bool IsLastSubreg = i == SB.NumSubRegs - 1;
2201 bool UseKill = SB.IsKill && IsLastSubreg;
2202
2203
2204 // Mark the "old value of vgpr" input undef only if this is the first sgpr
2205 // spill to this specific vgpr in the first basic block.
2206 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2207 SB.TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), Spill.VGPR)
2208 .addReg(SubReg, getKillRegState(UseKill))
2209 .addImm(Spill.Lane)
2210 .addReg(Spill.VGPR);
2211
2212 MachineInstr *CFI = nullptr;
2213 if (NeedsCFI) {
2214 if (SB.SuperReg == SB.TRI.getReturnAddressReg(SB.MF)) {
2215 if (i == e - 1)
2216 CFI = TFL->buildCFIForSGPRToVGPRSpill(*SB.MBB, MI, DebugLoc(),
2217 AMDGPU::PC_REG, VGPRSpills);
2218 } else {
2219 CFI = TFL->buildCFIForSGPRToVGPRSpill(*SB.MBB, MI, DebugLoc(), SubReg,
2220 Spill.VGPR, Spill.Lane);
2221 }
2222 }
2223
2224 if (Indexes) {
2225 if (IsFirstSubreg)
2226 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2227 else
2228 Indexes->insertMachineInstrInMaps(*MIB);
2229
2230 if (CFI)
2231 Indexes->insertMachineInstrInMaps(*CFI);
2232 }
2233
2234 if (IsFirstSubreg && SB.NumSubRegs > 1) {
2235 // We may be spilling a super-register which is only partially defined,
2236 // and need to ensure later spills think the value is defined.
2237 MIB.addReg(SB.SuperReg, RegState::ImplicitDefine);
2238 }
2239
2240 if (SB.NumSubRegs > 1 && (IsFirstSubreg || IsLastSubreg))
2241 MIB.addReg(SB.SuperReg, getKillRegState(UseKill) | RegState::Implicit);
2242
2243 // FIXME: Since this spills to another register instead of an actual
2244 // frame index, we should delete the frame index when all references to
2245 // it are fixed.
2246 }
2247 } else {
2248 SB.prepare();
2249
2250 // SubReg carries the "Kill" flag when SubReg == SB.SuperReg.
2251 RegState SubKillState = getKillRegState((SB.NumSubRegs == 1) && SB.IsKill);
2252
2253 // Per VGPR helper data
2254 auto PVD = SB.getPerVGPRData();
2255
2256 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2257 RegState TmpVGPRFlags = RegState::Undef;
2258
2259 // Write sub registers into the VGPR
2260 for (unsigned i = Offset * PVD.PerVGPR,
2261 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2262 i < e; ++i) {
2263 Register SubReg =
2264 SB.NumSubRegs == 1
2265 ? SB.SuperReg
2266 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2267
2268 MachineInstrBuilder WriteLane =
2269 BuildMI(*SB.MBB, MI, SB.DL,
2270 SB.TII.get(AMDGPU::SI_SPILL_S32_TO_VGPR), SB.TmpVGPR)
2271 .addReg(SubReg, SubKillState)
2272 .addImm(i % PVD.PerVGPR)
2273 .addReg(SB.TmpVGPR, TmpVGPRFlags);
2274 TmpVGPRFlags = {};
2275
2276 if (Indexes) {
2277 if (i == 0)
2278 Indexes->replaceMachineInstrInMaps(*MI, *WriteLane);
2279 else
2280 Indexes->insertMachineInstrInMaps(*WriteLane);
2281 }
2282
2283 // There could be undef components of a spilled super register.
2284 // TODO: Can we detect this and skip the spill?
2285 if (SB.NumSubRegs > 1) {
2286 // The last implicit use of the SB.SuperReg carries the "Kill" flag.
2287 RegState SuperKillState = {};
2288 if (i + 1 == SB.NumSubRegs)
2289 SuperKillState |= getKillRegState(SB.IsKill);
2290 WriteLane.addReg(SB.SuperReg, RegState::Implicit | SuperKillState);
2291 }
2292 }
2293
2294 // Write out VGPR
2295 SB.readWriteTmpVGPR(Offset, /*IsLoad*/ false);
2296
2297 // TODO: Implement CFI for SpillToVMEM for all scenarios.
2298 MachineInstr *CFI = nullptr;
2299 if (NeedsCFI && SB.SuperReg == SB.TRI.getReturnAddressReg(SB.MF)) {
2300 int64_t CFIOffset = (Offset * SB.EltSize +
2301 SB.MF.getFrameInfo().getObjectOffset(Index)) *
2302 ST.getWavefrontSize();
2303 CFI = TFL->buildCFIForSGPRToVMEMSpill(*SB.MBB, MI, DebugLoc(),
2304 AMDGPU::PC_REG, CFIOffset);
2305 }
2306 if (Indexes && CFI)
2307 Indexes->insertMachineInstrInMaps(*CFI);
2308 }
2309
2310 SB.restore();
2311 }
2312
2313 MI->eraseFromParent();
2315
2316 if (LIS)
2318
2319 return true;
2320}
2321
2323 RegScavenger *RS, SlotIndexes *Indexes,
2324 LiveIntervals *LIS, bool OnlyToVGPR,
2325 bool SpillToPhysVGPRLane) const {
2326 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, Index, RS);
2327
2328 ArrayRef<SpilledReg> VGPRSpills =
2329 SpillToPhysVGPRLane ? SB.MFI.getSGPRSpillToPhysicalVGPRLanes(Index)
2331 bool SpillToVGPR = !VGPRSpills.empty();
2332 if (OnlyToVGPR && !SpillToVGPR)
2333 return false;
2334
2335 if (SpillToVGPR) {
2336 for (unsigned i = 0, e = SB.NumSubRegs; i < e; ++i) {
2337 Register SubReg =
2338 SB.NumSubRegs == 1
2339 ? SB.SuperReg
2340 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2341
2342 SpilledReg Spill = VGPRSpills[i];
2343 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2344 SB.TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2345 .addReg(Spill.VGPR)
2346 .addImm(Spill.Lane);
2347 if (SB.NumSubRegs > 1 && i == 0)
2349 if (Indexes) {
2350 if (i == e - 1)
2351 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2352 else
2353 Indexes->insertMachineInstrInMaps(*MIB);
2354 }
2355 }
2356 } else {
2357 SB.prepare();
2358
2359 // Per VGPR helper data
2360 auto PVD = SB.getPerVGPRData();
2361
2362 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2363 // Load in VGPR data
2364 SB.readWriteTmpVGPR(Offset, /*IsLoad*/ true);
2365
2366 // Unpack lanes
2367 for (unsigned i = Offset * PVD.PerVGPR,
2368 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2369 i < e; ++i) {
2370 Register SubReg =
2371 SB.NumSubRegs == 1
2372 ? SB.SuperReg
2373 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2374
2375 bool LastSubReg = (i + 1 == e);
2376 auto MIB = BuildMI(*SB.MBB, MI, SB.DL,
2377 SB.TII.get(AMDGPU::SI_RESTORE_S32_FROM_VGPR), SubReg)
2378 .addReg(SB.TmpVGPR, getKillRegState(LastSubReg))
2379 .addImm(i);
2380 if (SB.NumSubRegs > 1 && i == 0)
2382 if (Indexes) {
2383 if (i == e - 1)
2384 Indexes->replaceMachineInstrInMaps(*MI, *MIB);
2385 else
2386 Indexes->insertMachineInstrInMaps(*MIB);
2387 }
2388 }
2389 }
2390
2391 SB.restore();
2392 }
2393
2394 MI->eraseFromParent();
2395
2396 if (LIS)
2398
2399 return true;
2400}
2401
2403 MachineBasicBlock &RestoreMBB,
2404 Register SGPR, RegScavenger *RS) const {
2405 SGPRSpillBuilder SB(*this, *ST.getInstrInfo(), isWave32, MI, SGPR, false, 0,
2406 RS);
2407 SB.prepare();
2408 // Generate the spill of SGPR to SB.TmpVGPR.
2409 RegState SubKillState = getKillRegState((SB.NumSubRegs == 1) && SB.IsKill);
2410 auto PVD = SB.getPerVGPRData();
2411 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2412 RegState TmpVGPRFlags = RegState::Undef;
2413 // Write sub registers into the VGPR
2414 for (unsigned i = Offset * PVD.PerVGPR,
2415 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2416 i < e; ++i) {
2417 Register SubReg =
2418 SB.NumSubRegs == 1
2419 ? SB.SuperReg
2420 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2421
2422 MachineInstrBuilder WriteLane =
2423 BuildMI(*SB.MBB, MI, SB.DL, SB.TII.get(AMDGPU::V_WRITELANE_B32),
2424 SB.TmpVGPR)
2425 .addReg(SubReg, SubKillState)
2426 .addImm(i % PVD.PerVGPR)
2427 .addReg(SB.TmpVGPR, TmpVGPRFlags);
2428 TmpVGPRFlags = {};
2429 // There could be undef components of a spilled super register.
2430 // TODO: Can we detect this and skip the spill?
2431 if (SB.NumSubRegs > 1) {
2432 // The last implicit use of the SB.SuperReg carries the "Kill" flag.
2433 RegState SuperKillState = {};
2434 if (i + 1 == SB.NumSubRegs)
2435 SuperKillState |= getKillRegState(SB.IsKill);
2436 WriteLane.addReg(SB.SuperReg, RegState::Implicit | SuperKillState);
2437 }
2438 }
2439 // Don't need to write VGPR out.
2440 }
2441
2442 // Restore clobbered registers in the specified restore block.
2443 MI = RestoreMBB.end();
2444 SB.setMI(&RestoreMBB, MI);
2445 // Generate the restore of SGPR from SB.TmpVGPR.
2446 for (unsigned Offset = 0; Offset < PVD.NumVGPRs; ++Offset) {
2447 // Don't need to load VGPR in.
2448 // Unpack lanes
2449 for (unsigned i = Offset * PVD.PerVGPR,
2450 e = std::min((Offset + 1) * PVD.PerVGPR, SB.NumSubRegs);
2451 i < e; ++i) {
2452 Register SubReg =
2453 SB.NumSubRegs == 1
2454 ? SB.SuperReg
2455 : Register(getSubReg(SB.SuperReg, SB.SplitParts[i]));
2456
2457 assert(SubReg.isPhysical());
2458 bool LastSubReg = (i + 1 == e);
2459 auto MIB = BuildMI(*SB.MBB, MI, SB.DL, SB.TII.get(AMDGPU::V_READLANE_B32),
2460 SubReg)
2461 .addReg(SB.TmpVGPR, getKillRegState(LastSubReg))
2462 .addImm(i);
2463 if (SB.NumSubRegs > 1 && i == 0)
2465 }
2466 }
2467 SB.restore();
2468
2470 return false;
2471}
2472
2473/// Special case of eliminateFrameIndex. Returns true if the SGPR was spilled to
2474/// a VGPR and the stack slot can be safely eliminated when all other users are
2475/// handled.
2478 SlotIndexes *Indexes, LiveIntervals *LIS, bool SpillToPhysVGPRLane) const {
2479 bool NeedsCFI = false;
2480 switch (MI->getOpcode()) {
2481 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2482 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2483 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2484 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2485 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2486 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2487 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2488 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2489 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2490 case AMDGPU::SI_SPILL_S32_CFI_SAVE:
2491 NeedsCFI = true;
2492 [[fallthrough]];
2493 case AMDGPU::SI_SPILL_S1024_SAVE:
2494 case AMDGPU::SI_SPILL_S512_SAVE:
2495 case AMDGPU::SI_SPILL_S384_SAVE:
2496 case AMDGPU::SI_SPILL_S352_SAVE:
2497 case AMDGPU::SI_SPILL_S320_SAVE:
2498 case AMDGPU::SI_SPILL_S288_SAVE:
2499 case AMDGPU::SI_SPILL_S256_SAVE:
2500 case AMDGPU::SI_SPILL_S224_SAVE:
2501 case AMDGPU::SI_SPILL_S192_SAVE:
2502 case AMDGPU::SI_SPILL_S160_SAVE:
2503 case AMDGPU::SI_SPILL_S128_SAVE:
2504 case AMDGPU::SI_SPILL_S96_SAVE:
2505 case AMDGPU::SI_SPILL_S64_SAVE:
2506 case AMDGPU::SI_SPILL_S32_SAVE:
2507 return spillSGPR(MI, FI, RS, Indexes, LIS, true, SpillToPhysVGPRLane,
2508 NeedsCFI);
2509 case AMDGPU::SI_SPILL_S1024_RESTORE:
2510 case AMDGPU::SI_SPILL_S512_RESTORE:
2511 case AMDGPU::SI_SPILL_S384_RESTORE:
2512 case AMDGPU::SI_SPILL_S352_RESTORE:
2513 case AMDGPU::SI_SPILL_S320_RESTORE:
2514 case AMDGPU::SI_SPILL_S288_RESTORE:
2515 case AMDGPU::SI_SPILL_S256_RESTORE:
2516 case AMDGPU::SI_SPILL_S224_RESTORE:
2517 case AMDGPU::SI_SPILL_S192_RESTORE:
2518 case AMDGPU::SI_SPILL_S160_RESTORE:
2519 case AMDGPU::SI_SPILL_S128_RESTORE:
2520 case AMDGPU::SI_SPILL_S96_RESTORE:
2521 case AMDGPU::SI_SPILL_S64_RESTORE:
2522 case AMDGPU::SI_SPILL_S32_RESTORE:
2523 return restoreSGPR(MI, FI, RS, Indexes, LIS, true, SpillToPhysVGPRLane);
2524 default:
2525 llvm_unreachable("not an SGPR spill instruction");
2526 }
2527}
2528
2529// Does adding the low 32 bits of \p LHS and \p RHS carry out?
2530static bool wrapsAround32(int64_t LHS, int64_t RHS) {
2531 return static_cast<uint64_t>(static_cast<uint32_t>(LHS)) +
2532 static_cast<uint32_t>(RHS) >
2533 UINT32_MAX;
2534}
2535
2536// Would folding Offset into OtherOp (in place of a separate frame-base add)
2537// use a different carry-out than the unfolded add?
2539 int64_t Offset, Register FrameReg) {
2540 return OtherOp.isImm() ? wrapsAround32(OtherOp.getImm(), Offset)
2541 : FrameReg.isValid();
2542}
2543
2545 int SPAdj, unsigned FIOperandNum,
2546 RegScavenger *RS) const {
2547 MachineFunction *MF = MI->getMF();
2548 MachineBasicBlock *MBB = MI->getParent();
2550 MachineFrameInfo &FrameInfo = MF->getFrameInfo();
2551 const SIInstrInfo *TII = ST.getInstrInfo();
2552 const DebugLoc &DL = MI->getDebugLoc();
2553
2554 assert(SPAdj == 0 && "unhandled SP adjustment in call sequence?");
2555
2557 "unreserved scratch RSRC register");
2558
2559 MachineOperand *FIOp = &MI->getOperand(FIOperandNum);
2560 int Index = MI->getOperand(FIOperandNum).getIndex();
2561
2562 Register FrameReg = FrameInfo.isFixedObjectIndex(Index) && hasBasePointer(*MF)
2563 ? getBaseRegister()
2564 : getFrameRegister(*MF);
2565
2566 bool NeedsCFI = false;
2567
2568 switch (MI->getOpcode()) {
2569 // SGPR register spill
2570 case AMDGPU::SI_SPILL_S1024_CFI_SAVE:
2571 case AMDGPU::SI_SPILL_S512_CFI_SAVE:
2572 case AMDGPU::SI_SPILL_S256_CFI_SAVE:
2573 case AMDGPU::SI_SPILL_S224_CFI_SAVE:
2574 case AMDGPU::SI_SPILL_S192_CFI_SAVE:
2575 case AMDGPU::SI_SPILL_S160_CFI_SAVE:
2576 case AMDGPU::SI_SPILL_S128_CFI_SAVE:
2577 case AMDGPU::SI_SPILL_S96_CFI_SAVE:
2578 case AMDGPU::SI_SPILL_S64_CFI_SAVE:
2579 case AMDGPU::SI_SPILL_S32_CFI_SAVE: {
2580 NeedsCFI = true;
2581 [[fallthrough]];
2582 }
2583 case AMDGPU::SI_SPILL_S1024_SAVE:
2584 case AMDGPU::SI_SPILL_S512_SAVE:
2585 case AMDGPU::SI_SPILL_S384_SAVE:
2586 case AMDGPU::SI_SPILL_S352_SAVE:
2587 case AMDGPU::SI_SPILL_S320_SAVE:
2588 case AMDGPU::SI_SPILL_S288_SAVE:
2589 case AMDGPU::SI_SPILL_S256_SAVE:
2590 case AMDGPU::SI_SPILL_S224_SAVE:
2591 case AMDGPU::SI_SPILL_S192_SAVE:
2592 case AMDGPU::SI_SPILL_S160_SAVE:
2593 case AMDGPU::SI_SPILL_S128_SAVE:
2594 case AMDGPU::SI_SPILL_S96_SAVE:
2595 case AMDGPU::SI_SPILL_S64_SAVE:
2596 case AMDGPU::SI_SPILL_S32_SAVE: {
2597 return spillSGPR(MI, Index, RS, nullptr, nullptr,
2598 FrameInfo.getStackID(Index) == TargetStackID::SGPRSpill,
2599 false, NeedsCFI);
2600 }
2601
2602 // SGPR register restore
2603 case AMDGPU::SI_SPILL_S1024_RESTORE:
2604 case AMDGPU::SI_SPILL_S512_RESTORE:
2605 case AMDGPU::SI_SPILL_S384_RESTORE:
2606 case AMDGPU::SI_SPILL_S352_RESTORE:
2607 case AMDGPU::SI_SPILL_S320_RESTORE:
2608 case AMDGPU::SI_SPILL_S288_RESTORE:
2609 case AMDGPU::SI_SPILL_S256_RESTORE:
2610 case AMDGPU::SI_SPILL_S224_RESTORE:
2611 case AMDGPU::SI_SPILL_S192_RESTORE:
2612 case AMDGPU::SI_SPILL_S160_RESTORE:
2613 case AMDGPU::SI_SPILL_S128_RESTORE:
2614 case AMDGPU::SI_SPILL_S96_RESTORE:
2615 case AMDGPU::SI_SPILL_S64_RESTORE:
2616 case AMDGPU::SI_SPILL_S32_RESTORE: {
2617 return restoreSGPR(MI, Index, RS, nullptr, nullptr,
2618 FrameInfo.getStackID(Index) ==
2620 }
2621
2622 // VGPR register spill
2623 case AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE:
2624 case AMDGPU::SI_SPILL_V1024_CFI_SAVE:
2625 case AMDGPU::SI_SPILL_V512_CFI_SAVE:
2626 case AMDGPU::SI_SPILL_V256_CFI_SAVE:
2627 case AMDGPU::SI_SPILL_V224_CFI_SAVE:
2628 case AMDGPU::SI_SPILL_V192_CFI_SAVE:
2629 case AMDGPU::SI_SPILL_V160_CFI_SAVE:
2630 case AMDGPU::SI_SPILL_V128_CFI_SAVE:
2631 case AMDGPU::SI_SPILL_V96_CFI_SAVE:
2632 case AMDGPU::SI_SPILL_V64_CFI_SAVE:
2633 case AMDGPU::SI_SPILL_V32_CFI_SAVE:
2634 case AMDGPU::SI_SPILL_A1024_CFI_SAVE:
2635 case AMDGPU::SI_SPILL_A512_CFI_SAVE:
2636 case AMDGPU::SI_SPILL_A256_CFI_SAVE:
2637 case AMDGPU::SI_SPILL_A224_CFI_SAVE:
2638 case AMDGPU::SI_SPILL_A192_CFI_SAVE:
2639 case AMDGPU::SI_SPILL_A160_CFI_SAVE:
2640 case AMDGPU::SI_SPILL_A128_CFI_SAVE:
2641 case AMDGPU::SI_SPILL_A96_CFI_SAVE:
2642 case AMDGPU::SI_SPILL_A64_CFI_SAVE:
2643 case AMDGPU::SI_SPILL_A32_CFI_SAVE:
2644 case AMDGPU::SI_SPILL_AV1024_CFI_SAVE:
2645 case AMDGPU::SI_SPILL_AV512_CFI_SAVE:
2646 case AMDGPU::SI_SPILL_AV256_CFI_SAVE:
2647 case AMDGPU::SI_SPILL_AV224_CFI_SAVE:
2648 case AMDGPU::SI_SPILL_AV192_CFI_SAVE:
2649 case AMDGPU::SI_SPILL_AV160_CFI_SAVE:
2650 case AMDGPU::SI_SPILL_AV128_CFI_SAVE:
2651 case AMDGPU::SI_SPILL_AV96_CFI_SAVE:
2652 case AMDGPU::SI_SPILL_AV64_CFI_SAVE:
2653 case AMDGPU::SI_SPILL_AV32_CFI_SAVE:
2654 NeedsCFI = true;
2655 [[fallthrough]];
2656 case AMDGPU::SI_BLOCK_SPILL_V1024_SAVE:
2657 case AMDGPU::SI_SPILL_V1024_SAVE:
2658 case AMDGPU::SI_SPILL_V512_SAVE:
2659 case AMDGPU::SI_SPILL_V384_SAVE:
2660 case AMDGPU::SI_SPILL_V352_SAVE:
2661 case AMDGPU::SI_SPILL_V320_SAVE:
2662 case AMDGPU::SI_SPILL_V288_SAVE:
2663 case AMDGPU::SI_SPILL_V256_SAVE:
2664 case AMDGPU::SI_SPILL_V224_SAVE:
2665 case AMDGPU::SI_SPILL_V192_SAVE:
2666 case AMDGPU::SI_SPILL_V160_SAVE:
2667 case AMDGPU::SI_SPILL_V128_SAVE:
2668 case AMDGPU::SI_SPILL_V96_SAVE:
2669 case AMDGPU::SI_SPILL_V64_SAVE:
2670 case AMDGPU::SI_SPILL_V32_SAVE:
2671 case AMDGPU::SI_SPILL_V16_SAVE:
2672 case AMDGPU::SI_SPILL_A1024_SAVE:
2673 case AMDGPU::SI_SPILL_A512_SAVE:
2674 case AMDGPU::SI_SPILL_A384_SAVE:
2675 case AMDGPU::SI_SPILL_A352_SAVE:
2676 case AMDGPU::SI_SPILL_A320_SAVE:
2677 case AMDGPU::SI_SPILL_A288_SAVE:
2678 case AMDGPU::SI_SPILL_A256_SAVE:
2679 case AMDGPU::SI_SPILL_A224_SAVE:
2680 case AMDGPU::SI_SPILL_A192_SAVE:
2681 case AMDGPU::SI_SPILL_A160_SAVE:
2682 case AMDGPU::SI_SPILL_A128_SAVE:
2683 case AMDGPU::SI_SPILL_A96_SAVE:
2684 case AMDGPU::SI_SPILL_A64_SAVE:
2685 case AMDGPU::SI_SPILL_A32_SAVE:
2686 case AMDGPU::SI_SPILL_AV1024_SAVE:
2687 case AMDGPU::SI_SPILL_AV512_SAVE:
2688 case AMDGPU::SI_SPILL_AV384_SAVE:
2689 case AMDGPU::SI_SPILL_AV352_SAVE:
2690 case AMDGPU::SI_SPILL_AV320_SAVE:
2691 case AMDGPU::SI_SPILL_AV288_SAVE:
2692 case AMDGPU::SI_SPILL_AV256_SAVE:
2693 case AMDGPU::SI_SPILL_AV224_SAVE:
2694 case AMDGPU::SI_SPILL_AV192_SAVE:
2695 case AMDGPU::SI_SPILL_AV160_SAVE:
2696 case AMDGPU::SI_SPILL_AV128_SAVE:
2697 case AMDGPU::SI_SPILL_AV96_SAVE:
2698 case AMDGPU::SI_SPILL_AV64_SAVE:
2699 case AMDGPU::SI_SPILL_AV32_SAVE:
2700 case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2701 case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
2702 assert(
2703 MI->getOpcode() != AMDGPU::SI_BLOCK_SPILL_V1024_SAVE &&
2704 "block spill does not currenty support spilling non-CSR registers");
2705
2706 if (MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE)
2707 // Put mask into M0.
2708 BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_MOV_B32),
2709 AMDGPU::M0)
2710 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::mask));
2711
2712 const MachineOperand *VData = TII->getNamedOperand(*MI,
2713 AMDGPU::OpName::vdata);
2714 if (VData->isUndef()) {
2715 MI->eraseFromParent();
2716 return true;
2717 }
2718
2719 assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==
2720 MFI->getStackPtrOffsetReg());
2721
2722 unsigned Opc;
2723 if (MI->getOpcode() == AMDGPU::SI_SPILL_V16_SAVE) {
2724 assert(ST.hasFlatScratchEnabled() && "Flat Scratch is not enabled!");
2725 Opc = AMDGPU::SCRATCH_STORE_SHORT_SADDR_t16;
2726 } else {
2727 Opc = MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_CFI_SAVE
2728 ? AMDGPU::SCRATCH_STORE_BLOCK_SADDR
2729 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_STORE_DWORD_SADDR
2730 : AMDGPU::BUFFER_STORE_DWORD_OFFSET;
2731 }
2732
2733 auto *MBB = MI->getParent();
2734 bool IsWWMRegSpill = TII->isWWMRegSpillOpcode(MI->getOpcode());
2735 if (IsWWMRegSpill) {
2736 TII->insertScratchExecCopy(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy(),
2737 RS->isRegUsed(AMDGPU::SCC));
2738 }
2740 *MBB, MI, DL, Opc, Index, VData->getReg(), VData->isKill(), FrameReg,
2741 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(),
2742 *MI->memoperands_begin(), RS, nullptr, NeedsCFI);
2744 if (IsWWMRegSpill)
2745 TII->restoreExec(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy());
2746
2747 MI->eraseFromParent();
2748 return true;
2749 }
2750 case AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE: {
2751 // Put mask into M0.
2752 BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_MOV_B32),
2753 AMDGPU::M0)
2754 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::mask));
2755 [[fallthrough]];
2756 }
2757 case AMDGPU::SI_SPILL_V16_RESTORE:
2758 case AMDGPU::SI_SPILL_V32_RESTORE:
2759 case AMDGPU::SI_SPILL_V64_RESTORE:
2760 case AMDGPU::SI_SPILL_V96_RESTORE:
2761 case AMDGPU::SI_SPILL_V128_RESTORE:
2762 case AMDGPU::SI_SPILL_V160_RESTORE:
2763 case AMDGPU::SI_SPILL_V192_RESTORE:
2764 case AMDGPU::SI_SPILL_V224_RESTORE:
2765 case AMDGPU::SI_SPILL_V256_RESTORE:
2766 case AMDGPU::SI_SPILL_V288_RESTORE:
2767 case AMDGPU::SI_SPILL_V320_RESTORE:
2768 case AMDGPU::SI_SPILL_V352_RESTORE:
2769 case AMDGPU::SI_SPILL_V384_RESTORE:
2770 case AMDGPU::SI_SPILL_V512_RESTORE:
2771 case AMDGPU::SI_SPILL_V1024_RESTORE:
2772 case AMDGPU::SI_SPILL_A32_RESTORE:
2773 case AMDGPU::SI_SPILL_A64_RESTORE:
2774 case AMDGPU::SI_SPILL_A96_RESTORE:
2775 case AMDGPU::SI_SPILL_A128_RESTORE:
2776 case AMDGPU::SI_SPILL_A160_RESTORE:
2777 case AMDGPU::SI_SPILL_A192_RESTORE:
2778 case AMDGPU::SI_SPILL_A224_RESTORE:
2779 case AMDGPU::SI_SPILL_A256_RESTORE:
2780 case AMDGPU::SI_SPILL_A288_RESTORE:
2781 case AMDGPU::SI_SPILL_A320_RESTORE:
2782 case AMDGPU::SI_SPILL_A352_RESTORE:
2783 case AMDGPU::SI_SPILL_A384_RESTORE:
2784 case AMDGPU::SI_SPILL_A512_RESTORE:
2785 case AMDGPU::SI_SPILL_A1024_RESTORE:
2786 case AMDGPU::SI_SPILL_AV32_RESTORE:
2787 case AMDGPU::SI_SPILL_AV64_RESTORE:
2788 case AMDGPU::SI_SPILL_AV96_RESTORE:
2789 case AMDGPU::SI_SPILL_AV128_RESTORE:
2790 case AMDGPU::SI_SPILL_AV160_RESTORE:
2791 case AMDGPU::SI_SPILL_AV192_RESTORE:
2792 case AMDGPU::SI_SPILL_AV224_RESTORE:
2793 case AMDGPU::SI_SPILL_AV256_RESTORE:
2794 case AMDGPU::SI_SPILL_AV288_RESTORE:
2795 case AMDGPU::SI_SPILL_AV320_RESTORE:
2796 case AMDGPU::SI_SPILL_AV352_RESTORE:
2797 case AMDGPU::SI_SPILL_AV384_RESTORE:
2798 case AMDGPU::SI_SPILL_AV512_RESTORE:
2799 case AMDGPU::SI_SPILL_AV1024_RESTORE:
2800 case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2801 case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
2802 const MachineOperand *VData = TII->getNamedOperand(*MI,
2803 AMDGPU::OpName::vdata);
2804 assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==
2805 MFI->getStackPtrOffsetReg());
2806
2807 unsigned Opc;
2808 if (MI->getOpcode() == AMDGPU::SI_SPILL_V16_RESTORE) {
2809 assert(ST.hasFlatScratchEnabled() && "Flat Scratch is not enabled!");
2810 Opc = ST.d16PreservesUnusedBits()
2811 ? AMDGPU::SCRATCH_LOAD_SHORT_D16_SADDR_t16
2812 : AMDGPU::SCRATCH_LOAD_USHORT_SADDR;
2813 } else {
2814 Opc = MI->getOpcode() == AMDGPU::SI_BLOCK_SPILL_V1024_RESTORE
2815 ? AMDGPU::SCRATCH_LOAD_BLOCK_SADDR
2816 : ST.hasFlatScratchEnabled() ? AMDGPU::SCRATCH_LOAD_DWORD_SADDR
2817 : AMDGPU::BUFFER_LOAD_DWORD_OFFSET;
2818 }
2819
2820 auto *MBB = MI->getParent();
2821 bool IsWWMRegSpill = TII->isWWMRegSpillOpcode(MI->getOpcode());
2822 if (IsWWMRegSpill) {
2823 TII->insertScratchExecCopy(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy(),
2824 RS->isRegUsed(AMDGPU::SCC));
2825 }
2826
2828 *MBB, MI, DL, Opc, Index, VData->getReg(), VData->isKill(), FrameReg,
2829 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(),
2830 *MI->memoperands_begin(), RS);
2831
2832 if (IsWWMRegSpill)
2833 TII->restoreExec(*MF, *MBB, MI, DL, MFI->getSGPRForEXECCopy());
2834
2835 MI->eraseFromParent();
2836 return true;
2837 }
2838 case AMDGPU::V_ADD_U32_e32:
2839 case AMDGPU::V_ADD_U32_e64:
2840 case AMDGPU::V_ADD_CO_U32_e32:
2841 case AMDGPU::V_ADD_CO_U32_e64: {
2842 // TODO: Handle sub, and, or.
2843 unsigned NumDefs = MI->getNumExplicitDefs();
2844 unsigned Src0Idx = NumDefs;
2845
2846 bool HasClamp = false;
2847 MachineOperand *VCCOp = nullptr;
2848
2849 switch (MI->getOpcode()) {
2850 case AMDGPU::V_ADD_U32_e32:
2851 break;
2852 case AMDGPU::V_ADD_U32_e64:
2853 HasClamp = MI->getOperand(3).getImm();
2854 break;
2855 case AMDGPU::V_ADD_CO_U32_e32:
2856 VCCOp = &MI->getOperand(3);
2857 break;
2858 case AMDGPU::V_ADD_CO_U32_e64:
2859 VCCOp = &MI->getOperand(1);
2860 HasClamp = MI->getOperand(4).getImm();
2861 break;
2862 default:
2863 break;
2864 }
2865 bool DeadVCC = !VCCOp || VCCOp->isDead();
2866 MachineOperand &DstOp = MI->getOperand(0);
2867 Register DstReg = DstOp.getReg();
2868
2869 unsigned OtherOpIdx =
2870 FIOperandNum == Src0Idx ? FIOperandNum + 1 : Src0Idx;
2871 MachineOperand *OtherOp = &MI->getOperand(OtherOpIdx);
2872
2873 unsigned Src1Idx = Src0Idx + 1;
2874 Register MaterializedReg = FrameReg;
2875 Register ScavengedVGPR;
2876
2877 int64_t Offset = FrameInfo.getObjectOffset(Index);
2878
2879 // A split or wrapping fold add carries out of the wrong sum, and clamp
2880 // does not distribute.
2881 if ((!DeadVCC || HasClamp) &&
2882 foldingOffsetChangesCarry(*OtherOp, Offset, FrameReg))
2883 break;
2884
2885 // For the non-immediate case, we could fall through to the default
2886 // handling, but we do an in-place update of the result register here to
2887 // avoid scavenging another register.
2888 if (OtherOp->isImm()) {
2889 int64_t TotalOffset = OtherOp->getImm() + Offset;
2890
2891 if (!ST.hasVOP3Literal() && SIInstrInfo::isVOP3(*MI) &&
2892 !AMDGPU::isInlinableIntLiteral(TotalOffset)) {
2893 // If we can't support a VOP3 literal in the VALU instruction, we
2894 // can't specially fold into the add.
2895 // TODO: Handle VOP3->VOP2 shrink to support the fold.
2896 break;
2897 }
2898
2899 OtherOp->setImm(TotalOffset);
2900 Offset = 0;
2901 }
2902
2903 if (FrameReg && !ST.hasFlatScratchEnabled()) {
2904 // We should just do an in-place update of the result register. However,
2905 // the value there may also be used by the add, in which case we need a
2906 // temporary register.
2907 //
2908 // FIXME: The scavenger is not finding the result register in the
2909 // common case where the add does not read the register.
2910
2911 ScavengedVGPR = RS->scavengeRegisterBackwards(
2912 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false, /*SPAdj=*/0);
2913
2914 // TODO: If we have a free SGPR, it's sometimes better to use a scalar
2915 // shift.
2916 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64))
2917 .addDef(ScavengedVGPR, RegState::Renamable)
2918 .addImm(ST.getWavefrontSizeLog2())
2919 .addReg(FrameReg);
2920 MaterializedReg = ScavengedVGPR;
2921 }
2922
2923 if ((!OtherOp->isImm() || OtherOp->getImm() != 0) && MaterializedReg) {
2924 if (OtherOp->isImm()) {
2925 FIOp->ChangeToRegister(MaterializedReg, false);
2926 FIOp->setIsKill(MaterializedReg != FrameReg);
2927 } else {
2928 if (ST.hasFlatScratchEnabled() &&
2929 !TII->isOperandLegal(*MI, Src1Idx, OtherOp)) {
2930 // We didn't need the shift above, so we have an SGPR for the frame
2931 // register, but may have a VGPR only operand.
2932 //
2933 // TODO: On gfx10+, we can easily change the opcode to the e64
2934 // version and use the higher constant bus restriction to avoid this
2935 // copy.
2936
2937 if (!ScavengedVGPR) {
2938 ScavengedVGPR = RS->scavengeRegisterBackwards(
2939 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false,
2940 /*SPAdj=*/0);
2941 }
2942
2943 assert(ScavengedVGPR != DstReg);
2944
2945 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_MOV_B32_e32),
2946 ScavengedVGPR)
2947 .addReg(MaterializedReg,
2948 getKillRegState(MaterializedReg != FrameReg));
2949 MaterializedReg = ScavengedVGPR;
2950 }
2951
2952 // TODO: In the flat scratch case, if this is an add of an SGPR, and
2953 // SCC is not live, we could use a scalar add + vector add instead of
2954 // 2 vector adds.
2955 auto AddI32 = BuildMI(*MBB, *MI, DL, TII->get(MI->getOpcode()))
2956 .addDef(DstReg, RegState::Renamable);
2957 if (NumDefs == 2)
2958 AddI32.add(MI->getOperand(1));
2959
2960 RegState MaterializedRegFlags =
2961 getKillRegState(MaterializedReg != FrameReg);
2962
2963 if (isVGPRClass(getPhysRegBaseClass(MaterializedReg))) {
2964 // If we know we have a VGPR already, it's more likely the other
2965 // operand is a legal vsrc0.
2966 AddI32.add(*OtherOp).addReg(MaterializedReg, MaterializedRegFlags);
2967 } else {
2968 // Commute operands to avoid violating VOP2 restrictions. This will
2969 // typically happen when using scratch.
2970 AddI32.addReg(MaterializedReg, MaterializedRegFlags).add(*OtherOp);
2971 }
2972
2973 if (MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
2974 MI->getOpcode() == AMDGPU::V_ADD_U32_e64)
2975 AddI32.addImm(0); // clamp
2976
2977 if (MI->getOpcode() == AMDGPU::V_ADD_CO_U32_e32)
2978 AddI32.setOperandDead(3); // Dead vcc
2979
2980 MaterializedReg = DstReg;
2981
2982 OtherOp->ChangeToRegister(MaterializedReg, false);
2983 OtherOp->setIsKill(true);
2985 Offset = 0;
2986 }
2987 } else if (Offset != 0) {
2988 assert(!MaterializedReg);
2990 Offset = 0;
2991 } else {
2992 if (DeadVCC && !HasClamp) {
2993 assert(Offset == 0);
2994
2995 // TODO: Losing kills and implicit operands. Just mutate to copy and
2996 // let lowerCopy deal with it?
2997 if (OtherOp->isReg() && OtherOp->getReg() == DstReg) {
2998 // Folded to an identity copy.
2999 MI->eraseFromParent();
3000 return true;
3001 }
3002
3003 // The immediate value should be in OtherOp
3004 MI->setDesc(TII->get(AMDGPU::V_MOV_B32_e32));
3005 MI->removeOperand(FIOperandNum);
3006
3007 unsigned NumOps = MI->getNumOperands();
3008 for (unsigned I = NumOps - 2; I >= NumDefs + 1; --I)
3009 MI->removeOperand(I);
3010
3011 if (NumDefs == 2)
3012 MI->removeOperand(1);
3013
3014 // The code below can't deal with a mov.
3015 return true;
3016 }
3017
3018 // This folded to a constant, but we have to keep the add around for
3019 // pointless implicit defs or clamp modifier.
3020 FIOp->ChangeToImmediate(0);
3021 }
3022
3023 // Try to improve legality by commuting.
3024 if (!TII->isOperandLegal(*MI, Src1Idx) && TII->commuteInstruction(*MI)) {
3025 std::swap(FIOp, OtherOp);
3026 std::swap(FIOperandNum, OtherOpIdx);
3027 }
3028
3029 // We need at most one mov to satisfy the operand constraints. Prefer to
3030 // move the FI operand first, as it may be a literal in a VOP3
3031 // instruction.
3032 for (unsigned SrcIdx : {FIOperandNum, OtherOpIdx}) {
3033 if (!TII->isOperandLegal(*MI, SrcIdx)) {
3034 // If commuting didn't make the operands legal, we need to materialize
3035 // in a register.
3036 // TODO: Can use SGPR on gfx10+ in some cases.
3037 if (!ScavengedVGPR) {
3038 ScavengedVGPR = RS->scavengeRegisterBackwards(
3039 AMDGPU::VGPR_32RegClass, MI, /*RestoreAfter=*/false,
3040 /*SPAdj=*/0);
3041 }
3042
3043 assert(ScavengedVGPR != DstReg);
3044
3045 MachineOperand &Src = MI->getOperand(SrcIdx);
3046 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), ScavengedVGPR)
3047 .add(Src);
3048
3049 Src.ChangeToRegister(ScavengedVGPR, false);
3050 Src.setIsKill(true);
3051 break;
3052 }
3053 }
3054
3055 // Fold out add of 0 case that can appear in kernels.
3056 if (FIOp->isImm() && FIOp->getImm() == 0 && DeadVCC && !HasClamp) {
3057 if (OtherOp->isReg() && OtherOp->getReg() != DstReg) {
3058 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::COPY), DstReg).add(*OtherOp);
3059 }
3060
3061 MI->eraseFromParent();
3062 }
3063
3064 return true;
3065 }
3066 case AMDGPU::S_ADD_I32:
3067 case AMDGPU::S_ADD_U32: {
3068 // TODO: Handle s_or_b32, s_and_b32.
3069 unsigned OtherOpIdx = FIOperandNum == 1 ? 2 : 1;
3070 MachineOperand &OtherOp = MI->getOperand(OtherOpIdx);
3071
3072 assert(FrameReg || MFI->isBottomOfStack());
3073
3074 MachineOperand &DstOp = MI->getOperand(0);
3075 const DebugLoc &DL = MI->getDebugLoc();
3076 Register MaterializedReg = FrameReg;
3077
3078 int64_t Offset = FrameInfo.getObjectOffset(Index);
3079
3080 // See the VALU adds above, with SCC in place of the carry-out.
3081 bool DeadSCC = MI->getOperand(3).isDead();
3082 if (!DeadSCC && foldingOffsetChangesCarry(OtherOp, Offset, FrameReg))
3083 break;
3084
3085 Register TmpReg;
3086
3087 // FIXME: Scavenger should figure out that the result register is
3088 // available. Also should do this for the v_add case.
3089 if (OtherOp.isReg() && OtherOp.getReg() != DstOp.getReg())
3090 TmpReg = DstOp.getReg();
3091
3092 if (FrameReg && !ST.hasFlatScratchEnabled()) {
3093 // FIXME: In the common case where the add does not also read its result
3094 // (i.e. this isn't a reg += fi), it's not finding the dest reg as
3095 // available.
3096 if (!TmpReg)
3097 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3098 MI, /*RestoreAfter=*/false, 0,
3099 /*AllowSpill=*/false);
3100 if (TmpReg) {
3101 BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::S_LSHR_B32))
3102 .addDef(TmpReg, RegState::Renamable)
3103 .addReg(FrameReg)
3104 .addImm(ST.getWavefrontSizeLog2())
3105 .setOperandDead(3); // Set SCC dead
3106 }
3107 MaterializedReg = TmpReg;
3108 }
3109
3110 // For the non-immediate case, we could fall through to the default
3111 // handling, but we do an in-place update of the result register here to
3112 // avoid scavenging another register.
3113 if (OtherOp.isImm()) {
3114 OtherOp.setImm(OtherOp.getImm() + Offset);
3115 Offset = 0;
3116
3117 if (MaterializedReg)
3118 FIOp->ChangeToRegister(MaterializedReg, false);
3119 else
3120 FIOp->ChangeToImmediate(0);
3121 } else if (MaterializedReg) {
3122 // If we can't fold the other operand, do another increment.
3123 Register DstReg = DstOp.getReg();
3124
3125 if (!TmpReg && MaterializedReg == FrameReg) {
3126 TmpReg = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3127 MI, /*RestoreAfter=*/false, 0,
3128 /*AllowSpill=*/false);
3129 DstReg = TmpReg;
3130 }
3131
3132 if (TmpReg) {
3133 auto AddI32 = BuildMI(*MBB, *MI, DL, MI->getDesc())
3134 .addDef(DstReg, RegState::Renamable)
3135 .addReg(MaterializedReg, RegState::Kill)
3136 .add(OtherOp);
3137 if (DeadSCC)
3138 AddI32.setOperandDead(3);
3139
3140 MaterializedReg = DstReg;
3141
3142 OtherOp.ChangeToRegister(MaterializedReg, false);
3143 OtherOp.setIsKill(true);
3144 OtherOp.setIsRenamable(true);
3145 }
3147 } else {
3148 // If we don't have any other offset to apply, we can just directly
3149 // interpret the frame index as the offset.
3151 }
3152
3153 if (DeadSCC && OtherOp.isImm() && OtherOp.getImm() == 0) {
3154 assert(Offset == 0);
3155 MI->removeOperand(3);
3156 MI->removeOperand(OtherOpIdx);
3157 MachineOperand &Src = MI->getOperand(1);
3158 MI->setDesc(TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3159 } else if (DeadSCC && FIOp->isImm() && FIOp->getImm() == 0) {
3160 assert(Offset == 0);
3161 MI->removeOperand(3);
3162 MI->removeOperand(FIOperandNum);
3163 MachineOperand &Src = MI->getOperand(1);
3164 MI->setDesc(TII->get(Src.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
3165 }
3166
3167 assert(!FIOp->isFI());
3168 return true;
3169 }
3170 default: {
3171 break;
3172 }
3173 }
3174
3175 int64_t Offset = FrameInfo.getObjectOffset(Index);
3176 if (ST.hasFlatScratchEnabled()) {
3177 if (TII->isFLATScratch(*MI)) {
3178 assert(
3179 (int16_t)FIOperandNum ==
3180 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::saddr));
3181
3182 // The offset is always swizzled, just replace it
3183 if (FrameReg)
3184 FIOp->ChangeToRegister(FrameReg, false);
3185
3187 TII->getNamedOperand(*MI, AMDGPU::OpName::offset);
3188 int64_t NewOffset = Offset + OffsetOp->getImm();
3189 if (TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
3191 OffsetOp->setImm(NewOffset);
3192 if (FrameReg)
3193 return false;
3194 Offset = 0;
3195 }
3196
3197 if (!Offset) {
3198 unsigned Opc = MI->getOpcode();
3199 int NewOpc = -1;
3200 if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vaddr)) {
3202 } else if (ST.hasFlatScratchSTMode()) {
3203 // On GFX10 we have ST mode to use no registers for an address.
3204 // Otherwise we need to materialize 0 into an SGPR.
3206 }
3207
3208 if (NewOpc != -1) {
3209 // removeOperand doesn't fixup tied operand indexes as it goes, so
3210 // it asserts. Untie vdst_in for now and retie them afterwards.
3211 int VDstIn =
3212 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst_in);
3213 bool TiedVDst = VDstIn != -1 && MI->getOperand(VDstIn).isReg() &&
3214 MI->getOperand(VDstIn).isTied();
3215 if (TiedVDst)
3216 MI->untieRegOperand(VDstIn);
3217
3218 MI->removeOperand(
3219 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::saddr));
3220
3221 if (TiedVDst) {
3222 int NewVDst =
3223 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
3224 int NewVDstIn =
3225 AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
3226 assert(NewVDst != -1 && NewVDstIn != -1 && "Must be tied!");
3227 MI->tieOperands(NewVDst, NewVDstIn);
3228 }
3229 MI->setDesc(TII->get(NewOpc));
3230 return false;
3231 }
3232 }
3233 }
3234
3235 if (!FrameReg) {
3237 if (TII->isOperandLegal(*MI, FIOperandNum, FIOp))
3238 return false;
3239 }
3240
3241 // We need to use register here. Check if we can use an SGPR or need
3242 // a VGPR.
3243 FIOp->ChangeToRegister(AMDGPU::M0, false);
3244 bool UseSGPR = TII->isOperandLegal(*MI, FIOperandNum, FIOp);
3245
3246 if (!Offset && FrameReg && UseSGPR) {
3247 FIOp->setReg(FrameReg);
3248 return false;
3249 }
3250
3251 const TargetRegisterClass *RC =
3252 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3253
3254 Register TmpReg =
3255 RS->scavengeRegisterBackwards(*RC, MI, false, 0, !UseSGPR);
3256 FIOp->setReg(TmpReg);
3257 FIOp->setIsKill();
3258
3259 if ((!FrameReg || !Offset) && TmpReg) {
3260 unsigned Opc = UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
3261 auto MIB = BuildMI(*MBB, MI, DL, TII->get(Opc), TmpReg);
3262 if (FrameReg)
3263 MIB.addReg(FrameReg);
3264 else
3265 MIB.addImm(Offset);
3266
3267 return false;
3268 }
3269
3270 bool NeedSaveSCC = (RS->isRegUsed(AMDGPU::SCC) &&
3271 !MI->definesRegister(AMDGPU::SCC, /*TRI=*/nullptr)) ||
3272 MI->readsRegister(AMDGPU::SCC, /*TRI=*/nullptr);
3273
3274 Register TmpSReg =
3275 UseSGPR ? TmpReg
3276 : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3277 MI, false, 0, !UseSGPR);
3278
3279 // If no SGPR was scavenged but a frame register is available, fall
3280 // through to reuse it as the temporary (computed in place, restored
3281 // after). Only bail out when there is no frame register, or a VGPR
3282 // operand is needed but none could be scavenged.
3283 if ((!TmpSReg && !FrameReg) || (!TmpReg && !UseSGPR)) {
3284 int SVfromSSOpcode =
3286 int SVfromSVSOpcode =
3288 int SVOpcode = SVfromSSOpcode != -1 ? SVfromSSOpcode : SVfromSVSOpcode;
3289 if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
3290 // SV form encodes only the offset in vaddr; an SS-form scratch op
3291 // keeps its FI in the SGPR saddr, so this is only reached with no
3292 // frame register. SVS form has both vaddr and saddr but still depends
3293 // on the FI being in the SGPR saddr so it is also possible to end up
3294 // here through SVS form without frame register and scavenged SGPR.
3295 assert(!FrameReg &&
3296 "SV-form fallback cannot encode a frame register");
3297
3298 // Fold as much of the constant offset as possible into the SV form
3299 // instruction's immediate offset field, and materialize the
3300 // remainder (plus the frame register, if any) into the scavenged
3301 // VGPR used as the vaddr.
3302 int64_t FullOffset =
3303 Offset +
3304 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm();
3305 auto [ImmOffset, RemainderOffset] =
3306 TII->splitFlatOffset(FullOffset, AMDGPUAS::PRIVATE_ADDRESS,
3308
3309 Register UsedVAddr;
3310 if (MachineOperand *VAddr =
3311 TII->getNamedOperand(*MI, AMDGPU::OpName::vaddr)) {
3312 MachineOperand *VData =
3313 TII->getNamedOperand(*MI, AMDGPU::OpName::vdata);
3314
3315 // SVS form: add RemainderOffset to vaddr.
3316 Register Src = VAddr->getReg();
3317 bool CanReuseVAddr = VAddr->isKill() &&
3318 !(VData && regsOverlap(Src, VData->getReg()));
3319 Register Dst = CanReuseVAddr ? Src
3320 : RS->scavengeRegisterBackwards(
3321 AMDGPU::VGPR_32RegClass, MI,
3322 false, 0, /*AllowSpill=*/true);
3323 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e32), Dst)
3324 .addImm(RemainderOffset)
3325 .addReg(Src, getKillRegState(CanReuseVAddr));
3326 UsedVAddr = Dst;
3327 } else {
3328 // SS form: no vaddr, materialize remainder as vgpr.
3329 UsedVAddr = RS->scavengeRegisterBackwards(
3330 AMDGPU::VGPR_32RegClass, MI, false, 0, /*AllowSpill=*/true);
3331 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), UsedVAddr)
3332 .addImm(RemainderOffset);
3333 }
3334 BuildMI(*MBB, MI, DL, TII->get(SVOpcode))
3335 .add(MI->getOperand(0)) // $vdata
3336 .addReg(UsedVAddr, RegState::Kill) // $vaddr
3337 .addImm(ImmOffset) // $offset
3338 .add(*TII->getNamedOperand(*MI, AMDGPU::OpName::cpol));
3339 MI->eraseFromParent();
3340 return true;
3341 }
3342 report_fatal_error("Cannot scavenge register in FI elimination!");
3343 }
3344
3345 if (!TmpSReg) {
3346 // Use frame register and restore it after.
3347 TmpSReg = FrameReg;
3348 FIOp->setReg(FrameReg);
3349 FIOp->setIsKill(false);
3350 }
3351
3352 if (NeedSaveSCC) {
3353 assert(!(Offset & 0x1) && "Flat scratch offset must be aligned!");
3354 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADDC_U32), TmpSReg)
3355 .addReg(FrameReg)
3356 .addImm(Offset);
3357 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_BITCMP1_B32))
3358 .addReg(TmpSReg)
3359 .addImm(0);
3360 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_BITSET0_B32), TmpSReg)
3361 .addImm(0)
3362 .addReg(TmpSReg);
3363 } else {
3364 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), TmpSReg)
3365 .addReg(FrameReg)
3366 .addImm(Offset);
3367 }
3368
3369 if (!UseSGPR)
3370 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
3371 .addReg(TmpSReg, RegState::Kill);
3372
3373 if (TmpSReg == FrameReg) {
3374 // Undo frame register modification.
3375 if (NeedSaveSCC &&
3376 !MI->registerDefIsDead(AMDGPU::SCC, /*TRI=*/nullptr)) {
3378 BuildMI(*MBB, std::next(MI), DL, TII->get(AMDGPU::S_ADDC_U32),
3379 TmpSReg)
3380 .addReg(FrameReg)
3381 .addImm(-Offset);
3382 I = BuildMI(*MBB, std::next(I), DL, TII->get(AMDGPU::S_BITCMP1_B32))
3383 .addReg(TmpSReg)
3384 .addImm(0);
3385 BuildMI(*MBB, std::next(I), DL, TII->get(AMDGPU::S_BITSET0_B32),
3386 TmpSReg)
3387 .addImm(0)
3388 .addReg(TmpSReg);
3389 } else {
3390 BuildMI(*MBB, std::next(MI), DL, TII->get(AMDGPU::S_ADD_I32),
3391 FrameReg)
3392 .addReg(FrameReg)
3393 .addImm(-Offset);
3394 }
3395 }
3396
3397 return false;
3398 }
3399
3400 bool IsMUBUF = TII->isMUBUF(*MI);
3401
3402 if (!IsMUBUF && !MFI->isBottomOfStack()) {
3403 // Convert to a swizzled stack address by scaling by the wave size.
3404 // In an entry function/kernel the offset is already swizzled.
3405 bool IsSALU = isSGPRClass(TII->getRegClass(MI->getDesc(), FIOperandNum));
3406 bool LiveSCC = RS->isRegUsed(AMDGPU::SCC) &&
3407 !MI->definesRegister(AMDGPU::SCC, /*TRI=*/nullptr);
3408 const TargetRegisterClass *RC = IsSALU && !LiveSCC
3409 ? &AMDGPU::SReg_32RegClass
3410 : &AMDGPU::VGPR_32RegClass;
3411 bool IsCopy = MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
3412 MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
3413 MI->getOpcode() == AMDGPU::S_MOV_B32;
3414
3415 int64_t Offset = FrameInfo.getObjectOffset(Index);
3416
3417 // Scaling FrameReg in place is the last resort when there is nothing to
3418 // scavenge. It has to be undone after MI, which is only possible while MI
3419 // does not use FrameReg for anything besides the frame index.
3420 bool CanUseFrameRegAsScratch = IsSALU && !LiveSCC && FrameReg &&
3421 !MI->readsRegister(FrameReg, this) &&
3422 !MI->modifiesRegister(FrameReg, this);
3423
3424 bool RestoreFrameReg = false;
3425 Register ResultReg;
3426 if (IsCopy) {
3427 ResultReg = MI->getOperand(0).getReg();
3428 } else {
3429 ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0,
3430 /*AllowSpill=*/false);
3431 if (!ResultReg) {
3432 if (CanUseFrameRegAsScratch) {
3433 // Spilling an SGPR here instead would flip EXEC with S_NOT, and
3434 // that clobbers the SCC MI may be defining for a later use.
3435 ResultReg = FrameReg;
3436 RestoreFrameReg = true;
3437 } else {
3438 ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0);
3439 }
3440 }
3441 }
3442
3443 // The carry-out lane of Add is unused, so it is safe to write with
3444 // S_MOV_B32 even into a VGPR.
3445 auto MaterializeCarryOutOffset = [&](MachineInstrBuilder &Add) {
3446 Register ConstOffsetReg =
3447 isWave32 ? Add.getReg(1)
3448 : Register(getSubReg(Add.getReg(1), AMDGPU::sub0));
3449 BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::S_MOV_B32), ConstOffsetReg)
3450 .addImm(Offset);
3451 return ConstOffsetReg;
3452 };
3453
3454 if (Offset == 0) {
3455 unsigned OpCode =
3456 IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
3457 Register TmpResultReg = ResultReg;
3458 if (IsSALU && LiveSCC) {
3459 TmpResultReg = RS->scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass,
3460 MI, false, 0);
3461 }
3462
3463 auto Shift = BuildMI(*MBB, MI, DL, TII->get(OpCode), TmpResultReg);
3464 if (OpCode == AMDGPU::V_LSHRREV_B32_e64)
3465 // For V_LSHRREV, the operands are reversed (the shift count goes
3466 // first).
3467 Shift.addImm(ST.getWavefrontSizeLog2()).addReg(FrameReg);
3468 else
3469 Shift.addReg(FrameReg).addImm(ST.getWavefrontSizeLog2());
3470 if (IsSALU && !LiveSCC)
3471 Shift.getInstr()->getOperand(3).setIsDead(); // Mark SCC as dead.
3472 if (IsSALU && LiveSCC) {
3473 Register NewDest;
3474 if (IsCopy) {
3475 assert(ResultReg.isPhysical());
3476 NewDest = ResultReg;
3477 } else {
3478 NewDest = RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
3479 Shift, false, 0);
3480 }
3481 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), NewDest)
3482 .addReg(TmpResultReg);
3483 ResultReg = NewDest;
3484 }
3485 } else {
3487 if (!IsSALU) {
3488 if ((MIB = TII->getAddNoCarry(*MBB, MI, DL, ResultReg, *RS)) !=
3489 nullptr) {
3490 // Reuse ResultReg in intermediate step.
3491 Register ScaledReg = ResultReg;
3492
3493 BuildMI(*MBB, *MIB, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3494 ScaledReg)
3495 .addImm(ST.getWavefrontSizeLog2())
3496 .addReg(FrameReg);
3497
3498 const bool IsVOP2 = MIB->getOpcode() == AMDGPU::V_ADD_U32_e32;
3499
3500 // TODO: Fold if use instruction is another add of a constant.
3501 if (IsVOP2 ||
3502 AMDGPU::isInlinableLiteral32(Offset, ST.hasInv2PiInlineImm())) {
3503 // FIXME: This can fail
3504 MIB.addImm(Offset);
3505 MIB.addReg(ScaledReg, RegState::Kill);
3506 if (!IsVOP2)
3507 MIB.addImm(0); // clamp bit
3508 } else {
3509 assert(MIB->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 &&
3510 "Need to reuse carry out register");
3511
3512 MIB.addReg(MaterializeCarryOutOffset(MIB), RegState::Kill);
3513 MIB.addReg(ScaledReg, RegState::Kill);
3514 MIB.addImm(0); // clamp bit
3515 }
3516 }
3517 }
3518 if (!MIB || IsSALU) {
3519 // We have to produce a carry out, and there isn't a free SGPR pair
3520 // for it. We can keep the whole computation on the SALU to avoid
3521 // clobbering an additional register at the cost of an extra mov.
3522
3523 // We may have 1 free scratch SGPR even though a carry out is
3524 // unavailable. Only one additional mov is needed.
3525 Register TmpScaledReg = IsCopy && IsSALU
3526 ? ResultReg
3527 : RS->scavengeRegisterBackwards(
3528 AMDGPU::SReg_32_XM0RegClass, MI,
3529 false, 0, /*AllowSpill=*/false);
3530 // A scalar result is already materialized in ResultReg, which holds
3531 // the scavenged register, or FrameReg itself if nothing was free.
3532 Register ScaledReg = TmpScaledReg;
3533 if (!ScaledReg.isValid())
3534 ScaledReg = IsSALU ? ResultReg : FrameReg;
3535 Register TmpResultReg = ScaledReg;
3536
3537 if (!LiveSCC) {
3538 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_LSHR_B32), TmpResultReg)
3539 .addReg(FrameReg)
3540 .addImm(ST.getWavefrontSizeLog2());
3541 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), TmpResultReg)
3542 .addReg(TmpResultReg, RegState::Kill)
3543 .addImm(Offset);
3544 } else {
3545 TmpResultReg = RS->scavengeRegisterBackwards(
3546 AMDGPU::VGPR_32RegClass, MI, false, 0, /*AllowSpill=*/true);
3547
3549 if ((Add = TII->getAddNoCarry(*MBB, MI, DL, TmpResultReg, *RS))) {
3550 BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3551 TmpResultReg)
3552 .addImm(ST.getWavefrontSizeLog2())
3553 .addReg(FrameReg);
3554 if (Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
3555 Add.addReg(MaterializeCarryOutOffset(Add), RegState::Kill)
3556 .addReg(TmpResultReg, RegState::Kill)
3557 .addImm(0);
3558 } else
3559 Add.addImm(Offset).addReg(TmpResultReg, RegState::Kill);
3560 } else {
3561 assert(Offset > 0 && isUInt<24>(2 * ST.getMaxWaveScratchSize()) &&
3562 "offset is unsafe for v_mad_u32_u24");
3563
3564 // We start with a frame pointer with a wave space value, and
3565 // an offset in lane-space. We are materializing a lane space
3566 // value. We can either do a right shift of the frame pointer
3567 // to get to lane space, or a left shift of the offset to get
3568 // to wavespace. We can right shift after the computation to
3569 // get back to the desired per-lane value. We are using the
3570 // mad_u32_u24 primarily as an add with no carry out clobber.
3571 bool IsInlinableLiteral =
3572 AMDGPU::isInlinableLiteral32(Offset, ST.hasInv2PiInlineImm());
3573 if (!IsInlinableLiteral) {
3574 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MOV_B32_e32),
3575 TmpResultReg)
3576 .addImm(Offset);
3577 }
3578
3579 Add = BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_MAD_U32_U24_e64),
3580 TmpResultReg);
3581
3582 if (!IsInlinableLiteral) {
3583 Add.addReg(TmpResultReg, RegState::Kill);
3584 } else {
3585 // We fold the offset into mad itself if its inlinable.
3586 Add.addImm(Offset);
3587 }
3588 Add.addImm(ST.getWavefrontSize()).addReg(FrameReg).addImm(0);
3589 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_LSHRREV_B32_e64),
3590 TmpResultReg)
3591 .addImm(ST.getWavefrontSizeLog2())
3592 .addReg(TmpResultReg);
3593 }
3594
3595 Register NewDest;
3596 if (IsCopy) {
3597 NewDest = ResultReg;
3598 } else {
3599 NewDest = RS->scavengeRegisterBackwards(
3600 AMDGPU::SReg_32_XM0RegClass, *Add, false, 0,
3601 /*AllowSpill=*/true);
3602 }
3603
3604 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
3605 NewDest)
3606 .addReg(TmpResultReg);
3607 ResultReg = NewDest;
3608 }
3609 // A scalar result still reads FrameReg at MI, so FrameReg is
3610 // restored after MI instead.
3611 if (!IsSALU) {
3612 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::COPY), ResultReg)
3613 .addReg(TmpResultReg, RegState::Kill);
3614 // If there were truly no free SGPRs, we need to undo everything.
3615 if (!TmpScaledReg.isValid()) {
3616 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), ScaledReg)
3617 .addReg(ScaledReg, RegState::Kill)
3618 .addImm(-Offset);
3619 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_LSHL_B32), ScaledReg)
3620 .addReg(FrameReg)
3621 .addImm(ST.getWavefrontSizeLog2());
3622 }
3623 }
3624 }
3625 }
3626
3627 if (RestoreFrameReg) {
3628 // Put FrameReg back now that MI has consumed the scaled address.
3629 // S_MUL_I32 undoes the scaling without writing SCC, which S_LSHL_B32
3630 // would. When MI leaves SCC live, fold the offset back with the carry
3631 // sequence that smuggles SCC through bit 0, which the scaling has just
3632 // cleared.
3633 MachineBasicBlock::iterator InsPt = std::next(MI);
3634 BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_MUL_I32), FrameReg)
3635 .addReg(FrameReg)
3636 .addImm(ST.getWavefrontSize());
3637
3638 if (Offset) {
3639 int64_t ScaledOffset = -Offset * ST.getWavefrontSize();
3640 bool SCCLiveAfterMI = MI->definesRegister(AMDGPU::SCC, this) &&
3641 !MI->registerDefIsDead(AMDGPU::SCC, this);
3642 if (!SCCLiveAfterMI) {
3643 BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_ADD_I32), FrameReg)
3644 .addReg(FrameReg)
3645 .addImm(ScaledOffset);
3646 } else {
3647 BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_ADDC_U32), FrameReg)
3648 .addReg(FrameReg)
3649 .addImm(ScaledOffset);
3650 BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_BITCMP1_B32))
3651 .addReg(FrameReg)
3652 .addImm(0);
3653 BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_BITSET0_B32), FrameReg)
3654 .addImm(0)
3655 .addReg(FrameReg);
3656 }
3657 }
3658 }
3659
3660 // Don't introduce an extra copy if we're just materializing in a mov.
3661 if (IsCopy) {
3662 MI->eraseFromParent();
3663 return true;
3664 }
3665 // FrameReg is restored after MI, so MI does not kill it.
3666 FIOp->ChangeToRegister(ResultReg, false, false, !RestoreFrameReg);
3667 return false;
3668 }
3669
3670 if (IsMUBUF) {
3671 // Disable offen so we don't need a 0 vgpr base.
3672 assert(
3673 static_cast<int>(FIOperandNum) ==
3674 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::vaddr));
3675
3676 auto &SOffset = *TII->getNamedOperand(*MI, AMDGPU::OpName::soffset);
3677 assert((SOffset.isImm() && SOffset.getImm() == 0));
3678
3679 if (FrameReg != AMDGPU::NoRegister)
3680 SOffset.ChangeToRegister(FrameReg, false);
3681
3682 int64_t Offset = FrameInfo.getObjectOffset(Index);
3683 int64_t OldImm =
3684 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm();
3685 int64_t NewOffset = OldImm + Offset;
3686
3687 if (TII->isLegalMUBUFImmOffset(NewOffset) &&
3688 buildMUBUFOffsetLoadStore(ST, FrameInfo, MI, Index, NewOffset)) {
3689 MI->eraseFromParent();
3690 return true;
3691 }
3692 }
3693
3694 // If the offset is simply too big, don't convert to a scratch wave offset
3695 // relative index.
3696
3698
3699 // Not isImmOperandLegal: a SALU user may already have a literal.
3700 if (!TII->isOperandLegal(*MI, FIOperandNum, FIOp)) {
3701 const TargetRegisterClass *OpRC =
3702 TII->getRegClass(MI->getDesc(), FIOperandNum);
3703 bool UseSGPR = OpRC && isSGPRClass(OpRC);
3704
3705 const TargetRegisterClass *RC =
3706 UseSGPR ? &AMDGPU::SReg_32_XM0RegClass : &AMDGPU::VGPR_32RegClass;
3707 Register TmpReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0);
3708 BuildMI(*MBB, MI, DL,
3709 TII->get(UseSGPR ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32),
3710 TmpReg)
3711 .addImm(Offset);
3712 FIOp->ChangeToRegister(TmpReg, false, false, true);
3713 }
3714
3715 return false;
3716}
3717
3721
3723 return getEncodingValue(Reg) & AMDGPU::HWEncoding::REG_IDX_MASK;
3724}
3725
3726static const TargetRegisterClass *
3728 if (BitWidth == 64)
3729 return &AMDGPU::VReg_64RegClass;
3730 if (BitWidth == 96)
3731 return &AMDGPU::VReg_96RegClass;
3732 if (BitWidth == 128)
3733 return &AMDGPU::VReg_128RegClass;
3734 if (BitWidth == 160)
3735 return &AMDGPU::VReg_160RegClass;
3736 if (BitWidth == 192)
3737 return &AMDGPU::VReg_192RegClass;
3738 if (BitWidth == 224)
3739 return &AMDGPU::VReg_224RegClass;
3740 if (BitWidth == 256)
3741 return &AMDGPU::VReg_256RegClass;
3742 if (BitWidth == 288)
3743 return &AMDGPU::VReg_288RegClass;
3744 if (BitWidth == 320)
3745 return &AMDGPU::VReg_320RegClass;
3746 if (BitWidth == 352)
3747 return &AMDGPU::VReg_352RegClass;
3748 if (BitWidth == 384)
3749 return &AMDGPU::VReg_384RegClass;
3750 if (BitWidth == 512)
3751 return &AMDGPU::VReg_512RegClass;
3752 if (BitWidth == 1024)
3753 return &AMDGPU::VReg_1024RegClass;
3754
3755 return nullptr;
3756}
3757
3758static const TargetRegisterClass *
3760 if (BitWidth == 64)
3761 return &AMDGPU::VReg_64_Align2RegClass;
3762 if (BitWidth == 96)
3763 return &AMDGPU::VReg_96_Align2RegClass;
3764 if (BitWidth == 128)
3765 return &AMDGPU::VReg_128_Align2RegClass;
3766 if (BitWidth == 160)
3767 return &AMDGPU::VReg_160_Align2RegClass;
3768 if (BitWidth == 192)
3769 return &AMDGPU::VReg_192_Align2RegClass;
3770 if (BitWidth == 224)
3771 return &AMDGPU::VReg_224_Align2RegClass;
3772 if (BitWidth == 256)
3773 return &AMDGPU::VReg_256_Align2RegClass;
3774 if (BitWidth == 288)
3775 return &AMDGPU::VReg_288_Align2RegClass;
3776 if (BitWidth == 320)
3777 return &AMDGPU::VReg_320_Align2RegClass;
3778 if (BitWidth == 352)
3779 return &AMDGPU::VReg_352_Align2RegClass;
3780 if (BitWidth == 384)
3781 return &AMDGPU::VReg_384_Align2RegClass;
3782 if (BitWidth == 512)
3783 return &AMDGPU::VReg_512_Align2RegClass;
3784 if (BitWidth == 1024)
3785 return &AMDGPU::VReg_1024_Align2RegClass;
3786
3787 return nullptr;
3788}
3789
3790const TargetRegisterClass *
3792 if (BitWidth == 1)
3793 return &AMDGPU::VReg_1RegClass;
3794 if (BitWidth == 16)
3795 return &AMDGPU::VGPR_16RegClass;
3796 if (BitWidth == 32)
3797 return &AMDGPU::VGPR_32RegClass;
3798 return ST.needsAlignedVGPRs() ? getAlignedVGPRClassForBitWidth(BitWidth)
3800}
3801
3802const TargetRegisterClass *
3804 if (BitWidth <= 32)
3805 return &AMDGPU::VGPR_32_Lo256RegClass;
3806 if (BitWidth <= 64)
3807 return &AMDGPU::VReg_64_Lo256_Align2RegClass;
3808 if (BitWidth <= 96)
3809 return &AMDGPU::VReg_96_Lo256_Align2RegClass;
3810 if (BitWidth <= 128)
3811 return &AMDGPU::VReg_128_Lo256_Align2RegClass;
3812 if (BitWidth <= 160)
3813 return &AMDGPU::VReg_160_Lo256_Align2RegClass;
3814 if (BitWidth <= 192)
3815 return &AMDGPU::VReg_192_Lo256_Align2RegClass;
3816 if (BitWidth <= 224)
3817 return &AMDGPU::VReg_224_Lo256_Align2RegClass;
3818 if (BitWidth <= 256)
3819 return &AMDGPU::VReg_256_Lo256_Align2RegClass;
3820 if (BitWidth <= 288)
3821 return &AMDGPU::VReg_288_Lo256_Align2RegClass;
3822 if (BitWidth <= 320)
3823 return &AMDGPU::VReg_320_Lo256_Align2RegClass;
3824 if (BitWidth <= 352)
3825 return &AMDGPU::VReg_352_Lo256_Align2RegClass;
3826 if (BitWidth <= 384)
3827 return &AMDGPU::VReg_384_Lo256_Align2RegClass;
3828 if (BitWidth <= 512)
3829 return &AMDGPU::VReg_512_Lo256_Align2RegClass;
3830 if (BitWidth <= 1024)
3831 return &AMDGPU::VReg_1024_Lo256_Align2RegClass;
3832
3833 return nullptr;
3834}
3835
3836static const TargetRegisterClass *
3838 if (BitWidth == 64)
3839 return &AMDGPU::AReg_64RegClass;
3840 if (BitWidth == 96)
3841 return &AMDGPU::AReg_96RegClass;
3842 if (BitWidth == 128)
3843 return &AMDGPU::AReg_128RegClass;
3844 if (BitWidth == 160)
3845 return &AMDGPU::AReg_160RegClass;
3846 if (BitWidth == 192)
3847 return &AMDGPU::AReg_192RegClass;
3848 if (BitWidth == 224)
3849 return &AMDGPU::AReg_224RegClass;
3850 if (BitWidth == 256)
3851 return &AMDGPU::AReg_256RegClass;
3852 if (BitWidth == 288)
3853 return &AMDGPU::AReg_288RegClass;
3854 if (BitWidth == 320)
3855 return &AMDGPU::AReg_320RegClass;
3856 if (BitWidth == 352)
3857 return &AMDGPU::AReg_352RegClass;
3858 if (BitWidth == 384)
3859 return &AMDGPU::AReg_384RegClass;
3860 if (BitWidth == 512)
3861 return &AMDGPU::AReg_512RegClass;
3862 if (BitWidth == 1024)
3863 return &AMDGPU::AReg_1024RegClass;
3864
3865 return nullptr;
3866}
3867
3868static const TargetRegisterClass *
3870 if (BitWidth == 64)
3871 return &AMDGPU::AReg_64_Align2RegClass;
3872 if (BitWidth == 96)
3873 return &AMDGPU::AReg_96_Align2RegClass;
3874 if (BitWidth == 128)
3875 return &AMDGPU::AReg_128_Align2RegClass;
3876 if (BitWidth == 160)
3877 return &AMDGPU::AReg_160_Align2RegClass;
3878 if (BitWidth == 192)
3879 return &AMDGPU::AReg_192_Align2RegClass;
3880 if (BitWidth == 224)
3881 return &AMDGPU::AReg_224_Align2RegClass;
3882 if (BitWidth == 256)
3883 return &AMDGPU::AReg_256_Align2RegClass;
3884 if (BitWidth == 288)
3885 return &AMDGPU::AReg_288_Align2RegClass;
3886 if (BitWidth == 320)
3887 return &AMDGPU::AReg_320_Align2RegClass;
3888 if (BitWidth == 352)
3889 return &AMDGPU::AReg_352_Align2RegClass;
3890 if (BitWidth == 384)
3891 return &AMDGPU::AReg_384_Align2RegClass;
3892 if (BitWidth == 512)
3893 return &AMDGPU::AReg_512_Align2RegClass;
3894 if (BitWidth == 1024)
3895 return &AMDGPU::AReg_1024_Align2RegClass;
3896
3897 return nullptr;
3898}
3899
3900const TargetRegisterClass *
3902 if (BitWidth == 16)
3903 return &AMDGPU::AGPR_LO16RegClass;
3904 if (BitWidth == 32)
3905 return &AMDGPU::AGPR_32RegClass;
3906 return ST.needsAlignedVGPRs() ? getAlignedAGPRClassForBitWidth(BitWidth)
3908}
3909
3910static const TargetRegisterClass *
3912 if (BitWidth == 64)
3913 return &AMDGPU::AV_64RegClass;
3914 if (BitWidth == 96)
3915 return &AMDGPU::AV_96RegClass;
3916 if (BitWidth == 128)
3917 return &AMDGPU::AV_128RegClass;
3918 if (BitWidth == 160)
3919 return &AMDGPU::AV_160RegClass;
3920 if (BitWidth == 192)
3921 return &AMDGPU::AV_192RegClass;
3922 if (BitWidth == 224)
3923 return &AMDGPU::AV_224RegClass;
3924 if (BitWidth == 256)
3925 return &AMDGPU::AV_256RegClass;
3926 if (BitWidth == 288)
3927 return &AMDGPU::AV_288RegClass;
3928 if (BitWidth == 320)
3929 return &AMDGPU::AV_320RegClass;
3930 if (BitWidth == 352)
3931 return &AMDGPU::AV_352RegClass;
3932 if (BitWidth == 384)
3933 return &AMDGPU::AV_384RegClass;
3934 if (BitWidth == 512)
3935 return &AMDGPU::AV_512RegClass;
3936 if (BitWidth == 1024)
3937 return &AMDGPU::AV_1024RegClass;
3938
3939 return nullptr;
3940}
3941
3942static const TargetRegisterClass *
3944 if (BitWidth == 64)
3945 return &AMDGPU::AV_64_Align2RegClass;
3946 if (BitWidth == 96)
3947 return &AMDGPU::AV_96_Align2RegClass;
3948 if (BitWidth == 128)
3949 return &AMDGPU::AV_128_Align2RegClass;
3950 if (BitWidth == 160)
3951 return &AMDGPU::AV_160_Align2RegClass;
3952 if (BitWidth == 192)
3953 return &AMDGPU::AV_192_Align2RegClass;
3954 if (BitWidth == 224)
3955 return &AMDGPU::AV_224_Align2RegClass;
3956 if (BitWidth == 256)
3957 return &AMDGPU::AV_256_Align2RegClass;
3958 if (BitWidth == 288)
3959 return &AMDGPU::AV_288_Align2RegClass;
3960 if (BitWidth == 320)
3961 return &AMDGPU::AV_320_Align2RegClass;
3962 if (BitWidth == 352)
3963 return &AMDGPU::AV_352_Align2RegClass;
3964 if (BitWidth == 384)
3965 return &AMDGPU::AV_384_Align2RegClass;
3966 if (BitWidth == 512)
3967 return &AMDGPU::AV_512_Align2RegClass;
3968 if (BitWidth == 1024)
3969 return &AMDGPU::AV_1024_Align2RegClass;
3970
3971 return nullptr;
3972}
3973
3974const TargetRegisterClass *
3976 if (BitWidth == 32)
3977 return &AMDGPU::AV_32RegClass;
3978 return ST.needsAlignedVGPRs()
3981}
3982
3983const TargetRegisterClass *
3985 // TODO: In principle this should use AV classes for gfx908 too. This is
3986 // limited to 90a+ to avoid regressing special case copy optimizations which
3987 // need new handling. The core issue is that it's not possible to directly
3988 // copy between AGPRs on gfx908, and the current optimizations around that
3989 // expect to see copies to VGPR.
3990 return ST.hasGFX90AInsts() ? getVectorSuperClassForBitWidth(BitWidth)
3992}
3993
3994const TargetRegisterClass *
3996 if (BitWidth == 16 || BitWidth == 32)
3997 return &AMDGPU::SReg_32RegClass;
3998 if (BitWidth == 64)
3999 return &AMDGPU::SReg_64RegClass;
4000 if (BitWidth == 96)
4001 return &AMDGPU::SGPR_96RegClass;
4002 if (BitWidth == 128)
4003 return &AMDGPU::SGPR_128RegClass;
4004 if (BitWidth == 160)
4005 return &AMDGPU::SGPR_160RegClass;
4006 if (BitWidth == 192)
4007 return &AMDGPU::SGPR_192RegClass;
4008 if (BitWidth == 224)
4009 return &AMDGPU::SGPR_224RegClass;
4010 if (BitWidth == 256)
4011 return &AMDGPU::SGPR_256RegClass;
4012 if (BitWidth == 288)
4013 return &AMDGPU::SGPR_288RegClass;
4014 if (BitWidth == 320)
4015 return &AMDGPU::SGPR_320RegClass;
4016 if (BitWidth == 352)
4017 return &AMDGPU::SGPR_352RegClass;
4018 if (BitWidth == 384)
4019 return &AMDGPU::SGPR_384RegClass;
4020 if (BitWidth == 512)
4021 return &AMDGPU::SGPR_512RegClass;
4022 if (BitWidth == 1024)
4023 return &AMDGPU::SGPR_1024RegClass;
4024
4025 return nullptr;
4026}
4027
4029 Register Reg) const {
4030 const TargetRegisterClass *RC;
4031 if (Reg.isVirtual())
4032 RC = MRI.getRegClass(Reg);
4033 else
4034 RC = getPhysRegBaseClass(Reg);
4035 return RC && isSGPRClass(RC);
4036}
4037
4038const TargetRegisterClass *
4040 unsigned Size = getRegSizeInBits(*SRC);
4041
4042 switch (SRC->getID()) {
4043 default:
4044 break;
4045 case AMDGPU::VS_16_Lo128RegClassID:
4046 return getAllocatableClass(&AMDGPU::VGPR_16_Lo128RegClass);
4047 case AMDGPU::VS_32_Lo128RegClassID:
4048 return getAllocatableClass(&AMDGPU::VGPR_32_Lo128RegClass);
4049 case AMDGPU::VS_32_Lo256RegClassID:
4050 case AMDGPU::VS_64_Lo256RegClassID:
4051 return getAllocatableClass(getAlignedLo256VGPRClassForBitWidth(Size));
4052 }
4053
4054 const TargetRegisterClass *VRC =
4055 getAllocatableClass(getVGPRClassForBitWidth(Size));
4056 assert(VRC && "Invalid register class size");
4057 return VRC;
4058}
4059
4060const TargetRegisterClass *
4062 unsigned Size = getRegSizeInBits(*SRC);
4064 assert(ARC && "Invalid register class size");
4065 return ARC;
4066}
4067
4068const TargetRegisterClass *
4070 unsigned Size = getRegSizeInBits(*SRC);
4072 assert(ARC && "Invalid register class size");
4073 return ARC;
4074}
4075
4076const TargetRegisterClass *
4078 unsigned Size = getRegSizeInBits(*VRC);
4079 if (Size == 32)
4080 return &AMDGPU::SGPR_32RegClass;
4082 assert(SRC && "Invalid register class size");
4083 return SRC;
4084}
4085
4086const TargetRegisterClass *
4088 const TargetRegisterClass *SubRC,
4089 unsigned SubIdx) const {
4090 // Ensure this subregister index is aligned in the super register.
4091 const TargetRegisterClass *MatchRC =
4092 getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
4093 return MatchRC && MatchRC->hasSubClassEq(SuperRC) ? MatchRC : nullptr;
4094}
4095
4096bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const {
4099 return !ST.hasMFMAInlineLiteralBug();
4100
4101 return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
4102 OpType <= AMDGPU::OPERAND_SRC_LAST;
4103}
4104
4105bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const {
4106 // TODO: 64-bit operands have extending behavior from 32-bit literal.
4107 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
4109}
4110
4111/// Returns a lowest register that is not used at any point in the function.
4112/// If all registers are used, then this function will return
4113/// AMDGPU::NoRegister. If \p ReserveHighestRegister = true, then return
4114/// highest unused register.
4116 const MachineRegisterInfo &MRI, const TargetRegisterClass *RC,
4117 const MachineFunction &MF, bool ReserveHighestRegister) const {
4118 // Never offer VCC as an unused register.
4119 auto isVCC = [](MCRegister Reg) {
4120 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::VCC_HI;
4121 };
4122
4123 if (ReserveHighestRegister) {
4124 for (MCRegister Reg : reverse(*RC))
4125 if (MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4126 return Reg;
4127 } else {
4128 for (MCRegister Reg : *RC)
4129 if (MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) && !isVCC(Reg))
4130 return Reg;
4131 }
4132 return MCRegister();
4133}
4134
4136 const RegisterBankInfo &RBI,
4137 Register Reg) const {
4138 auto *RB = RBI.getRegBank(Reg, MRI, *this);
4139 if (!RB)
4140 return false;
4141
4142 return !RBI.isDivergentRegBank(RB);
4143}
4144
4146 unsigned EltSize) const {
4147 const unsigned RegBitWidth = AMDGPU::getRegBitWidth(*RC);
4148 assert(RegBitWidth >= 32 && RegBitWidth <= 1024 && EltSize >= 2);
4149
4150 const unsigned RegHalves = RegBitWidth / 16;
4151 const unsigned EltHalves = EltSize / 2;
4152 assert(RegSplitParts.size() + 1 >= EltHalves);
4153
4154 const std::vector<int16_t> &Parts = RegSplitParts[EltHalves - 1];
4155 const unsigned NumParts = RegHalves / EltHalves;
4156
4157 return ArrayRef(Parts.data(), NumParts);
4158}
4159
4162 Register Reg) const {
4163 return Reg.isVirtual() ? MRI.getRegClass(Reg) : getPhysRegBaseClass(Reg);
4164}
4165
4166const TargetRegisterClass *
4168 const MachineOperand &MO) const {
4169 const TargetRegisterClass *SrcRC = getRegClassForReg(MRI, MO.getReg());
4170 return getSubRegisterClass(SrcRC, MO.getSubReg());
4171}
4172
4174 Register Reg) const {
4175 const TargetRegisterClass *RC = getRegClassForReg(MRI, Reg);
4176 // Registers without classes are unaddressable, SGPR-like registers.
4177 return RC && isVGPRClass(RC);
4178}
4179
4181 Register Reg) const {
4182 const TargetRegisterClass *RC = getRegClassForReg(MRI, Reg);
4183
4184 // Registers without classes are unaddressable, SGPR-like registers.
4185 return RC && isAGPRClass(RC);
4186}
4187
4189 MachineFunction &MF) const {
4190 unsigned MinOcc = ST.getOccupancyWithWorkGroupSizes(MF).first;
4191 switch (RC->getID()) {
4192 default:
4193 return AMDGPUGenRegisterInfo::getRegPressureLimit(RC, MF);
4194 case AMDGPU::VGPR_32RegClassID:
4195 return std::min(
4196 ST.getMaxNumVGPRs(
4197 MinOcc,
4199 ST.getMaxNumVGPRs(MF));
4200 case AMDGPU::SGPR_32RegClassID:
4201 case AMDGPU::SGPR_LO16RegClassID:
4202 return std::min(ST.getMaxNumSGPRs(MinOcc, true), ST.getMaxNumSGPRs(MF));
4203 }
4204}
4205
4207 unsigned Idx) const {
4208 switch (static_cast<AMDGPU::RegisterPressureSets>(Idx)) {
4209 case AMDGPU::RegisterPressureSets::VGPR_32:
4210 case AMDGPU::RegisterPressureSets::AGPR_32:
4211 return getRegPressureLimit(&AMDGPU::VGPR_32RegClass,
4212 const_cast<MachineFunction &>(MF));
4213 case AMDGPU::RegisterPressureSets::SReg_32:
4214 return getRegPressureLimit(&AMDGPU::SGPR_32RegClass,
4215 const_cast<MachineFunction &>(MF));
4216 }
4217
4218 llvm_unreachable("Unexpected register pressure set!");
4219}
4220
4221const int *SIRegisterInfo::getRegUnitPressureSets(MCRegUnit RegUnit) const {
4222 static const int Empty[] = { -1 };
4223
4224 if (RegPressureIgnoredUnits[static_cast<unsigned>(RegUnit)])
4225 return Empty;
4226
4227 return AMDGPUGenRegisterInfo::getRegUnitPressureSets(RegUnit);
4228}
4229
4231 ArrayRef<MCPhysReg> Order,
4233 const MachineFunction &MF,
4234 const VirtRegMap *VRM,
4235 const LiveRegMatrix *Matrix) const {
4236
4237 const MachineRegisterInfo &MRI = MF.getRegInfo();
4238 const SIRegisterInfo *TRI = ST.getRegisterInfo();
4239
4240 std::pair<unsigned, Register> Hint = MRI.getRegAllocationHint(VirtReg);
4241
4242 switch (Hint.first) {
4243 case AMDGPURI::Size32: {
4244 Register Paired = Hint.second;
4245 assert(Paired);
4246 Register PairedPhys;
4247 if (Paired.isPhysical()) {
4248 PairedPhys =
4249 getMatchingSuperReg(Paired, AMDGPU::lo16, &AMDGPU::VGPR_32RegClass);
4250 } else if (VRM && VRM->hasPhys(Paired)) {
4251 PairedPhys = getMatchingSuperReg(VRM->getPhys(Paired), AMDGPU::lo16,
4252 &AMDGPU::VGPR_32RegClass);
4253 }
4254
4255 // Prefer the paired physreg.
4256 if (PairedPhys)
4257 // isLo(Paired) is implicitly true here from the API of
4258 // getMatchingSuperReg.
4259 Hints.push_back(PairedPhys);
4260 return false;
4261 }
4262 case AMDGPURI::Size16: {
4263 Register Paired = Hint.second;
4264 assert(Paired);
4265 Register PairedPhys;
4266 if (Paired.isPhysical()) {
4267 PairedPhys = TRI->getSubReg(Paired, AMDGPU::lo16);
4268 } else if (VRM && VRM->hasPhys(Paired)) {
4269 PairedPhys = TRI->getSubReg(VRM->getPhys(Paired), AMDGPU::lo16);
4270 }
4271
4272 // First prefer the paired physreg.
4273 if (PairedPhys)
4274 Hints.push_back(PairedPhys);
4275 else {
4276 // Add all the lo16 physregs.
4277 // When the Paired operand has not yet been assigned a physreg it is
4278 // better to try putting VirtReg in a lo16 register, because possibly
4279 // later Paired can be assigned to the overlapping register and the COPY
4280 // can be eliminated.
4281 for (MCPhysReg PhysReg : Order) {
4282 if (PhysReg == PairedPhys || AMDGPU::isHi16Reg(PhysReg, *this))
4283 continue;
4284 if (AMDGPU::VGPR_16RegClass.contains(PhysReg) &&
4285 !MRI.isReserved(PhysReg))
4286 Hints.push_back(PhysReg);
4287 }
4288 }
4289 return false;
4290 }
4291 default:
4292 return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
4293 VRM);
4294 }
4295}
4296
4298 // Not a callee saved register.
4299 return AMDGPU::SGPR30_SGPR31;
4300}
4301
4302const TargetRegisterClass *
4304 const RegisterBank &RB) const {
4305 switch (RB.getID()) {
4306 case AMDGPU::VGPRRegBankID:
4308 std::max(ST.useRealTrue16Insts() ? 16u : 32u, Size));
4309 case AMDGPU::VCCRegBankID:
4310 assert(Size == 1);
4311 return getWaveMaskRegClass();
4312 case AMDGPU::SGPRRegBankID:
4313 return getSGPRClassForBitWidth(std::max(32u, Size));
4314 case AMDGPU::AGPRRegBankID:
4315 return getAGPRClassForBitWidth(std::max(32u, Size));
4316 default:
4317 llvm_unreachable("unknown register bank");
4318 }
4319}
4320
4322 Register Reg, const MachineRegisterInfo &MRI) const {
4323 const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg);
4324 if (const RegisterBank *RB = dyn_cast<const RegisterBank *>(RCOrRB))
4325 return getRegClassForTypeOnBank(MRI.getType(Reg), *RB);
4326
4327 if (const auto *RC = dyn_cast<const TargetRegisterClass *>(RCOrRB))
4328 return getAllocatableClass(RC);
4329
4330 return nullptr;
4331}
4332
4334 return isWave32 ? AMDGPU::VCC_LO : AMDGPU::VCC;
4335}
4336
4338 return isWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
4339}
4340
4342 // VGPR tuples have an alignment requirement on gfx90a variants.
4343 return ST.needsAlignedVGPRs() ? &AMDGPU::VReg_64_Align2RegClass
4344 : &AMDGPU::VReg_64RegClass;
4345}
4346
4347// Find reaching register definition
4351 LiveIntervals *LIS) const {
4352 auto &MDT = LIS->getDomTree();
4353 SlotIndex UseIdx = LIS->getInstructionIndex(Use);
4354 SlotIndex DefIdx;
4355
4356 if (Reg.isVirtual()) {
4357 if (!LIS->hasInterval(Reg))
4358 return nullptr;
4359 LiveInterval &LI = LIS->getInterval(Reg);
4360 LaneBitmask SubLanes = SubReg ? getSubRegIndexLaneMask(SubReg)
4361 : MRI.getMaxLaneMaskForVReg(Reg);
4362 VNInfo *V = nullptr;
4363 if (LI.hasSubRanges()) {
4364 for (auto &S : LI.subranges()) {
4365 if ((S.LaneMask & SubLanes) == SubLanes) {
4366 V = S.getVNInfoAt(UseIdx);
4367 break;
4368 }
4369 }
4370 } else {
4371 V = LI.getVNInfoAt(UseIdx);
4372 }
4373 if (!V)
4374 return nullptr;
4375 DefIdx = V->def;
4376 } else {
4377 // Find last def.
4378 for (MCRegUnit Unit : regunits(Reg.asMCReg())) {
4379 LiveRange &LR = LIS->getRegUnit(Unit);
4380 if (VNInfo *V = LR.getVNInfoAt(UseIdx)) {
4381 if (!DefIdx.isValid() ||
4382 MDT.dominates(LIS->getInstructionFromIndex(DefIdx),
4383 LIS->getInstructionFromIndex(V->def)))
4384 DefIdx = V->def;
4385 } else {
4386 return nullptr;
4387 }
4388 }
4389 }
4390
4391 MachineInstr *Def = LIS->getInstructionFromIndex(DefIdx);
4392
4393 if (!Def || !MDT.dominates(Def, &Use))
4394 return nullptr;
4395
4396 assert(Def->modifiesRegister(Reg, this));
4397
4398 return Def;
4399}
4400
4402 assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
4403
4404 for (const TargetRegisterClass *RC :
4405 {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
4406 &AMDGPU::AGPR_32RegClass}) {
4407 if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
4408 return Super;
4409 }
4410 if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::hi16,
4411 &AMDGPU::VGPR_32RegClass)) {
4412 return Super;
4413 }
4414
4415 return AMDGPU::NoRegister;
4416}
4417
4419 if (!ST.needsAlignedVGPRs())
4420 return true;
4421
4422 if (isVGPRClass(&RC))
4423 return RC.hasSuperClassEq(getVGPRClassForBitWidth(getRegSizeInBits(RC)));
4424 if (isAGPRClass(&RC))
4425 return RC.hasSuperClassEq(getAGPRClassForBitWidth(getRegSizeInBits(RC)));
4426 if (isVectorSuperClass(&RC))
4427 return RC.hasSuperClassEq(
4428 getVectorSuperClassForBitWidth(getRegSizeInBits(RC)));
4429
4430 assert(&RC != &AMDGPU::VS_64RegClass);
4431
4432 return true;
4433}
4434
4437 return ArrayRef(AMDGPU::SGPR_128RegClass.begin(), ST.getMaxNumSGPRs(MF) / 4);
4438}
4439
4442 return ArrayRef(AMDGPU::SGPR_64RegClass.begin(), ST.getMaxNumSGPRs(MF) / 2);
4443}
4444
4447 return ArrayRef(AMDGPU::SGPR_32RegClass.begin(), ST.getMaxNumSGPRs(MF));
4448}
4449
4450unsigned
4452 unsigned SubReg) const {
4453 switch (RC->TSFlags & SIRCFlags::RegKindMask) {
4454 case SIRCFlags::HasSGPR:
4455 return std::min(128u, getSubRegIdxSize(SubReg));
4456 case SIRCFlags::HasAGPR:
4457 case SIRCFlags::HasVGPR:
4459 return std::min(32u, getSubRegIdxSize(SubReg));
4460 default:
4461 break;
4462 }
4463 return 0;
4464}
4465
4467 const TargetRegisterClass &RC,
4468 bool IncludeCalls) const {
4469 unsigned NumArchVGPRs = ST.getAddressableNumArchVGPRs();
4471 (RC.getID() == AMDGPU::VGPR_32RegClassID)
4472 ? RC.getRegisters().take_front(NumArchVGPRs)
4473 : RC.getRegisters();
4474 for (MCPhysReg Reg : reverse(Registers)) {
4475 if (Reg != AMDGPU::VCC_LO && Reg != AMDGPU::VCC_HI &&
4476 MRI.isPhysRegUsed(Reg, /*SkipRegMaskTest=*/!IncludeCalls))
4477 return getHWRegIndex(Reg) + 1;
4478 }
4479 return 0;
4480}
4481
4484 const MachineFunction &MF) const {
4486 const SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
4487 if (FuncInfo->checkFlag(Reg, AMDGPU::VirtRegFlag::WWM_REG))
4488 RegFlags.push_back("WWM_REG");
4489 return RegFlags;
4490}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
AMDGPU Reserve WWM Registers
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.
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 bool wrapsAround32(int64_t LHS, int64_t RHS)
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 foldingOffsetChangesCarry(const MachineOperand &OtherOp, int64_t Offset, Register FrameReg)
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
Value * RHS
Value * LHS
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:273
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
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 * 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:478
@ OPERAND_REG_INLINE_AC_FIRST
Definition SIDefines.h:484
@ OPERAND_REG_INLINE_AC_LAST
Definition SIDefines.h:485
@ OPERAND_REG_IMM_LAST
Definition SIDefines.h:479
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:1685
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:408
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