LLVM: lib/CodeGen/MLRegAllocEvictAdvisor.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)

23#endif

41

42#include

43#include

44#include

45#include <unordered_map>

46

47using namespace llvm;

48

49#define DEBUG_TYPE "ml-regalloc"

50

51

52#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)

53#include "RegAllocEvictModel.h"

55#else

57#endif

58

60 "regalloc-evict-interactive-channel-base", cl::Hidden,

62 "Base file path for the interactive mode. The incoming filename should "

63 "have the name .in, while the "

64 "outgoing name should be "

65 ".out"));

66

68 "mlregalloc-max-eviction-count", cl::Hidden,

69 cl::desc("The maximum number of times a live range can be "

70 "evicted before preventing it from being evicted"),

72

73

74#ifdef LLVM_HAVE_TFLITE

77

80 cl::desc("Training log for the register allocator eviction model"));

81

84 cl::desc("The model being trained for register allocation eviction"));

85

86#endif

87

88

89

90

91namespace llvm {

93}

94

95namespace {

97public:

98 static char ID;

99

100 RegAllocScoring() : MachineFunctionPass(ID) {

102 }

103

104 ~RegAllocScoring() override = default;

105

106 StringRef getPassName() const override {

107 return "Register Allocation Pass Scoring";

108 }

109

110

111 void getAnalysisUsage(AnalysisUsage &AU) const override {

113 AU.addRequired();

114 AU.addRequired();

115 AU.addRequired();

117 }

118

119

120 bool runOnMachineFunction(MachineFunction &) override;

121};

122}

123

124char RegAllocScoring::ID = 0;

126 return new RegAllocScoring();

127}

128

130 "Register Allocation Scoring Pass", false, false)

131

132

133

134

135namespace {

136

137

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158#define RA_EVICT_FEATURES_LIST(M) \

159 M(int64_t, mask, PerLiveRangeShape, \

160 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \

161 "it " \

162 "can't be evicted)") \

163 M(int64_t, is_free, PerLiveRangeShape, \

164 "boolean values, 1 if this phys reg is actually free (no interferences)") \

165 M(float, nr_urgent, PerLiveRangeShape, \

166 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \

167 "to break cascades") \

168 M(float, nr_broken_hints, PerLiveRangeShape, \

169 "if this position were evicted, how many broken hints would there be") \

170 M(int64_t, is_hint, PerLiveRangeShape, \

171 "is this a preferred phys reg for the candidate") \

172 M(int64_t, is_local, PerLiveRangeShape, \

173 "is this live range local to a basic block") \

174 M(float, nr_rematerializable, PerLiveRangeShape, \

175 "nr rematerializable ranges") \

176 M(float, nr_defs_and_uses, PerLiveRangeShape, \

177 "bb freq - weighed nr defs and uses") \

178 M(float, weighed_reads_by_max, PerLiveRangeShape, \

179 "bb freq - weighed nr of reads, normalized") \

180 M(float, weighed_writes_by_max, PerLiveRangeShape, \

181 "bb feq - weighed nr of writes, normalized") \

182 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \

183 "bb freq - weighed nr of uses that are both read and writes, normalized") \

184 M(float, weighed_indvars_by_max, PerLiveRangeShape, \

185 "bb freq - weighed nr of uses that are indvars, normalized") \

186 M(float, hint_weights_by_max, PerLiveRangeShape, \

187 "bb freq - weighed nr of uses that are hints, normalized") \

188 M(float, start_bb_freq_by_max, PerLiveRangeShape, \

189 "the freq in the start block, normalized") \

190 M(float, end_bb_freq_by_max, PerLiveRangeShape, \

191 "freq of end block, normalized") \

192 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \

193 "hottest BB freq, normalized") \

194 M(float, liverange_size, PerLiveRangeShape, \

195 "size (instr index diff) of the LR") \

196 M(float, use_def_density, PerLiveRangeShape, \

197 "the max weight, as computed by the manual heuristic") \

198 M(int64_t, max_stage, PerLiveRangeShape, \

199 "largest stage of an interval in this LR") \

200 M(int64_t, min_stage, PerLiveRangeShape, \

201 "lowest stage of an interval in this LR") \

