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

1

2

3

4

5

6

7

8

9

10

11

12

13

19

20using namespace llvm;

21

22#define DEBUG_TYPE "machine-scheduler"

23

26 if (S1.size() != S2.size())

27 return false;

28

29 for (const auto &P : S1) {

30 auto I = S2.find(P.first);

31 if (I == S2.end() || I->second != P.second)

32 return false;

33 }

34 return true;

35}

36

37

38

39

47}

48

55 if (NewNumCoveredRegs == PrevNumCoveredRegs)

56 return;

57

58 int Sign = 1;

59 if (NewMask < PrevMask) {

61 std::swap(NewNumCoveredRegs, PrevNumCoveredRegs);

62 Sign = -1;

63 }

64 assert(PrevMask < NewMask && PrevNumCoveredRegs < NewNumCoveredRegs &&

65 "prev mask should always be lesser than new");

66

71 if (TRI->getRegSizeInBits(*RC) != 32) {

72

73 if (PrevMask.none()) {

75 Value[TupleIdx] += Sign * TRI->getRegClassWeight(RC).RegWeight;

76 }

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95 Sign *= NewNumCoveredRegs - PrevNumCoveredRegs;

96 }

98}

99

101 unsigned MaxOccupancy) const {

103 unsigned DynamicVGPRBlockSize =

105

106 const auto SGPROcc = std::min(MaxOccupancy,

107 ST.getOccupancyWithNumSGPRs(getSGPRNum()));

108 const auto VGPROcc = std::min(

109 MaxOccupancy, ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),

110 DynamicVGPRBlockSize));

111 const auto OtherSGPROcc = std::min(MaxOccupancy,

112 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));

113 const auto OtherVGPROcc =

114 std::min(MaxOccupancy,

115 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()),

116 DynamicVGPRBlockSize));

117

118 const auto Occ = std::min(SGPROcc, VGPROcc);

119 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);

120

121

122 if (Occ != OtherOcc)

123 return Occ > OtherOcc;

124

125 unsigned MaxVGPRs = ST.getMaxNumVGPRs(MF);

126 unsigned MaxSGPRs = ST.getMaxNumSGPRs(MF);

127

128

129 unsigned ExcessSGPR = std::max(static_cast<int>(getSGPRNum() - MaxSGPRs), 0);

130 unsigned OtherExcessSGPR =

131 std::max(static_cast<int>(O.getSGPRNum() - MaxSGPRs), 0);

132

133 auto WaveSize = ST.getWavefrontSize();

134

135 unsigned VGPRForSGPRSpills = (ExcessSGPR + (WaveSize - 1)) / WaveSize;

136 unsigned OtherVGPRForSGPRSpills =

137 (OtherExcessSGPR + (WaveSize - 1)) / WaveSize;

138

139 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();

140

141

142

143 unsigned ExcessVGPR =

144 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) +

145 VGPRForSGPRSpills - MaxVGPRs),

146 0);

147 unsigned OtherExcessVGPR =

148 std::max(static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) +

149 OtherVGPRForSGPRSpills - MaxVGPRs),

150 0);

151

152

153 unsigned ExcessArchVGPR = std::max(

154 static_cast<int>(getVGPRNum(false) + VGPRForSGPRSpills - MaxArchVGPRs),

155 0);

156 unsigned OtherExcessArchVGPR =

157 std::max(static_cast<int>(O.getVGPRNum(false) + OtherVGPRForSGPRSpills -

158 MaxArchVGPRs),

159 0);

160

