LLVM: lib/Target/AMDGPU/SIMachineFunctionInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

24#include

25#include

26#include

27

29

30using namespace llvm;

31

35}

36

40 UserSGPRInfo(F, *STI), WorkGroupIDX(false), WorkGroupIDY(false),

41 WorkGroupIDZ(false), WorkGroupInfo(false), LDSKernelId(false),

42 PrivateSegmentWaveByteOffset(false), WorkItemIDX(false),

43 WorkItemIDY(false), WorkItemIDZ(false), ImplicitArgPtr(false),

44 GITPtrHigh(0xffffffff), HighBitsOf32BitAddress(0) {

46 FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);

47 WavesPerEU = ST.getWavesPerEU(F);

48 MaxNumWorkGroups = ST.getMaxNumWorkGroups(F);

50

51 Occupancy = ST.computeOccupancy(F, getLDSSize());

53

54 VRegFlags.reserve(1024);

55

58

59 if (IsKernel) {

60 WorkGroupIDX = true;

61 WorkItemIDX = true;

64 }

65

66 MayNeedAGPRs = ST.hasMAIInsts();

67

69

70

71

72

73 StackPtrOffsetReg = AMDGPU::SGPR32;

74

75 ScratchRSrcReg = AMDGPU::SGPR48_SGPR49_SGPR50_SGPR51;

76

77 ArgInfo.PrivateSegmentBuffer =

79

80 ImplicitArgPtr = false;

84

85 FrameOffsetReg = AMDGPU::SGPR33;

86 StackPtrOffsetReg = AMDGPU::SGPR32;

87

88 if (!ST.enableFlatScratch()) {

89

90

91 ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;

92

93 ArgInfo.PrivateSegmentBuffer =

95 }

96

97 if (F.hasFnAttribute("amdgpu-no-implicitarg-ptr"))

98 ImplicitArgPtr = true;

99 } else {

100 ImplicitArgPtr = false;

101 MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),

103

104 if (ST.hasGFX90AInsts() &&

105 ST.getMaxNumVGPRs(F) <= AMDGPU::VGPR_32RegClass.getNumRegs() &&

107 MayNeedAGPRs = false;

108 }

109

112 ST.hasArchitectedSGPRs())) {

113 if (IsKernel || F.hasFnAttribute("amdgpu-no-workgroup-id-x"))

114 WorkGroupIDX = true;

115

116 if (F.hasFnAttribute("amdgpu-no-workgroup-id-y"))

117 WorkGroupIDY = true;

118

119 if (F.hasFnAttribute("amdgpu-no-workgroup-id-z"))

120 WorkGroupIDZ = true;

121 }

122

124 if (IsKernel || F.hasFnAttribute("amdgpu-no-workitem-id-x"))

125 WorkItemIDX = true;

126

127 if (F.hasFnAttribute("amdgpu-no-workitem-id-y") &&

128 ST.getMaxWorkitemID(F, 1) != 0)

129 WorkItemIDY = true;

130

131 if (F.hasFnAttribute("amdgpu-no-workitem-id-z") &&

132 ST.getMaxWorkitemID(F, 2) != 0)

133 WorkItemIDZ = true;

134

135 if (!IsKernel && F.hasFnAttribute("amdgpu-no-lds-kernel-id"))

136 LDSKernelId = true;

137 }

138

140

141

142 if (WorkItemIDZ)

143 WorkItemIDY = true;

144

145 if (!ST.flatScratchIsArchitected()) {

146 PrivateSegmentWaveByteOffset = true;

147

148

151 ArgInfo.PrivateSegmentWaveByteOffset =

153 }

154 }

155

156 Attribute A = F.getFnAttribute("amdgpu-git-ptr-high");

160

161 A = F.getFnAttribute("amdgpu-32bit-address-high-bits");

162 S = A.getValueAsString();

165

166 MaxMemoryClusterDWords = F.getFnAttributeAsParsedInteger(

168

169

170

171

172 if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {

173 VGPRForAGPRCopy =

174 AMDGPU::VGPR_32RegClass.getRegister(ST.getMaxNumVGPRs(F) - 1);

175 }

176}

177

181 const {

183}

184

190}

191

194 ArgInfo.PrivateSegmentBuffer =

196 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SGPR_128RegClass));

197 NumUserSGPRs += 4;

198 return ArgInfo.PrivateSegmentBuffer.getRegister();

199}

200

203 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