202 M(float, progress, {1}, "ratio of current queue size to initial size")

203

204

205

206

207

208#define DecisionName "index_to_evict"

211

212

214#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name

215#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),

217#undef _FEATURE_IDX

218#undef _FEATURE_IDX_SIMPLE

219};

220

221

222

223

224

225template size_t getTotalSize(const std::vector<int64_t> &Shape) {

226 size_t Ret = sizeof(T);

227 for (const auto V : Shape)

228 Ret *= V;

229 return Ret;

230}

231

233#define _RESET(TYPE, NAME, SHAPE, __) \

234 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \

235 getTotalSize(SHAPE));

237#undef _RESET

238}

239

240

241

242struct LIFeatureComponents {

243 double R = 0;

244 double W = 0;

245 double RW = 0;

246 double IndVarUpdates = 0;

247 double HintWeights = 0.0;

248 int64_t NumDefsAndUses = 0;

249 float HottestBlockFreq = 0.0;

250 bool IsRemat = false;

251};

252

253using CandidateRegList =

255using FeaturesListNormalizer =

257

258

260public:

264

265protected:

268 }

269

270

271

272 const MLModelRunner &getRunner() const { return *Runner; }

273

274

275

276

277

278 virtual int64_t

279 tryFindEvictionCandidatePosition(const LiveInterval &VirtReg,

281 unsigned OrderLimit, uint8_t CostPerUseLimit,

283

284

285

286 bool

291

292private:

293 static float getInitialQueueSize(const MachineFunction &MF);

294

299

302 int64_t IsHint, int64_t LocalIntfsCount, float NumUrgent,

304

305

306

310 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,

311 FixedRegisters);

312 }

313

314 const LIFeatureComponents &

315 getLIFeatureComponents(const LiveInterval &LI) const;

316

317

318

319

320

325

326

327

328 std::bitsetFeatureIDs::FeatureCount DoNotNormalize;

329 const float InitialQSize;

330

333

334 mutable std::unordered_map<unsigned, unsigned> VirtRegEvictionCounts;

335

336 void onEviction(Register RegBeingEvicted) const {

337

338

339

340 ++VirtRegEvictionCounts[RegBeingEvicted.id()];

341 }

342

343 unsigned getEvictionCount(Register Reg) const {

344 auto EvictionCountIt = VirtRegEvictionCounts.find(Reg.id());

345 if (EvictionCountIt != VirtRegEvictionCounts.end())

346 return EvictionCountIt->second;

347 return 0;

348 }

349};

350

351#define _DECL_FEATURES(type, name, shape, _) \

352 TensorSpec::createSpec(#name, shape),

353

354

355

356

357

358class ReleaseModeEvictionAdvisorProvider final

360public:

361 ReleaseModeEvictionAdvisorProvider(LLVMContext &Ctx)

364 }

365

367 return R->getAdvisorMode() == AdvisorMode::Release;

368 }

369

370 std::unique_ptr

373 if (!Runner) {

375 Runner = std::make_unique<ReleaseModeModelRunner>(

377 else

378 Runner = std::make_unique(

382 }

384 "Invalid provider state: must have analysis available");

385 return std::make_unique(MF, RA, Runner.get(), *MBFI,

387 }

388

389private:

391 std::unique_ptr Runner;

392};

393

394class ReleaseModeEvictionAdvisorAnalysisLegacy final

396public:

397 ReleaseModeEvictionAdvisorAnalysisLegacy()

399

402

403 }

404

406 Provider =

407 std::make_unique(M.getContext());

408 return false;

409 }

410

412 return R->getAdvisorMode() == AdvisorMode::Release;

413 }

414

419 }

420};

421

422

423

424

425

426

427#ifdef LLVM_HAVE_TFLITE

429

430

431

432

433

434#define _DECL_TRAIN_FEATURES(type, name, shape, _) \

