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