161 unsigned ExcessAGPR = std::max(

162 static_cast<int>(ST.hasGFX90AInsts() ? (getAGPRNum() - MaxArchVGPRs)

164 0);

165 unsigned OtherExcessAGPR = std::max(

166 static_cast<int>(ST.hasGFX90AInsts() ? (O.getAGPRNum() - MaxArchVGPRs)

167 : (O.getAGPRNum() - MaxVGPRs)),

168 0);

169

170 bool ExcessRP = ExcessSGPR || ExcessVGPR || ExcessArchVGPR || ExcessAGPR;

171 bool OtherExcessRP = OtherExcessSGPR || OtherExcessVGPR ||

172 OtherExcessArchVGPR || OtherExcessAGPR;

173

174

175

176 if (ExcessRP || OtherExcessRP) {

177

178

179 int VGPRDiff = ((OtherExcessVGPR + OtherExcessArchVGPR + OtherExcessAGPR) -

180 (ExcessVGPR + ExcessArchVGPR + ExcessAGPR));

181

182 int SGPRDiff = OtherExcessSGPR - ExcessSGPR;

183

184 if (VGPRDiff != 0)

185 return VGPRDiff > 0;

186 if (SGPRDiff != 0) {

187 unsigned PureExcessVGPR =

188 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),

189 0) +

190 std::max(static_cast<int>(getVGPRNum(false) - MaxArchVGPRs), 0);

191 unsigned OtherPureExcessVGPR =

192 std::max(

193 static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),

194 0) +

195 std::max(static_cast<int>(O.getVGPRNum(false) - MaxArchVGPRs), 0);

196

197

198

199

200 if (PureExcessVGPR != OtherPureExcessVGPR)

201 return SGPRDiff < 0;

202

203

204 return SGPRDiff > 0;

205 }

206 }

207

208 bool SGPRImportant = SGPROcc < VGPROcc;

209 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;

210

211

212 if (SGPRImportant != OtherSGPRImportant) {

213 SGPRImportant = false;

214 }

215

216

217 bool SGPRFirst = SGPRImportant;

218 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {

219 if (SGPRFirst) {

221 auto OtherSW = O.getSGPRTuplesWeight();

222 if (SW != OtherSW)

223 return SW < OtherSW;

224 } else {

226 auto OtherVW = O.getVGPRTuplesWeight();

227 if (VW != OtherVW)

228 return VW < OtherVW;

229 }

230 }

231

232

233 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):

235 O.getVGPRNum(ST.hasGFX90AInsts()));

236}

237

239 unsigned DynamicVGPRBlockSize) {

241 OS << "VGPRs: " << RP.getArchVGPRNum() << ' '

242 << "AGPRs: " << RP.getAGPRNum();

243 if (ST)

244 OS << "(O"

245 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()),

246 DynamicVGPRBlockSize)

247 << ')';

248 OS << ", SGPRs: " << RP.getSGPRNum();

249 if (ST)

250 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';

251 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()

252 << ", LSGPR WT: " << RP.getSGPRTuplesWeight();

253 if (ST)

254 OS << " -> Occ: " << RP.getOccupancy(*ST, DynamicVGPRBlockSize);

255 OS << '\n';

256 });

257}

258

262

263

264

265

267 MRI.getMaxLaneMaskForVReg(MO.getReg()) :

268 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());

269}

270

271static void

275

276 auto &TRI = *MRI.getTargetRegisterInfo();

277 for (const auto &MO : MI.operands()) {

278 if (!MO.isReg() || !MO.getReg().isVirtual())

279 continue;

280 if (!MO.isUse() || !MO.readsReg())

281 continue;

282

285 return RM.VRegOrUnit.asVirtualReg() == Reg;

286 });

287

288 auto &P = I == VRegMaskOrUnits.end()

291 : *I;

292

293 P.LaneMask |= MO.getSubReg() ? TRI.getSubRegIndexLaneMask(MO.getSubReg())

294 : MRI.getMaxLaneMaskForVReg(Reg);

295 }

296

298 for (auto &P : VRegMaskOrUnits) {

299 auto &LI = LIS.getInterval(P.VRegOrUnit.asVirtualReg());

300 if (!LI.hasSubRanges())

301 continue;

302

303

304

305

306 if (!InstrSI)

307 InstrSI = LIS.getInstructionIndex(MI).getBaseIndex();

308

310 }

311}

312

313

323 if (Property(SR, Pos))

324 Result |= SR.LaneMask;

325 }

326 } else if (Property(LI, Pos)) {

327 Result =

329 }

330

331 return Result;

332}

333

334

335

336

337

343 bool Upward = false) {

345 if (MO.isUndef())

346 continue;

349 bool InRange = Upward ? (InstSlot > PriorUseIdx && InstSlot <= NextUseIdx)

350 : (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx);

352 continue;

353

354 unsigned SubRegIdx = MO.getSubReg();

355 LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);