435 TensorSpec::createSpec(std::string("action_") + #name, shape),

436

437class DevelopmentModeEvictAdvisor : public MLEvictAdvisor {

438public:

443 : MLEvictAdvisor(MF, RA, Runner, MBFI, Loops), Log(Log) {}

444

445private:

446 int64_t tryFindEvictionCandidatePosition(

448 unsigned OrderLimit, uint8_t CostPerUseLimit,

450

452};

453

454class DevelopmentModeEvictionAdvisorProvider final

456public:

457 DevelopmentModeEvictionAdvisorProvider(LLVMContext &Ctx)

460 TrainingInputFeatures = {

465 if (ModelUnderTraining.empty() && TrainingLog.empty()) {

466 Ctx.emitError("Regalloc development mode should be requested with at "

467 "least logging enabled and/or a training model");

468 return;

469 }

470 if (ModelUnderTraining.empty())

471 Runner = std::make_unique(Ctx, InputFeatures);

472 else

473 Runner = ModelUnderTrainingRunner::createAndEnsureValid(

474 Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures);

475 if (!Runner) {

476 Ctx.emitError("Regalloc: could not set up the model runner");

477 return;

478 }

479 if (TrainingLog.empty())

480 return;

481 std::error_code EC;

482 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);

483 if (EC) {

484 Ctx.emitError(EC.message() + ":" + TrainingLog);

485 return;

486 }

489 append_range(LFS, MUTR->extraOutputsForLoggingSpecs());

490

491

492

494

495 Log = std::make_unique(std::move(OS), LFS, Reward,

496 true);

497 return;

498 }

499

500

502 return R->getAdvisorMode() == AdvisorMode::Development;

503 }

504

507 if (!Log || !Log->hasAnyObservationForContext(MF.getName()))

508 return;

509

510

511

512

513 if (Log->currentContext() != MF.getName()) {

515 "The training log context shouldn't have had changed.");

516 }

517 if (Log->hasObservationInProgress())

518 Log->logReward<float>(GetReward());

519 }

520

521 std::unique_ptr

524 if (!Runner)

525 return nullptr;

526 if (Log)

527 Log->switchContext(MF.getName());

529 "Invalid provider state: must have analysis available");

530 return std::make_unique(

531 MF, RA, Runner.get(), *MBFI, *Loops, Log.get());

532 }

533

534private:

536 std::vector TrainingInputFeatures;

537

538 std::unique_ptr Runner;

539 std::unique_ptr Log;

540};

541

542class DevelopmentModeEvictionAdvisorAnalysisLegacy final

544public:

545 DevelopmentModeEvictionAdvisorAnalysisLegacy()

547

549 Provider = std::make_unique(

550 M.getContext());

551 return false;

552 }

553

556 Provider->logRewardIfNeeded(MF, GetReward);

557 }

558

559

561 return R->getAdvisorMode() == AdvisorMode::Development;

562 }

563

568 }

569};

570

571#endif

572}

573

574float MLEvictAdvisor::getInitialQueueSize(const MachineFunction &MF) {

576 unsigned NumUsedRegs = 0;

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

579 if (MRI.reg_nodbg_empty(Reg))

580 ++NumUsedRegs;

581 }

582 return static_cast<float>(NumUsedRegs);

583}

584

591 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {

592 assert(this->Runner);

594 DoNotNormalize.set(FeatureIDs::mask);

595 DoNotNormalize.set(FeatureIDs::is_free);

596 DoNotNormalize.set(FeatureIDs::is_hint);

597 DoNotNormalize.set(FeatureIDs::is_local);

598 DoNotNormalize.set(FeatureIDs::min_stage);

599 DoNotNormalize.set(FeatureIDs::max_stage);

600 DoNotNormalize.set(FeatureIDs::progress);

601}

602

603int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(

606 int64_t Ret = Runner->evaluate<int64_t>();

609 return Ret;

610}

611

612bool MLEvictAdvisor::loadInterferenceFeatures(

617

619

620 return false;

621 }

622

623 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);

624 int64_t LocalIntfs = 0;

625 float NumUrgent = 0.0f;

626

627

628 unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());

629

631 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

633

634

636 if (IFIntervals.empty() && InterferingIntervals.empty())

637 continue;

639 return false;

640 InterferingIntervals.append(IFIntervals.begin(), IFIntervals.end());

642 assert(Intf->reg().isVirtual() &&

643 "Only expecting virtual register interference from query");

644

645

646

647

648

649

650 if (FixedRegisters.count(Intf->reg()))

651 return false;