204 NumUserSGPRs += 2;

205 return ArgInfo.DispatchPtr.getRegister();

206}

207

210 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

211 NumUserSGPRs += 2;

212 return ArgInfo.QueuePtr.getRegister();

213}

214

216 ArgInfo.KernargSegmentPtr

218 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

219 NumUserSGPRs += 2;

220 return ArgInfo.KernargSegmentPtr.getRegister();

221}

222

225 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

226 NumUserSGPRs += 2;

227 return ArgInfo.DispatchID.getRegister();

228}

229

232 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

233 NumUserSGPRs += 2;

234 return ArgInfo.FlatScratchInit.getRegister();

235}

236

239 NumUserSGPRs += 1;

240 return ArgInfo.PrivateSegmentSize.getRegister();

241}

242

245 getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));

246 NumUserSGPRs += 2;

247 return ArgInfo.ImplicitBufferPtr.getRegister();

248}

249

252 NumUserSGPRs += 1;

253 return ArgInfo.LDSKernelId.getRegister();

254}

255

258 unsigned AllocSizeDWord, int KernArgIdx, int PaddingSGPRs) {

259 assert(ArgInfo.PreloadKernArgs.count(KernArgIdx) &&

260 "Preload kernel argument allocated twice.");

261 NumUserSGPRs += PaddingSGPRs;

262

263

264

265 if (ArgInfo.FirstKernArgPreloadReg)

266 ArgInfo.FirstKernArgPreloadReg = getNextUserSGPR();

268 TRI.getMatchingSuperReg(getNextUserSGPR(), AMDGPU::sub0, RC);

269 if (PreloadReg &&

270 (RC == &AMDGPU::SReg_32RegClass || RC == &AMDGPU::SReg_64RegClass)) {

271 ArgInfo.PreloadKernArgs[KernArgIdx].Regs.push_back(PreloadReg);

272 NumUserSGPRs += AllocSizeDWord;

273 } else {

274 for (unsigned I = 0; I < AllocSizeDWord; ++I) {

275 ArgInfo.PreloadKernArgs[KernArgIdx].Regs.push_back(getNextUserSGPR());

276 NumUserSGPRs++;

277 }

278 }

279

280

282 return &ArgInfo.PreloadKernArgs[KernArgIdx].Regs;

283}

284

287

289 return;

290

291

292

293

294

295

296

297

298

299

303 return;

304

305 WWMSpills.insert(std::make_pair(

307}

308

309

312 SmallVectorImpl<std::pair<Register, int>> &CalleeSavedRegs,

313 SmallVectorImpl<std::pair<Register, int>> &ScratchRegs) const {

315 for (auto &Reg : WWMSpills) {

317 CalleeSavedRegs.push_back(Reg);

318 else

319 ScratchRegs.push_back(Reg);

320 }

321}

322

325 for (unsigned I = 0; CSRegs[I]; ++I) {

326 if (CSRegs[I] == Reg)

327 return true;

328 }

329

330 return false;

331}

332

338 for (unsigned I = 0, E = WWMVGPRs.size(); I < E; ++I) {

341 TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);

342 if (!NewReg || NewReg >= Reg)

343 break;

344

345 MRI.replaceRegWith(Reg, NewReg);

346

347

348 WWMVGPRs[I] = NewReg;

349 WWMReservedRegs.remove(Reg);

350 WWMReservedRegs.insert(NewReg);

351 MRI.reserveReg(NewReg, TRI);

352

353

354

355 auto *RegItr = std::find(SpillPhysVGPRs.begin(), SpillPhysVGPRs.end(), Reg);

356 if (RegItr != SpillPhysVGPRs.end()) {

357 unsigned Idx = std::distance(SpillPhysVGPRs.begin(), RegItr);

358 SpillPhysVGPRs[Idx] = NewReg;

359 }

360

361

362

363 SavedVGPRs.reset(Reg);

364

368 }

369

370 Reg = NewReg;

371 }

372}

373

374bool SIMachineFunctionInfo::allocateVirtualVGPRForSGPRSpills(

378 if (!LaneIndex) {

379 LaneVGPR = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);

380 SpillVGPRs.push_back(LaneVGPR);

381 } else {

382 LaneVGPR = SpillVGPRs.back();

383 }

384

385 SGPRSpillsToVirtualVGPRLanes[FI].emplace_back(LaneVGPR, LaneIndex);

386 return true;

387}

388