356 LastUseMask &= ~UseMask;

357 if (LastUseMask.none())

359 }

360 return LastUseMask;

361}

362

363

364

365

368 const Function &F = MF.getFunction();

370 setTarget(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F));

371}

372

378

383 unsigned DynamicVGPRBlockSize =

385 setTarget(ST.getMaxNumSGPRs(Occupancy, false),

386 ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));

387}

388

391 MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);

392 MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);

393 if (UnifiedRF) {

394 unsigned DynamicVGPRBlockSize =

396 MaxUnifiedVGPRs =

397 std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);

398 } else {

399 MaxUnifiedVGPRs = 0;

400 }

401}

402

408

410 return RP.getSGPRNum() > MaxSGPRs;

411 unsigned NumVGPRs =

412 SRI->isAGPRClass(RC) ? RP.getAGPRNum() : RP.getArchVGPRNum();

413

414 if (NumVGPRs > MaxVGPRs)

415 return true;

416

417 return UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs;

418}

419

421 if (RP.getSGPRNum() > MaxSGPRs || RP.getVGPRNum(false) > MaxVGPRs)

422 return false;

423 if (UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs)

424 return false;

425 return true;

426}

427

428

429

430

437

443 for (const auto &S : LI.subranges())

444 if ((S.LaneMask & LaneMaskFilter).any() && S.liveAt(SI)) {

445 LiveMask |= S.LaneMask;

446 assert(LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg(LI.reg())));

447 }

449 LiveMask = MRI.getMaxLaneMaskForVReg(LI.reg());

450 }

451 LiveMask &= LaneMaskFilter;

452 return LiveMask;

453}

454

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

464 continue;

466 continue;

468 if (LiveMask.any())

470 }

472}

473

476 bool After) {

479 if (LiveRegsCopy) {

480 if (&LiveRegs != LiveRegsCopy)

482 } else {

485 }

486

488}

489

497

498

503 const LiveRange::Segment *S = LR.getSegmentContaining(Pos);

504 return S != nullptr && S->end == Pos.getRegSlot();

505 });

506}

507

508

509

510

512 assert(MRI && "call reset first");

513

515

516 if (MI.isDebugInstr())

517 return;

518

519

521 bool HasECDefs = false;

523 if (!MO.getReg().isVirtual())

524 continue;

525

528

529

530 if (MO.isEarlyClobber()) {

532 HasECDefs = true;

533 } else

535

538 continue;

539

542 LiveMask &= ~DefMask;

544 if (LiveMask.none())

546 }

547

548

550 if (HasECDefs)

551 DefPressure += ECDefPressure;

553

554

560 LiveMask |= U.LaneMask;

561 CurPressure.inc(U.VRegOrUnit.asVirtualReg(), PrevMask, LiveMask, *MRI);

562 }

563

564

567

569}

570

571

572

573

576 MRI = &MI.getMF()->getRegInfo();

578 MBBEnd = MI.getParent()->end();

579 NextMI = &MI;

581 if (NextMI == MBBEnd)

582 return false;

584 return true;

585}

586

588 bool UseInternalIterator) {

589 assert(MRI && "call reset first");

592 if (UseInternalIterator) {

594 return NextMI == MBBEnd;

595

596 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());

598

599 SI = NextMI == MBBEnd

600 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()

601 : LIS.getInstructionIndex(*NextMI).getBaseIndex();

602 } else {

603 SI = LIS.getInstructionIndex(*MI).getBaseIndex();

604 CurrMI = MI;

605 }

606

608

609

611 for (auto &MO : CurrMI->operands()) {

612 if (!MO.isReg() || !MO.getReg().isVirtual())

613 continue;

614 if (MO.isUse() && !MO.readsReg())

615 continue;

616 if (!UseInternalIterator && MO.isDef())

617 continue;

618 if (!SeenRegs.insert(MO.getReg()).second)

619 continue;

623 for (const auto &S : LI.subranges()) {

624 if (!S.liveAt(SI)) {

626 It = LiveRegs.find(MO.getReg());

629 }

630 auto PrevMask = It->second;

631 It->second &= ~S.LaneMask;

632 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI);

633 }

634 }

635 if (It != LiveRegs.end() && It->second.none())

