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