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