638 auto It = LiveRegs.find(MO.getReg());

643 }

644 }

645

647

649

650 return UseInternalIterator && (NextMI == MBBEnd);

651}

652

654 bool UseInternalIterator) {

655 if (UseInternalIterator) {

658 } else {

660 }

661

663

664

665 for (const auto &MO : CurrMI->all_defs()) {

667 if (!Reg.isVirtual())

668 continue;

669 auto &LiveMask = LiveRegs[Reg];

670 auto PrevMask = LiveMask;

673 }

674

676}

677

679 if (UseInternalIterator && NextMI == MBBEnd)

680 return false;

681

684 if (!UseInternalIterator) {

685

687 }

688 return true;

689}

690

692 while (NextMI != End)

693 if (advance()) return false;

694 return true;

695}

696

700 reset(*Begin, LiveRegsCopy);

702}

703

708 for (auto const &P : TrackedLR) {

709 auto I = LISLR.find(P.first);

710 if (I == LISLR.end()) {

712 << " isn't found in LIS reported set\n";

713 } else if (I->second != P.second) {

715 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)

717 }

718 }

719 for (auto const &P : LISLR) {

720 auto I = TrackedLR.find(P.first);

721 if (I == TrackedLR.end()) {

723 << " isn't found in tracked set\n";

724 }

725 }

726 });

727}

728

732 assert(MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");

733

735 SlotIdx = LIS.getInstructionIndex(*MI).getRegSlot();

736

737

739 RegOpers.collect(*MI, *TRI, *MRI, true, false);

742

744 if (Use.VRegOrUnit.isVirtualReg())

745 continue;

746 Register Reg = Use.VRegOrUnit.asVirtualReg();

748 if (LastUseMask.none())

749 continue;

750

751

752

753

754

759 if (IdxPos == MBB->end()) {

760 CurrIdx = LIS.getMBBEndIdx(MBB);

761 } else {

762 CurrIdx = LIS.getInstructionIndex(*IdxPos).getRegSlot();

763 }

764

765 LastUseMask =

767 if (LastUseMask.none())

768 continue;

769

770 auto It = LiveRegs.find(Reg);

772 LaneBitmask NewMask = LiveMask & ~LastUseMask;

773 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);

774 }

775

776

778 if (!Def.VRegOrUnit.isVirtualReg())

779 continue;

780 Register Reg = Def.VRegOrUnit.asVirtualReg();

781 auto It = LiveRegs.find(Reg);

783 LaneBitmask NewMask = LiveMask | Def.LaneMask;

784 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);

785 }

786

787 return TempPressure;

788}

789

791 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();

793 const auto &TrackedLR = LiveRegs;

794

795 if (isEqual(LISLR, TrackedLR)) {

796 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"

797 " LIS reported livesets mismatch:\n"

800 return false;

801 }

802

805 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "

807 return false;

808 }

809 return true;

810}

811

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

818 auto It = LiveRegs.find(Reg);

819 if (It != LiveRegs.end() && It->second.any())

821 }

822 OS << '\n';

823 });

824}

825

827

829 "amdgpu-print-rp-downward",

830 cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"),

832

835

837

838

839

844

845 auto IsInOneSegment = [Begin, End](const LiveRange &LR) -> bool {

846 auto *Segment = LR.getSegmentContaining(Begin);

847 return Segment && Segment->contains(End);

848 };

849

853 for (auto &SR : LI.subranges()) {

854 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR))

855 LiveThroughMask |= SR.LaneMask;

856 }

857 } else {

859 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI))

860 LiveThroughMask = RegMask;

861 }

862

863 return LiveThroughMask;

864}

865

870

871 auto &OS = dbgs();

872

873

874#define PFX " "

875

876 OS << "---\nname: " << MF.getName() << "\nbody: |\n";

877

880 OS << format(PFX " %-5d", RP.getSGPRNum())

881 << format(" %-5d", RP.getVGPRNum(false));

882 });

883 };

884

887 if (LISLR != TrackedLR) {

890 }

891 };

892

893

895