652 if (RA.getExtraInfo().getStage(*Intf) == RS_Done)

653 return false;

654 bool Urgent =

656 (Intf->isSpillable() ||

657 RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <

658 RegClassInfo.getNumAllocatableRegs(

659 MRI->getRegClass(Intf->reg())));

660

661 unsigned IntfCascade = RA.getExtraInfo().getCascade(Intf->reg());

662

663

664

665

666

667

668 if (getEvictionCount(Intf->reg()) > MaxEvictionCount && !Urgent)

669 return false;

670

671

672 if (Cascade <= IntfCascade) {

673 if (!Urgent)

674 return false;

675 ++NumUrgent;

676 }

677

678 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&

679 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));

680 }

681 }

682

683

684 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,

685 NumUrgent, LRPosInfo);

686 return true;

687}

688

689MCRegister MLEvictAdvisor::tryFindEvictionCandidate(

692 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);

693 if (!MaybeOrderLimit)

695 unsigned OrderLimit = *MaybeOrderLimit;

696

697

698

699

700

701

702

703 const bool MustFindEviction =

704 (!VirtReg.isSpillable() && CostPerUseLimit == static_cast<uint8_t>(~0u));

705

707

708

709 resetInputs(*Runner);

710

711

712

713

714 CandidateRegList Regs;

715 Regs.fill({0, false});

716

717

718

719

720

722

723

724

725

726

727

728 size_t Pos = 0;

731 ++I, ++Pos) {

733 assert(!Regs[Pos].second);

735 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {

736 continue;

737 }

738 if (loadInterferenceFeatures(VirtReg, PhysReg, I.isHint(), FixedRegisters,

739 Largest, Pos, LRPosInfo)) {

741 Regs[Pos] = std::make_pair(PhysReg, true);

742 }

743 }

745

746 assert(!MustFindEviction);

748 }

749 const size_t ValidPosLimit = Pos;

750

751

753 if (!MustFindEviction)

756 0,

757 0.0, LRPosInfo);

758 assert(InitialQSize > 0.0 && "We couldn't have gotten here if we had "

759 "nothing to allocate initially.");

760

761 for (auto &V : Largest)

762 V = V ? V : 1.0;

766 continue;

769 }

770 }

771 *Runner->getTensor<float>(FeatureIDs::progress) =

772 static_cast<float>(RA.getQueueSize()) / InitialQSize;

773

774

775 size_t CandidatePos = tryFindEvictionCandidatePosition(

776 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);

777

778

779 assert(Regs[CandidatePos].second);

781 onEviction(VirtReg.reg());

782 assert(!MustFindEviction);

784 }

785 assert(CandidatePos < ValidPosLimit);

786 (void)ValidPosLimit;

787

788

789

790

791 for (MCRegUnit Unit : TRI->regunits(Regs[CandidatePos].first)) {

795 onEviction(Intf->reg());

796 }

797 }

798

799 return Regs[CandidatePos].first;

800}

801

802const LIFeatureComponents &

803MLEvictAdvisor::getLIFeatureComponents(const LiveInterval &LI) const {

804 RegID ID = LI.reg().id();

805 LIFeatureComponents Empty;

806 auto I = CachedFeatures.insert(std::make_pair(ID, Empty));

807 LIFeatureComponents &Ret = I.first->getSecond();

808 if (I.second)

809 return Ret;

810

813

815 I = MRI->reg_instr_nodbg_begin(LI.reg()),

816 E = MRI->reg_instr_nodbg_end();

817 I != E;) {

819

820 ++Ret.NumDefsAndUses;

821 if (!Visited.insert(MI).second)

822 continue;

823

824 if (MI->isIdentityCopy() || MI->isImplicitDef())

825 continue;

826

827 bool Reads, Writes;

828 std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());

829

831 Ret.HottestBlockFreq = std::max(Freq, Ret.HottestBlockFreq);

832

833 Ret.R += (Reads && !Writes) * Freq;

834 Ret.W += (!Reads && Writes) * Freq;

835 Ret.RW += (Reads && Writes) * Freq;

836

837 auto *MBB = MI->getParent();

840

841 if (Writes && IsExiting && LIS->isLiveOutOfMBB(LI, MBB))

