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()).second;

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

188 limitOccupancy(ST.getOccupancyWithWorkGroupSizes(MF).second);

189}

190

193 ArgInfo.PrivateSegmentBuffer =

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

196 NumUserSGPRs += 4;

197 return ArgInfo.PrivateSegmentBuffer.getRegister();

198}

199

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

203 NumUserSGPRs += 2;

204 return ArgInfo.DispatchPtr.getRegister();

205}

206

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

210 NumUserSGPRs += 2;

211 return ArgInfo.QueuePtr.getRegister();

212}

213

215 ArgInfo.KernargSegmentPtr

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

218 NumUserSGPRs += 2;

219 return ArgInfo.KernargSegmentPtr.getRegister();

220}

221

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

225 NumUserSGPRs += 2;

226 return ArgInfo.DispatchID.getRegister();

227}

228

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

232 NumUserSGPRs += 2;

233 return ArgInfo.FlatScratchInit.getRegister();

234}

235

238 NumUserSGPRs += 1;

239 return ArgInfo.PrivateSegmentSize.getRegister();

240}

241

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

245 NumUserSGPRs += 2;

246 return ArgInfo.ImplicitBufferPtr.getRegister();

247}

248

251 NumUserSGPRs += 1;

252 return ArgInfo.LDSKernelId.getRegister();

253}

254

257 unsigned AllocSizeDWord, int KernArgIdx, int PaddingSGPRs) {

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

259 "Preload kernel argument allocated twice.");

260 NumUserSGPRs += PaddingSGPRs;

261

262

263

264 if (ArgInfo.FirstKernArgPreloadReg)

265 ArgInfo.FirstKernArgPreloadReg = getNextUserSGPR();

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

268 if (PreloadReg &&

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

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

271 NumUserSGPRs += AllocSizeDWord;

272 } else {

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

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

275 NumUserSGPRs++;

276 }

277 }

278

279

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

282}

283

286

288 return;

289

290

291

292

293

294

295

296

297

298

302 return;

303

304 WWMSpills.insert(std::make_pair(

306}

307

308

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

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

314 for (auto &Reg : WWMSpills) {

316 CalleeSavedRegs.push_back(Reg);

317 else

318 ScratchRegs.push_back(Reg);

319 }

320}

321

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

325 if (CSRegs[I] == Reg)

326 return true;

327 }

328

329 return false;

330}

331

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

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

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

342 break;

343

344 MRI.replaceRegWith(Reg, NewReg);

345

346

347 WWMVGPRs[I] = NewReg;

348 WWMReservedRegs.remove(Reg);

349 WWMReservedRegs.insert(NewReg);

350 MRI.reserveReg(NewReg, TRI);

351

352

353

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

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

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

357 SpillPhysVGPRs[Idx] = NewReg;

358 }

359

360

361

362 SavedVGPRs.reset(Reg);

363

367 }

368

369 Reg = NewReg;

370 }

371}

372

373bool SIMachineFunctionInfo::allocateVirtualVGPRForSGPRSpills(

377 if (!LaneIndex) {

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

379 SpillVGPRs.push_back(LaneVGPR);

380 } else {

381 LaneVGPR = SpillVGPRs.back();

382 }

383

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

385 return true;

386}

387

388bool SIMachineFunctionInfo::allocatePhysicalVGPRForSGPRSpills(

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

394 if (!LaneIndex) {

395

396

397

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

399 !IsPrologEpilog);

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

401

402

403 SGPRSpillsToPhysicalVGPRLanes.erase(FI);

404 return false;

405 }

406

407 if (IsPrologEpilog)

409

414 }

415 SpillPhysVGPRs.push_back(LaneVGPR);

416 } else {

417 LaneVGPR = SpillPhysVGPRs.back();

418 }

419

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

421 return true;

422}

423

426 bool IsPrologEpilog) {

427 std::vectorSIRegisterInfo::SpilledReg &SpillLanes =

428 SpillToPhysVGPRLane ? SGPRSpillsToPhysicalVGPRLanes[FI]

429 : SGPRSpillsToVirtualVGPRLanes[FI];

430

431

432 if (!SpillLanes.empty())

433 return true;

434

437 unsigned WaveSize = ST.getWavefrontSize();

438

439 unsigned Size = FrameInfo.getObjectSize(FI);

440 unsigned NumLanes = Size / 4;

441

442 if (NumLanes > WaveSize)

443 return false;

444

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

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

447 "not spilling SGPRs to VGPRs");

448

449 unsigned &NumSpillLanes = SpillToPhysVGPRLane ? NumPhysicalVGPRSpillLanes

450 : NumVirtualVGPRSpillLanes;

451

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

453 unsigned LaneIndex = (NumSpillLanes % WaveSize);

454

455 bool Allocated = SpillToPhysVGPRLane

456 ? allocatePhysicalVGPRForSGPRSpills(MF, FI, LaneIndex,

457 IsPrologEpilog)