896 for (auto &MBB : MF) {

897 RP.clear();

898 RP.reserve(MBB.size());

899

900 OS << PFX;

901 MBB.printName(OS);

902 OS << ":\n";

903

906

909

911 if (MBB.empty()) {

912 LiveIn = LiveOut = getLiveRegs(MBBStartSlot, LIS, MRI);

914 } else {

917

919

923 RP.emplace_back(RPBeforeMI, RPT.getPressure());

924 }

925

928 }

929 } else {

932

935

939 if (MI.isDebugInstr())

941 }

942

944 }

945

948 ReportLISMismatchIfAny(LiveIn, getLiveRegs(MBBStartSlot, LIS, MRI));

949

950 OS << PFX " SGPR VGPR\n";

951 int I = 0;

952 for (auto &MI : MBB) {

953 if (MI.isDebugInstr()) {

954 auto &[RPBeforeInstr, RPAtInstr] =

956 ++I;

957 OS << printRP(RPBeforeInstr) << '\n' << printRP(RPAtInstr) << " ";

958 } else

959 OS << PFX " ";

960 MI.print(OS);

961 }

962 OS << printRP(RPAtMBBEnd) << '\n';

963

966 ReportLISMismatchIfAny(LiveOut, getLiveRegs(MBBLastSlot, LIS, MRI));

967

969 for (auto [Reg, Mask] : LiveIn) {

971 if (MaskIntersection.any()) {

973 MRI, LIS, Reg, MBBStartSlot, MBBLastSlot, MaskIntersection);

974 if (LTMask.any())

975 LiveThrough[Reg] = LTMask;

976 }

977 }

980 }

981 OS << "...\n";

982 return false;

983

984#undef PFX

985}

986

987#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

992

995 auto &OS = dbgs();

997

998 unsigned MaxNumRegs = 0;

1006 if (NumRegs > MaxNumRegs) {

1007 MaxNumRegs = NumRegs;

1008 MaxPressureMI = &MI;

1009 }

1010 }

1011 }

1012

1014

1015

1016

1017

1025 ECNumRegs > RNumRegs ? &ECLiveSet : &RLiveSet;

1026 SlotIndex MaxPressureSlot = ECNumRegs > RNumRegs ? ECSlot : RSlot;

1028

1029

1032 for (auto [Reg, LaneMask] : *LiveSet) {

1038 return SR.getNumValNums() == 1;

1039 }))) {

1042 } else {

1045 }

1046 }

1047 unsigned SDefNumRegs = SDefPressure.getNumRegs(Kind);

1048 unsigned MDefNumRegs = MDefPressure.getNumRegs(Kind);

1049 assert(SDefNumRegs + MDefNumRegs == MaxNumRegs);

1050

1054 if (MLI)

1057 << ", Depth " << ML->getLoopDepth() << ")";

1058 });

1059 };

1060

1065 << TRI->getRegClassName(MRI.getRegClass(Reg)) << ", LiveMask "

1066 << PrintLaneMask(LiveMask) << " (" << RegPressure.getNumRegs(Kind) << ' '

1068

1069

1070 std::map<SlotIndex, const MachineInstr *> Instrs;

1071 for (const MachineInstr &MI : MRI.reg_nodbg_instructions(Reg)) {

1073 }

1074

1075 for (const auto &[SI, MI] : Instrs) {

1076 OS << " ";

1077 if (MI->definesRegister(Reg, TRI))

1078 OS << "def ";

1079 if (MI->readsRegister(Reg, TRI))

1080 OS << "use ";

1081 OS << printLoc(MI->getParent(), SI) << ": " << *MI;

1082 }

1083 };

1084

1085 OS << "\n*** Register pressure info (" << RegName << "s) for " << MF.getName()

1086 << " ***\n";

1087 OS << "Max pressure is " << MaxNumRegs << ' ' << RegName << "s at "

1088 << printLoc(MaxPressureMI->getParent(), MaxPressureSlot) << ": "

1089 << *MaxPressureMI;

1090

1091 OS << "\nLive registers with single definition (" << SDefNumRegs << ' '

1093

1094

1096 return std::distance(MRI.use_nodbg_begin(A), MRI.use_nodbg_end()) <

1097 std::distance(MRI.use_nodbg_begin(B), MRI.use_nodbg_end());

1098 });

1099