842 Ret.IndVarUpdates += Freq;

843

845 Ret.HintWeights += Freq;

846 }

849 return Ret;

850}

851

852

853

854void MLEvictAdvisor::extractFeatures(

857 int64_t LocalIntfsCount, float NumUrgent,

859 int64_t NumDefsAndUses = 0;

860 int64_t NumBrokenHints = 0;

861 double R = 0.0;

862 double W = 0.0;

863 double RW = 0.0;

864 double IndVarUpdates = 0.0;

865 double HintWeights = 0.0;

866 float StartBBFreq = 0.0;

867 float EndBBFreq = 0.0;

868 float HottestBlockFreq = 0.0;

869 int32_t NumRematerializable = 0;

870 float TotalWeight = 0.0;

871

872 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();

873 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();

874 int64_t MaxStage = 0;

875 int64_t MinStage =

876 Intervals.empty() ? 0 : std::numeric_limits<int64_t>::max();

877

878 for (const auto *L : Intervals) {

880 MaxStage = std::max<int64_t>(

881 MaxStage, static_cast<int64_t>(RA.getExtraInfo().getStage(LI)));

882 MinStage = std::min<int64_t>(

883 MinStage, static_cast<int64_t>(RA.getExtraInfo().getStage(LI)));

884

885 TotalWeight = std::max(TotalWeight, LI.weight());

886

889

892 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);

893 NumBrokenHints += VRM->hasPreferredPhys(LI.reg());

894

895 NumDefsAndUses += LIFC.NumDefsAndUses;

896 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);

897 R += LIFC.R;

898 W += LIFC.W;

899 RW += LIFC.RW;

900

901 IndVarUpdates += LIFC.IndVarUpdates;

902

903 HintWeights += LIFC.HintWeights;

904 NumRematerializable += LIFC.IsRemat;

905 }

906 size_t Size = 0;

907 if (!Intervals.empty()) {

908 StartBBFreq =

910 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())

911 EndSI = LIS->getSlotIndexes()->getLastIndex().getPrevIndex();

912 EndBBFreq =

915 }

916

917#define SET(ID, TYPE, VAL) \

918 do { \

919 Runner->getTensor(FeatureIDs::ID)[Pos] = static_cast(VAL); \

920 if (!DoNotNormalize.test(FeatureIDs::ID)) \

921 Largest[FeatureIDs::ID] = \

922 std::max(Largest[FeatureIDs::ID], static_cast(VAL)); \

923 } while (false)

925 SET(is_free, int64_t, Intervals.empty());

926 SET(nr_urgent, float, NumUrgent);

927 SET(nr_broken_hints, float, NumBrokenHints);

928 SET(is_hint, int64_t, IsHint);

929 SET(is_local, int64_t, LocalIntfsCount);

930 SET(nr_rematerializable, float, NumRematerializable);

931 SET(nr_defs_and_uses, float, NumDefsAndUses);

932 SET(weighed_reads_by_max, float, R);

933 SET(weighed_writes_by_max, float, W);

934 SET(weighed_read_writes_by_max, float, RW);

935 SET(weighed_indvars_by_max, float, IndVarUpdates);

936 SET(hint_weights_by_max, float, HintWeights);

937 SET(start_bb_freq_by_max, float, StartBBFreq);

938 SET(end_bb_freq_by_max, float, EndBBFreq);

939 SET(hottest_bb_freq_by_max, float, HottestBlockFreq);

940 SET(liverange_size, float, Size);

941 SET(use_def_density, float, TotalWeight);

942 SET(max_stage, int64_t, MaxStage);

943 SET(min_stage, int64_t, MinStage);

944#undef SET

945}

946

947

948#ifdef LLVM_HAVE_TFLITE

949

952 return new DevelopmentModeEvictionAdvisorAnalysisLegacy();

953}

954

955int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(

957 unsigned OrderLimit, uint8_t CostPerUseLimit,

959 int64_t Ret = 0;

961 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(

962 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);

963 } else {

964 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(

965 VirtReg, Order, CostPerUseLimit, FixedRegisters);

966

967

968

969 if (!PhysReg)

971 else

973 I != E; ++I, ++Ret)

974 if (*I == PhysReg)