389bool SIMachineFunctionInfo::allocatePhysicalVGPRForSGPRSpills(

390 MachineFunction &MF, int FI, unsigned LaneIndex, bool IsPrologEpilog) {

395 if (!LaneIndex) {

396

397

398

399 LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF,

400 !IsPrologEpilog);

401 if (LaneVGPR == AMDGPU::NoRegister) {

402

403

404 SGPRSpillsToPhysicalVGPRLanes.erase(FI);

405 return false;

406 }

407

408 if (IsPrologEpilog)

410

415 }

416 SpillPhysVGPRs.push_back(LaneVGPR);

417 } else {

418 LaneVGPR = SpillPhysVGPRs.back();

419 }

420

421 SGPRSpillsToPhysicalVGPRLanes[FI].emplace_back(LaneVGPR, LaneIndex);

422 return true;

423}

424

427 bool IsPrologEpilog) {

428 std::vectorSIRegisterInfo::SpilledReg &SpillLanes =

429 SpillToPhysVGPRLane ? SGPRSpillsToPhysicalVGPRLanes[FI]

430 : SGPRSpillsToVirtualVGPRLanes[FI];

431

432

433 if (!SpillLanes.empty())

434 return true;

435

438 unsigned WaveSize = ST.getWavefrontSize();

439

440 unsigned Size = FrameInfo.getObjectSize(FI);

441 unsigned NumLanes = Size / 4;

442

443 if (NumLanes > WaveSize)

444 return false;

445

446 assert(Size >= 4 && "invalid sgpr spill size");

447 assert(ST.getRegisterInfo()->spillSGPRToVGPR() &&

448 "not spilling SGPRs to VGPRs");

449

450 unsigned &NumSpillLanes = SpillToPhysVGPRLane ? NumPhysicalVGPRSpillLanes

451 : NumVirtualVGPRSpillLanes;

452

453 for (unsigned I = 0; I < NumLanes; ++I, ++NumSpillLanes) {

454 unsigned LaneIndex = (NumSpillLanes % WaveSize);

455

456 bool Allocated = SpillToPhysVGPRLane

457 ? allocatePhysicalVGPRForSGPRSpills(MF, FI, LaneIndex,

458 IsPrologEpilog)

459 : allocateVirtualVGPRForSGPRSpills(MF, FI, LaneIndex);

460 if (!Allocated) {

461 NumSpillLanes -= I;

462 return false;

463 }

464 }

465

466 return true;

467}

468

469

470

471

473 int FI,

474 bool isAGPRtoVGPR) {

478

480

481 auto &Spill = VGPRToAGPRSpills[FI];

482

483

484 if (!Spill.Lanes.empty())

485 return Spill.FullyAllocated;

486

488 unsigned NumLanes = Size / 4;

489 Spill.Lanes.resize(NumLanes, AMDGPU::NoRegister);

490

492 isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;

494

495 auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;

497 Spill.FullyAllocated = true;

498

499

500

502 OtherUsedRegs.resize(TRI->getNumRegs());

503

506 if (CSRMask)

508

509

510

512 OtherUsedRegs.set(Reg);

514 OtherUsedRegs.set(Reg);

515

517 for (int I = NumLanes - 1; I >= 0; --I) {

518 NextSpillReg = std::find_if(

519 NextSpillReg, Regs.end(), [&MRI, &OtherUsedRegs](MCPhysReg Reg) {

520 return MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) &&

521 !OtherUsedRegs[Reg];

522 });

523

524 if (NextSpillReg == Regs.end()) {

525 Spill.FullyAllocated = false;

526 break;

527 }

528

529 OtherUsedRegs.set(*NextSpillReg);

530 SpillRegs.push_back(*NextSpillReg);

531 MRI.reserveReg(*NextSpillReg, TRI);

532 Spill.Lanes[I] = *NextSpillReg++;

533 }

534

535 return Spill.FullyAllocated;

536}

537

540

541

542

543

544

545

548 SGPRSpillsToVirtualVGPRLanes.erase(R.first);

549 }

550

551

552

553 if (!ResetSGPRSpillStackIDs) {

556 SGPRSpillsToPhysicalVGPRLanes.erase(R.first);

557 }

558 }

559 bool HaveSGPRToMemory = false;

560

561 if (ResetSGPRSpillStackIDs) {

562

563

565 ++I) {

569 HaveSGPRToMemory = true;

570 }

571 }

572 }

573 }

574