1100 for (const Register Reg : SDefRegs) {

1101 PrintRegInfo(Reg, LiveSet->lookup(Reg));

1102 }

1103

1104 OS << "\nLive registers with multiple definitions (" << MDefNumRegs << ' '

1106 for (const Register Reg : MDefRegs) {

1107 PrintRegInfo(Reg, LiveSet->lookup(Reg));

1108 }

1109}

1110#endif

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

static void collectVirtualRegUses(SmallVectorImpl< VRegMaskOrUnit > &VRegMaskOrUnits, const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)

Definition GCNRegPressure.cpp:272

static cl::opt< bool > UseDownwardTracker("amdgpu-print-rp-downward", cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"), cl::init(false), cl::Hidden)

static LaneBitmask getDefRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI)

Definition GCNRegPressure.cpp:259

static LaneBitmask getRegLiveThroughMask(const MachineRegisterInfo &MRI, const LiveIntervals &LIS, Register Reg, SlotIndex Begin, SlotIndex End, LaneBitmask Mask=LaneBitmask::getAll())

Definition GCNRegPressure.cpp:841

This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...

Register const TargetRegisterInfo * TRI

static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, bool TrackLaneMasks, VirtRegOrUnit VRegOrUnit, SlotIndex Pos, LaneBitmask SafeDefault, bool(*Property)(const LiveRange &LR, SlotIndex Pos))

static LaneBitmask findUseBetween(VirtRegOrUnit VRegOrUnit, LaneBitmask LastUseMask, SlotIndex PriorUseIdx, SlotIndex NextUseIdx, const MachineRegisterInfo &MRI, const LiveIntervals *LIS)

Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

iterator find(const_arg_type_t< KeyT > Val)

bool advanceBeforeNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)

Move to the state right before the next MI or after the end of MBB.

Definition GCNRegPressure.cpp:587

bool advance(MachineInstr *MI=nullptr, bool UseInternalIterator=true)

Move to the state at the next MI.

Definition GCNRegPressure.cpp:678

GCNRegPressure bumpDownwardPressure(const MachineInstr *MI, const SIRegisterInfo *TRI) const

Mostly copy/paste from CodeGen/RegisterPressure.cpp Calculate the impact MI will have on CurPressure ...

Definition GCNRegPressure.cpp:730

bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)

Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.

Definition GCNRegPressure.cpp:574

void advanceToNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)

Move to the state at the MI, advanceBeforeNext has to be called first.

Definition GCNRegPressure.cpp:653

GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP)

Sets up the target such that the register pressure starting at RP does not show register spilling on ...

Definition GCNRegPressure.cpp:366

bool isSaveBeneficial(Register Reg) const

Determines whether saving virtual register Reg will be beneficial towards achieving the RP target.

Definition GCNRegPressure.cpp:403

bool satisfied() const

Whether the current RP is at or below the defined pressure target.

Definition GCNRegPressure.cpp:420

void setTarget(unsigned NumSGPRs, unsigned NumVGPRs)

Changes the target (same semantics as constructor).

Definition GCNRegPressure.cpp:389

GCNRegPressure getPressure() const

const decltype(LiveRegs) & getLiveRegs() const

const MachineInstr * LastTrackedMI

GCNRegPressure CurPressure

DenseMap< unsigned, LaneBitmask > LiveRegSet

LaneBitmask getLastUsedLanes(Register Reg, SlotIndex Pos) const

Mostly copy/paste from CodeGen/RegisterPressure.cpp.

Definition GCNRegPressure.cpp:499

GCNRegPressure MaxPressure

void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)

Definition GCNRegPressure.cpp:474

const MachineRegisterInfo * MRI

const LiveIntervals & LIS

void reset(const MachineRegisterInfo &MRI, SlotIndex SI)

reset tracker at the specified slot index SI.

void recede(const MachineInstr &MI)

Move to the state of RP just before the MI .

Definition GCNRegPressure.cpp:511

const GCNRegPressure & getMaxPressure() const

bool isValid() const

returns whether the tracker's state after receding MI corresponds to reported by LIS.

Definition GCNRegPressure.cpp:790

A live range for subregisters.

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()

bool hasInterval(Register Reg) const

SlotIndexes * getSlotIndexes() const

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

LiveInterval & getInterval(Register Reg)