975 break;

976 }

977 if (TrainingLog.empty())

978 return Ret;

979

980

981

982 if (Log->hasObservationInProgress())

983 Log->logReward<float>(0.0);

984

985 Log->startObservation();

986 size_t CurrentFeature = 0;

988 for (; CurrentFeature < FeatureCount; ++CurrentFeature) {

989 Log->logTensorValue(CurrentFeature,

990 reinterpret_cast<const char *>(

991 getRunner().getTensorUntyped(CurrentFeature)));

992 }

994 for (size_t I = 0; I < MUTR->extraOutputsForLoggingSpecs().size();

995 ++I, ++CurrentFeature)

996 Log->logTensorValue(

997 CurrentFeature,

998 reinterpret_cast<const char *>(MUTR->getUntypedExtraOutputValue(I)));

999

1000 Log->logTensorValue(CurrentFeature, reinterpret_cast<const char *>(&Ret));

1001 Log->endObservation();

1002 return Ret;

1003}

1004

1005bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) {

1006 std::optional CachedReward;

1007 auto GetReward = [&]() {

1008 if (!CachedReward)

1009 CachedReward = static_cast<float>(

1011 MF, getAnalysis().getMBFI())

1013 return *CachedReward;

1014 };

1015

1016 getAnalysis().logRewardIfNeeded(

1017 MF, GetReward);

1018 getAnalysis().logRewardIfNeeded(

1019 MF, GetReward);

1020 return false;

1021}

1022#endif

1023

1024RegAllocEvictionAdvisorProvider *

1026 return new ReleaseModeEvictionAdvisorProvider(Ctx);

1027}

1028

1031#if defined(LLVM_HAVE_TFLITE)

1032 return new DevelopmentModeEvictionAdvisorProvider(Ctx);

1033#endif

1034 return nullptr;

1035}

1036

1041 ? new ReleaseModeEvictionAdvisorAnalysisLegacy()

1042 : nullptr;

1043}

1044

1045

1046#if !defined(LLVM_HAVE_TFLITE)

1047bool RegAllocScoring::runOnMachineFunction(MachineFunction &) { return false; }

1048#endif

unsigned const MachineRegisterInfo * MRI

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

static constexpr unsigned long long mask(BlockVerifier::State S)

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

@ Available

We know the block is fully available. This is a fixpoint.

Module.h This file contains the declarations for the Module class.

NoopSavedModelImpl CompiledModelType

static cl::opt< std::string > InteractiveChannelBaseName("inliner-interactive-channel-base", cl::Hidden, cl::desc("Base file path for the interactive mode. The incoming filename should " "have the name .in, while the " "outgoing name should be .out"))

static cl::opt< unsigned > MaxEvictionCount("mlregalloc-max-eviction-count", cl::Hidden, cl::desc("The maximum number of times a live range can be " "evicted before preventing it from being evicted"), cl::init(100))

#define RA_EVICT_FEATURES_LIST(M)

#define SET(ID, TYPE, VAL)

#define _RESET(TYPE, NAME, SHAPE, __)

static cl::opt< std::string > InteractiveChannelBaseName("regalloc-evict-interactive-channel-base", cl::Hidden, cl::desc("Base file path for the interactive mode. The incoming filename should " "have the name .in, while the " "outgoing name should be " ".out"))

#define _FEATURE_IDX(A, B, C, D)

#define _DECL_FEATURES(type, name, shape, _)

Register const TargetRegisterInfo * TRI

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

SI optimize exec mask operations pre RA

LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty

Iterator getOrderLimitEnd(unsigned OrderLimit) const

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

void setPreservesAll()

Set by analyses that do not transform their input at all.

FunctionPass class - This class is used to implement most global optimizations.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

This is an important class for using LLVM in a threaded context.

LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)

emitError - Emit an error message to the currently installed error handler with optional location inf...

Query interferences between a single live virtual register and a live interval union.

const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())

LiveInterval - This class represents the liveness of a register, or stack slot.

bool isSpillable() const

isSpillable - Can this interval be spilled?

SlotIndex beginIndex() const

beginIndex - Return the lowest numbered slot covered.

SlotIndex endIndex() const

endNumber - return the maximum point of the range of the whole, exclusive.