575 for (auto &R : VGPRToAGPRSpills) {

576 if (R.second.IsDead)

578 }

579

580 return HaveSGPRToMemory;

581}

582

585 if (ScavengeFI)

586 return *ScavengeFI;

587

588 ScavengeFI =

590 TRI.getSpillAlign(AMDGPU::SGPR_32RegClass), false);

591 return *ScavengeFI;

592}

593

594MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {

595 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");

596 return AMDGPU::SGPR0 + NumUserSGPRs;

597}

598

599MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {

600 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;

601}

602

603void SIMachineFunctionInfo::MRI_NoteNewVirtualRegister(Register Reg) {

604 VRegFlags.grow(Reg);

605}

606

607void SIMachineFunctionInfo::MRI_NoteCloneVirtualRegister(Register NewReg,

609 VRegFlags.grow(NewReg);

610 VRegFlags[NewReg] = VRegFlags[SrcReg];

611}

612

616 if (!ST.isAmdPalOS())

618 Register GitPtrLo = AMDGPU::SGPR0;

619 if (ST.hasMergedShaders()) {

623

624

625 GitPtrLo = AMDGPU::SGPR8;

626 return GitPtrLo;

627 default:

628 return GitPtrLo;

629 }

630 }

631 return GitPtrLo;

632}

633

637 {

640 }

641 return Dest;

642}

643

644static std::optionalyaml::SIArgumentInfo

648

649 auto convertArg = [&](std::optionalyaml::SIArgument &A,

651 if (!Arg)

652 return false;

653

654

656 if (Arg.isRegister()) {

659 } else

661

662 if (Arg.isMasked())

663 SA.Mask = Arg.getMask();

664

665 A = SA;

666 return true;

667 };

668

669

670 bool Any = false;

684 ArgInfo.PrivateSegmentWaveByteOffset);

690

692 return AI;

693

694 return std::nullopt;

695}

696

700 : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),

701 MaxKernArgAlign(MFI.getMaxKernArgAlign()), LDSSize(MFI.getLDSSize()),

702 GDSSize(MFI.getGDSSize()), DynLDSAlign(MFI.getDynLDSAlign()),

703 IsEntryFunction(MFI.isEntryFunction()),

704 NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),

705 MemoryBound(MFI.isMemoryBound()), WaveLimiter(MFI.needsWaveLimiter()),

706 HasSpilledSGPRs(MFI.hasSpilledSGPRs()),

707 HasSpilledVGPRs(MFI.hasSpilledVGPRs()),

708 HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),

709 Occupancy(MFI.getOccupancy()),

710 ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)),

711 FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)),

712 StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)),

713 BytesInStackArgArea(MFI.getBytesInStackArgArea()),

714 ReturnsVoid(MFI.returnsVoid()),

716 PSInputAddr(MFI.getPSInputAddr()), PSInputEnable(MFI.getPSInputEnable()),

717 MaxMemoryClusterDWords(MFI.getMaxMemoryClusterDWords()),

718 Mode(MFI.getMode()), HasInitWholeWave(MFI.hasInitWholeWave()) {

721

724

729

732

734 if (SFI)

736}

737

740}

741

763

766 if (!FIOrErr) {

767

770

773 "", {}, {});

774 SourceRange = YamlMFI.ScavengeFI->SourceRange;

775 return true;

776 }

778 } else {

780 }

781 return false;

782}

783

785 return F.hasFnAttribute("amdgpu-no-agpr");

786}

787

789 if (UsesAGPRs)

790 return *UsesAGPRs;

791

792 if (!mayNeedAGPRs()) {

793 UsesAGPRs = false;

794 return false;

795 }

796

799 UsesAGPRs = true;

800 return true;

801 }

802

804

805 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {

809 UsesAGPRs = true;

810 return true;

811 }

812 if (!RC && MRI.use_empty(Reg) && MRI.getType(Reg).isValid()) {

813

814 return true;

815 }

816 }

817

818 for (MCRegister Reg : AMDGPU::AGPR_32RegClass) {

819 if (MRI.isPhysRegUsed(Reg)) {

820 UsesAGPRs = true;

821 return true;

822 }

823 }

824

825 UsesAGPRs = false;

826 return false;

827}

unsigned const MachineRegisterInfo * MRI

Provides AMDGPU specific target descriptions.

Base class for AMDGPU specific classes of TargetSubtarget.

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

AMD GCN specific subclass of TargetSubtarget.