This class represents the liveness of a register, stack slot, etc.

bool liveAt(SlotIndex index) const

unsigned getNumValNums() const

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

MachineInstrBundleIterator< const MachineInstr > const_iterator

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

filtered_mop_range all_defs()

Returns an iterator range over all operands that are (explicit or implicit) register defs.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

Register getReg() const

getReg - Returns the register number.

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

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

Simple wrapper around std::function<void(raw_ostream&)>.

List of registers defined and used by a machine instruction.

SmallVector< VRegMaskOrUnit, 8 > Defs

List of virtual registers and register units defined by the instruction which are not dead.

LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)

Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...

LLVM_ABI void adjustLaneLiveness(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, SlotIndex Pos, MachineInstr *AddFlagsMI=nullptr)

Use liveness information to find out which uses/defs are partially undefined/dead and adjust the VReg...

SmallVector< VRegMaskOrUnit, 8 > Uses

List of virtual registers and register units read by the instruction.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

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

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

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

unsigned getDynamicVGPRBlockSize() const

static unsigned getNumCoveredRegs(LaneBitmask LM)

bool isVectorSuperClass(const TargetRegisterClass *RC) const

static bool isSGPRClass(const TargetRegisterClass *RC)

static bool isAGPRClass(const TargetRegisterClass *RC)

SlotIndex - An opaque wrapper around machine indexes.

SlotIndex getBaseIndex() const

Returns the base index for associated with this index.

SlotIndex getPrevSlot() const

Returns the previous slot in the index list.

SlotIndex getRegSlot(bool EC=false) const

Returns the register use/def slot in the current instruction for a normal or early-clobber def.

SlotIndex getMBBLastIdx(const MachineBasicBlock *MBB) const

Returns the last valid index in the given basic block.

SlotIndex getMBBEndIdx(unsigned Num) const

Returns the index past the last valid index in the given basic block.

SlotIndex getMBBStartIdx(unsigned Num) const

Returns the first index in the given basic block number.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

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

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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

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

A Use represents the edge between a Value definition and its users.

Wrapper class representing a virtual register or register unit.

An efficient, type-erasing, non-owning reference to a callable.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)

LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, LaneBitmask LaneMaskFilter=LaneBitmask::getAll())

Definition GCNRegPressure.cpp:431

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)

Definition GCNRegPressure.cpp:24

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

Definition GCNRegPressure.cpp:238

GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, GCNRegPressure::RegKind RegKind=GCNRegPressure::TOTAL_KINDS)

Definition GCNRegPressure.cpp:455

GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)

Printable PrintLaneMask(LaneBitmask LaneMask)

Create Printable object to print LaneBitmasks on a raw_ostream.

IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)

Increment It until it points to a non-debug instruction or to End and return the resulting iterator.

GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)

auto reverse(ContainerTy &&C)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

char & GCNRegPressurePrinterID

Definition GCNRegPressure.cpp:834

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)

LLVM_ABI void dumpMaxRegPressure(MachineFunction &MF, GCNRegPressure::RegKind Kind, LiveIntervals &LIS, const MachineLoopInfo *MLI)

Definition GCNRegPressure.cpp:988

LLVM_ABI 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.

Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")

Definition GCNRegPressure.cpp:704

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

bool runOnMachineFunction(MachineFunction &MF) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

Definition GCNRegPressure.cpp:866

static RegKind getRegKind(unsigned Reg, const MachineRegisterInfo &MRI)

static constexpr const char * getName(RegKind Kind)

void dump() const

Definition GCNRegPressure.cpp:826

unsigned getNumRegs(RegKind Kind) const

unsigned getVGPRTuplesWeight() const

unsigned getVGPRNum(bool UnifiedVGPRFile) const

friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)

void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)

Definition GCNRegPressure.cpp:49

unsigned getAGPRNum() const

unsigned getSGPRNum() const

unsigned getSGPRTuplesWeight() const

bool less(const MachineFunction &MF, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const

Compares this GCNRegpressure to O, returning true if this is less.

Definition GCNRegPressure.cpp:100

static constexpr LaneBitmask getAll()

constexpr bool none() const

constexpr bool any() const

static constexpr LaneBitmask getNone()