@ IK_VirtReg

Virtual register interference.

Logging utility - given an ordered specification of features, and assuming a scalar reward,...

bool isLoopExiting(const BlockT *BB) const

True if terminator in the block can branch to another block that is outside of the current loop.

Represents a single loop in the control flow graph.

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

static constexpr unsigned NoRegister

MLModelRunner interface: abstraction of a mechanism for evaluating a ML model.

virtual void switchContext(StringRef Name)

T * getTensor(I FeatureID)

MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...

double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const

Compute the frequency of the block, relative to the entry block.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

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.

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

defusechain_instr_iterator< true, true, true, true > reg_instr_nodbg_iterator

reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk all defs and uses of the sp...

A Module instance is used to store all the information related to an LLVM module.

A mock class satisfying the interface expected by ReleaseModeModelRunner for its TGen parameter.

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

virtual bool doInitialization(Module &)

doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...

ImmutableAnalysis abstraction for fetching the Eviction Advisor.

virtual void logRewardIfNeeded(const MachineFunction &MF, function_ref< float()> GetReward)

RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode Mode)

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

Common provider for legacy and new pass managers.

virtual std::unique_ptr< RegAllocEvictionAdvisor > getAdvisor(const MachineFunction &MF, const RAGreedy &RA, MachineBlockFrequencyInfo *MBFI, MachineLoopInfo *Loops)=0

virtual void logRewardIfNeeded(const MachineFunction &MF, llvm::function_ref< float()> GetReward)

RegAllocEvictionAdvisorProvider(AdvisorMode Mode, LLVMContext &Ctx)

virtual bool canEvictHintInterference(const LiveInterval &VirtReg, MCRegister PhysReg, const SmallVirtRegSet &FixedRegisters) const =0

Find out if we can evict the live ranges occupying the given PhysReg, which is a hint (preferred regi...

virtual MCRegister tryFindEvictionCandidate(const LiveInterval &VirtReg, const AllocationOrder &Order, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const =0

Find a physical register that can be freed by evicting the FixedRegisters, or return NoRegister.

LLVM_ABI_FOR_TEST double getScore() const

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

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

constexpr unsigned id() const

SlotIndex - An opaque wrapper around machine indexes.

int distance(SlotIndex other) const

Return the distance from this index to the given one.

SlotIndex getPrevIndex() const

Returns the previous index.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

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

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

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

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

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

static TensorSpec createSpec(const std::string &Name, const std::vector< int64_t > &Shape, int Port=0)

static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)

Determine if all values in LI are rematerializable.

static Register copyHint(const MachineInstr *MI, Register Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)

Return the preferred allocation register for reg, given a COPY instruction.

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

bool isEmbeddedModelEvaluatorValid()

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.

SmallSet< Register, 16 > SmallVirtRegSet

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()

Definition MLRegAllocEvictAdvisor.cpp:1038

RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)

Definition MLRegAllocEvictAdvisor.cpp:1030

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

static const TensorSpec DecisionSpec

RegAllocScore calculateRegAllocScore(const MachineFunction &MF, const MachineBlockFrequencyInfo &MBFI)

Calculate a score.

auto reverse(ContainerTy &&C)

LLVM_ABI void initializeRegAllocScoringPass(PassRegistry &)

static const std::vector< TensorSpec > InputFeatures

@ RS_Done

There is nothing more we can do to this live range.

LLVM_ABI FunctionPass * createRegAllocScoringPass()

When learning an eviction policy, extract score(reward) information, otherwise this does nothing.

Definition MLRegAllocEvictAdvisor.cpp:125

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

cl::opt< unsigned > EvictInterferenceCutoff

OutputIt move(R &&Range, OutputIt Out)

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

LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider * createReleaseModeAdvisorProvider(LLVMContext &Ctx)

Definition MLRegAllocEvictAdvisor.cpp:1025

static const int64_t NumberOfInterferences

static const std::vector< int64_t > PerLiveRangeShape

RegAllocEvictionAdvisorAnalysisLegacy * createDevelopmentModeAdvisorAnalysisLegacy()

static const int64_t CandidateVirtRegPos

Implement std::hash so that hash_code can be used in STL containers.