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