unsigned const TargetRegisterInfo * TRI

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

const GCNTargetMachine & getTM(const GCNSubtarget *STI)

static std::optional< yaml::SIArgumentInfo > convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo, const TargetRegisterInfo &TRI)

static yaml::StringValue regToString(Register Reg, const TargetRegisterInfo &TRI)

Interface definition for SIRegisterInfo.

static const AMDGPUFunctionArgInfo FixedABIFunctionInfo

uint32_t getLDSSize() const

bool isChainFunction() const

bool hasInitWholeWave() const

bool isEntryFunction() const

void resize(unsigned N, bool t=false)

resize - Grow or shrink the bitvector.

void setBitsInMask(const uint32_t *Mask, unsigned MaskWords=~0u)

setBitsInMask - Add '1' bits from Mask to this vector.

Allocate memory in an ever growing pool, as if by bump-pointer.

Lightweight error class with error context and mandatory checking.

CallingConv::ID getCallingConv() const

getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...

const SITargetLowering * getTargetLowering() const override

void allocKernargPreloadSGPRs(unsigned NumSGPRs)

Wrapper class representing physical registers. Should be passed by value.

void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())

Remove the specified register from the live in set.

void sortUniqueLiveIns()

Sorts and uniques the LiveIns vector.

void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())

Adds the specified register as a live in.

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)

Create a new statically sized stack object, returning a nonnegative identifier to represent it.

bool hasCalls() const

Return true if the current function has any function calls.

int CreateSpillStackObject(uint64_t Size, Align Alignment)

Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...

void setStackID(int ObjectIdx, uint8_t ID)

bool hasTailCall() const

Returns true if the function contains a tail call.

bool isSpillSlotObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a spill slot.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

void RemoveStackObject(int ObjectIdx)

Remove or mark dead a statically sized stack object.

int getObjectIndexEnd() const

Return one past the maximum frame object index.

uint8_t getStackID(int ObjectIdx) const

int getObjectIndexBegin() const

Return the minimum frame object index.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

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 * cloneInfo(const Ty &Old)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

const MCPhysReg * getCalleeSavedRegs() const

Returns list of callee saved registers.

size_type count(const KeyT &Key) const

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

This interface provides simple read-only access to a block of memory, and provides simple methods for...

virtual StringRef getBufferIdentifier() const

Return an identifier for this buffer, typically the filename it was read from.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

Convert a 0-based index to a virtual register number.

This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...

bool usesAGPRs(const MachineFunction &MF) const

bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI, const MachineFunction &MF, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange)

void shiftWwmVGPRsToLowestRange(MachineFunction &MF, SmallVectorImpl< Register > &WWMVGPRs, BitVector &SavedVGPRs)

Register addPrivateSegmentSize(const SIRegisterInfo &TRI)

void allocateWWMSpill(MachineFunction &MF, Register VGPR, uint64_t Size=4, Align Alignment=Align(4))

Register addDispatchPtr(const SIRegisterInfo &TRI)

Register getLongBranchReservedReg() const

Register addFlatScratchInit(const SIRegisterInfo &TRI)

unsigned getMaxWavesPerEU() const

ArrayRef< Register > getSGPRSpillPhysVGPRs() const

int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI)

Register addQueuePtr(const SIRegisterInfo &TRI)

SIMachineFunctionInfo(const SIMachineFunctionInfo &MFI)=default

Register getGITPtrLoReg(const MachineFunction &MF) const

bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR)

Reserve AGPRs or VGPRs to support spilling for FrameIndex FI.

void splitWWMSpillRegisters(MachineFunction &MF, SmallVectorImpl< std::pair< Register, int > > &CalleeSavedRegs, SmallVectorImpl< std::pair< Register, int > > &ScratchRegs) const

Register getSGPRForEXECCopy() const

bool mayUseAGPRs(const Function &F) const

bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg) const

Register addLDSKernelId()

Register getVGPRForAGPRCopy() const

bool allocateSGPRSpillToVGPRLane(MachineFunction &MF, int FI, bool SpillToPhysVGPRLane=false, bool IsPrologEpilog=false)

Register addKernargSegmentPtr(const SIRegisterInfo &TRI)

Register addDispatchID(const SIRegisterInfo &TRI)

bool removeDeadFrameIndices(MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs)

If ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill to the default stack.

MachineFunctionInfo * clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, const DenseMap< MachineBasicBlock *, MachineBasicBlock * > &Src2DstMBB) const override

