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 (.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 {
805 LIFeatureComponents Empty;
806 auto I = CachedFeatures.insert(std::make_pair(ID, Empty));
807 LIFeatureComponents &Ret = I.first->getSecond();
808 if (.second)
809 return Ret;
810
813
815 I = MRI->reg_instr_nodbg_begin(LI.reg()),
816 E = MRI->reg_instr_nodbg_end();
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
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.