458 : allocateVirtualVGPRForSGPRSpills(MF, FI, LaneIndex);

459 if (!Allocated) {

460 NumSpillLanes -= I;

461 return false;

462 }

463 }

464

465 return true;

466}

467

468

469

470

472 int FI,

473 bool isAGPRtoVGPR) {

477

479

480 auto &Spill = VGPRToAGPRSpills[FI];

481

482

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

484 return Spill.FullyAllocated;

485

487 unsigned NumLanes = Size / 4;

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

489

491 isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;

493

494 auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;

496 Spill.FullyAllocated = true;

497

498

499

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

502

505 if (CSRMask)

507

508

509

511 OtherUsedRegs.set(Reg);

513 OtherUsedRegs.set(Reg);

514

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

517 NextSpillReg = std::find_if(

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

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

520 !OtherUsedRegs[Reg];

521 });

522

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

524 Spill.FullyAllocated = false;

525 break;

526 }

527

528 OtherUsedRegs.set(*NextSpillReg);

529 SpillRegs.push_back(*NextSpillReg);

530 MRI.reserveReg(*NextSpillReg, TRI);

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

532 }

533

534 return Spill.FullyAllocated;

535}

536

539

540

541

542

543

544

547 SGPRSpillsToVirtualVGPRLanes.erase(R.first);

548 }

549

550

551

552 if (!ResetSGPRSpillStackIDs) {

555 SGPRSpillsToPhysicalVGPRLanes.erase(R.first);

556 }

557 }

558 bool HaveSGPRToMemory = false;

559

560 if (ResetSGPRSpillStackIDs) {

561

562

564 ++I) {

568 HaveSGPRToMemory = true;

569 }

570 }

571 }

572 }

573

574 for (auto &R : VGPRToAGPRSpills) {

575 if (R.second.IsDead)

577 }

578

579 return HaveSGPRToMemory;

580}

581

584 if (ScavengeFI)

585 return *ScavengeFI;

586

587 ScavengeFI =

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

590 return *ScavengeFI;

591}

592

593MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {

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

595 return AMDGPU::SGPR0 + NumUserSGPRs;

596}

597

598MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {

599 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;

600}

601

602void SIMachineFunctionInfo::MRI_NoteNewVirtualRegister(Register Reg) {

603 VRegFlags.grow(Reg);

604}

605

606void SIMachineFunctionInfo::MRI_NoteCloneVirtualRegister(Register NewReg,

608 VRegFlags.grow(NewReg);

609 VRegFlags[NewReg] = VRegFlags[SrcReg];

610}

611

615 if (!ST.isAmdPalOS())

617 Register GitPtrLo = AMDGPU::SGPR0;

618 if (ST.hasMergedShaders()) {

622

623

624 GitPtrLo = AMDGPU::SGPR8;

625 return GitPtrLo;

626 default:

627 return GitPtrLo;

628 }

629 }

630 return GitPtrLo;

631}

632

636 {

639 }

640 return Dest;

641}

642

643static std::optionalyaml::SIArgumentInfo

647

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

650 if (!Arg)

651 return false;

652

653

655 if (Arg.isRegister()) {

658 } else

660

661 if (Arg.isMasked())

662 SA.Mask = Arg.getMask();

663

664 A = SA;

665 return true;

666 };

667

668

669 bool Any = false;

683 ArgInfo.PrivateSegmentWaveByteOffset);

689

691 return AI;

692

693 return std::nullopt;

694}

695

699 : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),

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

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

702 IsEntryFunction(MFI.isEntryFunction()),

703 NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),

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

705 HasSpilledSGPRs(MFI.hasSpilledSGPRs()),

706 HasSpilledVGPRs(MFI.hasSpilledVGPRs()),

707 HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),

708 Occupancy(MFI.getOccupancy()),

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

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

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

712 BytesInStackArgArea(MFI.getBytesInStackArgArea()),

713 ReturnsVoid(MFI.returnsVoid()),

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

716 MaxMemoryClusterDWords(MFI.getMaxMemoryClusterDWords()),

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

720

723

728

731

733 if (SFI)

735}

736

739}

740

762

765 if (!FIOrErr) {

766

769

772 "", {}, {});

773 SourceRange = YamlMFI.ScavengeFI->SourceRange;

774 return true;

775 }

777 } else {

779 }

780 return false;

781}

782

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

785}

786

788 if (UsesAGPRs)

789 return *UsesAGPRs;

790

791 if (!mayNeedAGPRs()) {

792 UsesAGPRs = false;

793 return false;

794 }

795

798 UsesAGPRs = true;

799 return true;

800 }

801

803

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

808 UsesAGPRs = true;

809 return true;

810 }

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

812

813 return true;

814 }

815 }

816

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

818 if (MRI.isPhysRegUsed(Reg)) {

819 UsesAGPRs = true;

820 return true;

821 }

822 }

823

824 UsesAGPRs = false;

825 return false;

826}

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.