Make a functionally equivalent copy of this MachineFunctionInfo in MF.

bool checkIndexInPrologEpilogSGPRSpills(int FI) const

Register addPrivateSegmentBuffer(const SIRegisterInfo &TRI)

const ReservedRegSet & getWWMReservedRegs() const

std::optional< int > getOptionalScavengeFI() const

Register addImplicitBufferPtr(const SIRegisterInfo &TRI)

void limitOccupancy(const MachineFunction &MF)

SmallVectorImpl< MCRegister > * addPreloadedKernArg(const SIRegisterInfo &TRI, const TargetRegisterClass *RC, unsigned AllocSizeDWord, int KernArgIdx, int PaddingSGPRs)

void reserveWWMRegister(Register Reg)

static bool isChainScratchRegister(Register VGPR)

static bool isAGPRClass(const TargetRegisterClass *RC)

Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...

Represents a location in source code.

Represents a range in source code.

bool remove(const value_type &X)

Remove an item from the set vector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

typename SuperClass::const_iterator const_iterator

unsigned getMainFileID() const

const MemoryBuffer * getMemoryBuffer(unsigned i) const

StringRef - Represent a constant reference to a string, i.e.

bool consumeInteger(unsigned Radix, T &Result)

Parse the current string as an integer of the specified radix.

constexpr bool empty() const

empty - Check if the string is empty.

const TargetMachine & getTargetMachine() const

ArrayRef< MCPhysReg > getRegisters() const

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

A raw_ostream that writes to an std::string.

bool isEntryFunctionCC(CallingConv::ID CC)

bool isChainCC(CallingConv::ID CC)

unsigned getInitialPSInputAddr(const Function &F)

bool isGraphics(CallingConv::ID cc)

@ AMDGPU_CS

Used for Mesa/AMDPAL compute shaders.

@ AMDGPU_KERNEL

Used for AMDGPU code object kernels.

@ AMDGPU_Gfx

Used for AMD graphics targets.

@ AMDGPU_HS

Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).

@ AMDGPU_GS

Used for Mesa/AMDPAL geometry shaders.

@ AMDGPU_PS

Used for Mesa/AMDPAL pixel shaders.

@ SPIR_KERNEL

Used for SPIR kernel functions.

This is an optimization pass for GlobalISel generic memory operations.

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

constexpr unsigned DefaultMemoryClusterDWordsLimit

const char * toString(DWARFSectionKind Kind)

Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

This struct is a compact representation of a valid (non-zero power of two) alignment.

static ArgDescriptor createRegister(Register Reg, unsigned Mask=~0u)

Helper struct shared between Function Specialization and SCCP Solver.

MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...

A serializaable representation of a reference to a stack object or fixed stack object.

std::optional< SIArgument > PrivateSegmentWaveByteOffset

std::optional< SIArgument > WorkGroupIDY

std::optional< SIArgument > FlatScratchInit

std::optional< SIArgument > DispatchPtr

std::optional< SIArgument > DispatchID

std::optional< SIArgument > WorkItemIDY

std::optional< SIArgument > WorkGroupIDX

std::optional< SIArgument > ImplicitArgPtr

std::optional< SIArgument > QueuePtr

std::optional< SIArgument > WorkGroupInfo

std::optional< SIArgument > LDSKernelId

std::optional< SIArgument > ImplicitBufferPtr

std::optional< SIArgument > WorkItemIDX

std::optional< SIArgument > KernargSegmentPtr

std::optional< SIArgument > WorkItemIDZ

std::optional< SIArgument > PrivateSegmentSize

std::optional< SIArgument > PrivateSegmentBuffer

std::optional< SIArgument > WorkGroupIDZ

std::optional< unsigned > Mask

static SIArgument createArgument(bool IsReg)

unsigned MaxMemoryClusterDWords

StringValue SGPRForEXECCopy

SmallVector< StringValue > WWMReservedRegs

uint32_t HighBitsOf32BitAddress

SIMachineFunctionInfo()=default

StringValue LongBranchReservedReg

uint64_t ExplicitKernArgSize

void mappingImpl(yaml::IO &YamlIO) override

StringValue VGPRForAGPRCopy

SmallVector< StringValue, 2 > SpillPhysVGPRS

std::optional< FrameIndex > ScavengeFI

unsigned BytesInStackArgArea

A wrapper around std::string which contains a source range that's being set during parsing.