19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)
45#include <unordered_map>
49#define DEBUG_TYPE "ml-regalloc"
52#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)
53#include "RegAllocEvictModel.h"
60 "regalloc-evict-interactive-channel-base",
cl::Hidden,
62 "Base file path for the interactive mode. The incoming filename should "
63 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
64 "outgoing name should be "
65 "<regalloc-evict-interactive-channel-base>.out"));
69 cl::desc(
"The maximum number of times a live range can be "
70 "evicted before preventing it from being evicted"),
74#ifdef LLVM_HAVE_TFLITE
80 cl::desc(
"Training log for the register allocator eviction model"));
84 cl::desc(
"The model being trained for register allocation eviction"));
87 "regalloc-enable-development-features",
cl::Hidden,
88 cl::desc(
"Whether or not to enable features under development for the ML "
107 RegAllocScoring() : MachineFunctionPass(ID) {
111 ~RegAllocScoring()
override =
default;
113 StringRef getPassName()
const override {
114 return "Register Allocation Pass Scoring";
118 void getAnalysisUsage(AnalysisUsage &AU)
const override {
120 AU.
addRequired<RegAllocEvictionAdvisorAnalysisLegacy>();
121 AU.
addRequired<RegAllocPriorityAdvisorAnalysisLegacy>();
122 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
127 bool runOnMachineFunction(MachineFunction &)
override;
131char RegAllocScoring::ID = 0;
133 return new RegAllocScoring();
137 "Register Allocation Scoring Pass",
false,
false)
145static const int OpcodeValueCutoff = 17716;
169#define RA_EVICT_FEATURES_LIST(M) \
170 M(int64_t, mask, PerLiveRangeShape, \
171 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
173 "can't be evicted)") \
174 M(int64_t, is_free, PerLiveRangeShape, \
175 "boolean values, 1 if this phys reg is actually free (no interferences)") \
176 M(float, nr_urgent, PerLiveRangeShape, \
177 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
178 "to break cascades") \
179 M(float, nr_broken_hints, PerLiveRangeShape, \
180 "if this position were evicted, how many broken hints would there be") \
181 M(int64_t, is_hint, PerLiveRangeShape, \
182 "is this a preferred phys reg for the candidate") \
183 M(int64_t, is_local, PerLiveRangeShape, \
184 "is this live range local to a basic block") \
185 M(float, nr_rematerializable, PerLiveRangeShape, \
186 "nr rematerializable ranges") \
187 M(float, nr_defs_and_uses, PerLiveRangeShape, \
188 "bb freq - weighed nr defs and uses") \
189 M(float, weighed_reads_by_max, PerLiveRangeShape, \
190 "bb freq - weighed nr of reads, normalized") \
191 M(float, weighed_writes_by_max, PerLiveRangeShape, \
192 "bb feq - weighed nr of writes, normalized") \
193 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
194 "bb freq - weighed nr of uses that are both read and writes, normalized") \
195 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
196 "bb freq - weighed nr of uses that are indvars, normalized") \
197 M(float, hint_weights_by_max, PerLiveRangeShape, \
198 "bb freq - weighed nr of uses that are hints, normalized") \
199 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
200 "the freq in the start block, normalized") \
201 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
202 "freq of end block, normalized") \
203 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
204 "hottest BB freq, normalized") \
205 M(float, liverange_size, PerLiveRangeShape, \
206 "size (instr index diff) of the LR") \
207 M(float, use_def_density, PerLiveRangeShape, \
208 "the max weight, as computed by the manual heuristic") \
209 M(int64_t, max_stage, PerLiveRangeShape, \
210 "largest stage of an interval in this LR") \
211 M(int64_t, min_stage, PerLiveRangeShape, \
212 "lowest stage of an interval in this LR") \
213 M(float, progress, {1}, "ratio of current queue size to initial size")
215#ifdef LLVM_HAVE_TFLITE
216#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M) \
217 M(int64_t, instructions, InstructionsShape, \
218 "Opcodes of the instructions covered by the eviction problem")
220#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M) \
221 M(int64_t, instructions_mapping, InstructionsMappingShape, \
222 "A binary matrix mapping LRs to instruction opcodes") \
223 M(float, mbb_frequencies, MBBFrequencyShape, \
224 "A vector of machine basic block frequencies") \
225 M(int64_t, mbb_mapping, InstructionsShape, \
226 "A vector of indices mapping instructions to MBBs")
228#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
229#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
236#define DecisionName "index_to_evict"
242#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
243#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
245#ifdef LLVM_HAVE_TFLITE
252#undef _FEATURE_IDX_SIMPLE
259template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
260 size_t Ret =
sizeof(
T);
261 for (
const auto V : Shape)
267#define _RESET(TYPE, NAME, SHAPE, __) \
268 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
269 getTotalSize<TYPE>(SHAPE));
280struct LIFeatureComponents {
284 double IndVarUpdates = 0;
285 double HintWeights = 0.0;
286 int64_t NumDefsAndUses = 0;
287 float HottestBlockFreq = 0.0;
288 bool IsRemat =
false;
291using CandidateRegList =
293using FeaturesListNormalizer =
317 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
319 unsigned OrderLimit,
uint8_t CostPerUseLimit,
340 int64_t IsHint, int64_t LocalIntfsCount,
float NumUrgent,
348 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
352 const LIFeatureComponents &
366 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
367 const float InitialQSize;
372 mutable std::unordered_map<unsigned, unsigned> VirtRegEvictionCounts;
374 void onEviction(
Register RegBeingEvicted)
const {
378 ++VirtRegEvictionCounts[RegBeingEvicted.
id()];
382 auto EvictionCountIt = VirtRegEvictionCounts.find(
Reg.id());
383 if (EvictionCountIt != VirtRegEvictionCounts.end())
384 return EvictionCountIt->second;
389#define _DECL_FEATURES(type, name, shape, _) \
390 TensorSpec::createSpec<type>(#name, shape),
396class ReleaseModeEvictionAdvisorProvider final
399 ReleaseModeEvictionAdvisorProvider(
LLVMContext &Ctx)
411 return R->getAdvisorMode() == AdvisorMode::Release;
414 std::unique_ptr<RegAllocEvictionAdvisor>
419 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
422 Runner = std::make_unique<InteractiveModelRunner>(
428 "Invalid provider state: must have analysis available");
429 return std::make_unique<MLEvictAdvisor>(MF,
RA, Runner.get(), *MBFI,
435 std::unique_ptr<MLModelRunner> Runner;
438class ReleaseModeEvictionAdvisorAnalysisLegacy final
441 ReleaseModeEvictionAdvisorAnalysisLegacy()
451 std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
456 return R->getAdvisorMode() == AdvisorMode::Release;
471#ifdef LLVM_HAVE_TFLITE
478#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
479 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
481class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
487 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
490 int64_t tryFindEvictionCandidatePosition(
492 unsigned OrderLimit,
uint8_t CostPerUseLimit,
498class DevelopmentModeEvictionAdvisorProvider final
501 DevelopmentModeEvictionAdvisorProvider(
LLVMContext &Ctx)
507 TrainingInputFeatures = {
516 TrainingInputFeatures = {
522 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
523 Ctx.emitError(
"Regalloc development mode should be requested with at "
524 "least logging enabled and/or a training model");
527 if (ModelUnderTraining.empty())
528 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
530 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
531 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
533 Ctx.emitError(
"Regalloc: could not set up the model runner");
536 if (TrainingLog.empty())
539 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
541 Ctx.emitError(EC.message() +
":" + TrainingLog);
552 Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
559 return R->getAdvisorMode() == AdvisorMode::Development;
564 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
570 if (Log->currentContext() != MF.
getName()) {
572 "The training log context shouldn't have had changed.");
574 if (Log->hasObservationInProgress())
575 Log->logReward<
float>(GetReward());
578 std::unique_ptr<RegAllocEvictionAdvisor>
584 Log->switchContext(MF.
getName());
586 "Invalid provider state: must have analysis available");
587 return std::make_unique<DevelopmentModeEvictAdvisor>(
588 MF,
RA, Runner.get(), *MBFI, *
Loops, Log.get());
593 std::vector<TensorSpec> TrainingInputFeatures;
595 std::unique_ptr<MLModelRunner> Runner;
596 std::unique_ptr<Logger> Log;
599class DevelopmentModeEvictionAdvisorAnalysisLegacy final
602 DevelopmentModeEvictionAdvisorAnalysisLegacy()
606 Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
613 Provider->logRewardIfNeeded(MF, GetReward);
618 return R->getAdvisorMode() == AdvisorMode::Development;
633 unsigned NumUsedRegs = 0;
634 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
636 if (!
MRI.reg_nodbg_empty(
Reg))
639 return static_cast<float>(NumUsedRegs);
648 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
651 DoNotNormalize.set(FeatureIDs::mask);
652 DoNotNormalize.set(FeatureIDs::is_free);
653 DoNotNormalize.set(FeatureIDs::is_hint);
654 DoNotNormalize.set(FeatureIDs::is_local);
655 DoNotNormalize.set(FeatureIDs::min_stage);
656 DoNotNormalize.set(FeatureIDs::max_stage);
657 DoNotNormalize.set(FeatureIDs::progress);
660int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
669bool MLEvictAdvisor::loadInterferenceFeatures(
680 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
681 int64_t LocalIntfs = 0;
682 float NumUrgent = 0.0f;
685 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
693 if (IFIntervals.empty() && InterferingIntervals.
empty())
697 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
699 assert(Intf->reg().isVirtual() &&
700 "Only expecting virtual register interference from query");
707 if (FixedRegisters.
count(Intf->reg()))
709 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
713 (Intf->isSpillable() ||
714 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
715 RegClassInfo.getNumAllocatableRegs(
716 MRI->getRegClass(Intf->reg())));
718 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
729 if (Cascade <= IntfCascade) {
735 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
736 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
741 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
742 NumUrgent, LRPosInfo);
746MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
749 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
750 if (!MaybeOrderLimit)
752 unsigned OrderLimit = *MaybeOrderLimit;
760 const bool MustFindEviction =
766 resetInputs(*Runner);
771 CandidateRegList Regs;
772 Regs.fill({0,
false});
790 assert(!Regs[Pos].second);
792 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
795 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
796 Largest, Pos, LRPosInfo)) {
798 Regs[Pos] = std::make_pair(PhysReg,
true);
803 assert(!MustFindEviction);
806 const size_t ValidPosLimit = Pos;
810 if (!MustFindEviction)
815 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
816 "nothing to allocate initially.");
817#ifdef LLVM_HAVE_TFLITE
822 auto *CurrentMachineInstruction =
823 LIS->getInstructionFromIndex(InputIndex);
824 if (!CurrentMachineInstruction) {
827 return CurrentMachineInstruction->getOpcode();
830 auto *CurrentMachineInstruction =
831 LIS->getInstructionFromIndex(InputIndex);
833 CurrentMachineInstruction->getParent());
836 auto *CurrentMachineInstruction =
837 LIS->getInstructionFromIndex(InputIndex);
838 return CurrentMachineInstruction->getParent();
840 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
841 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
842 LIS->getSlotIndexes()->getLastIndex());
846 for (
auto &V : Largest)
856 *Runner->
getTensor<
float>(FeatureIDs::progress) =
857 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
860 size_t CandidatePos = tryFindEvictionCandidatePosition(
861 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
864 assert(Regs[CandidatePos].second);
866 onEviction(VirtReg.
reg());
867 assert(!MustFindEviction);
870 assert(CandidatePos < ValidPosLimit);
876 for (
MCRegUnit Unit :
TRI->regunits(Regs[CandidatePos].first)) {
880 onEviction(Intf->reg());
884 return Regs[CandidatePos].first;
887const LIFeatureComponents &
888MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
890 LIFeatureComponents
Empty;
891 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
892 LIFeatureComponents &
Ret =
I.first->getSecond();
900 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
901 E =
MRI->reg_instr_nodbg_end();
905 ++
Ret.NumDefsAndUses;
909 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
913 std::tie(Reads, Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
916 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
918 Ret.R += (Reads && !Writes) * Freq;
919 Ret.W += (!Reads && Writes) * Freq;
920 Ret.RW += (Reads && Writes) * Freq;
922 auto *
MBB =
MI->getParent();
926 if (Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
927 Ret.IndVarUpdates += Freq;
930 Ret.HintWeights += Freq;
939void MLEvictAdvisor::extractFeatures(
942 int64_t LocalIntfsCount,
float NumUrgent,
944 int64_t NumDefsAndUses = 0;
945 int64_t NumBrokenHints = 0;
949 double IndVarUpdates = 0.0;
950 double HintWeights = 0.0;
951 float StartBBFreq = 0.0;
952 float EndBBFreq = 0.0;
953 float HottestBlockFreq = 0.0;
954 int32_t NumRematerializable = 0;
955 float TotalWeight = 0.0;
957 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
958 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
959 int64_t MaxStage = 0;
961 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
963 for (
const auto *L : Intervals) {
965 MaxStage = std::max<int64_t>(
966 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
967 MinStage = std::min<int64_t>(
968 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
970 TotalWeight = std::max(TotalWeight, LI.
weight());
977 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
978 NumBrokenHints += VRM->hasPreferredPhys(LI.
reg());
980 NumDefsAndUses += LIFC.NumDefsAndUses;
981 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
986 IndVarUpdates += LIFC.IndVarUpdates;
988 HintWeights += LIFC.HintWeights;
989 NumRematerializable += LIFC.IsRemat;
992 for (
auto CurrentSegment : LI) {
999 if (!Intervals.empty()) {
1002 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
1003 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
1009#define SET(ID, TYPE, VAL) \
1011 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
1012 if (!DoNotNormalize.test(FeatureIDs::ID)) \
1013 Largest[FeatureIDs::ID] = \
1014 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
1017 SET(is_free, int64_t, Intervals.empty());
1018 SET(nr_urgent,
float, NumUrgent);
1019 SET(nr_broken_hints,
float, NumBrokenHints);
1020 SET(is_hint, int64_t, IsHint);
1021 SET(is_local, int64_t, LocalIntfsCount);
1022 SET(nr_rematerializable,
float, NumRematerializable);
1023 SET(nr_defs_and_uses,
float, NumDefsAndUses);
1024 SET(weighed_reads_by_max,
float, R);
1025 SET(weighed_writes_by_max,
float, W);
1026 SET(weighed_read_writes_by_max,
float, RW);
1027 SET(weighed_indvars_by_max,
float, IndVarUpdates);
1028 SET(hint_weights_by_max,
float, HintWeights);
1029 SET(start_bb_freq_by_max,
float, StartBBFreq);
1030 SET(end_bb_freq_by_max,
float, EndBBFreq);
1031 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
1032 SET(liverange_size,
float,
Size);
1033 SET(use_def_density,
float, TotalWeight);
1034 SET(max_stage, int64_t, MaxStage);
1035 SET(min_stage, int64_t, MinStage);
1044 const int InstructionsIndex,
const int InstructionsMappingIndex,
1045 const int MBBFreqIndex,
const int MBBMappingIndex,
1063 LRPosInfo.
begin(), LRPosInfo.
end(),
1065 size_t InstructionIndex = 0;
1066 size_t CurrentSegmentIndex = 0;
1067 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
1068 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
1069 size_t CurrentMBBIndex = 0;
1081 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].End &&
1083 int CurrentOpcode = GetOpcode(CurrentIndex);
1085 if (CurrentOpcode == -1) {
1088 if (CurrentIndex >= LastIndex) {
1095 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1096 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1100 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1101 MBBFreqIndex, MBBMappingIndex);
1103 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1104 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1105 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1107 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1109 InstructionsMappingIndex)[CurrentSegmentPosition *
1111 InstructionIndex] = 1;
1120 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1121 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1122 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1123 auto OverlapCurrentSegmentPosition =
1124 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1125 if (LRPosInfo[OverlapCheckCurrentSegment].End >= CurrentIndex) {
1127 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1129 InstructionIndex] = 1;
1131 ++OverlapCheckCurrentSegment;
1134 if (CurrentIndex >= LastIndex) {
1141 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1148 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1149 LRPosInfo[CurrentSegmentIndex].End) {
1150 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1152 ++CurrentSegmentIndex;
1157 const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
1158 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1161 const int MBBFreqIndex,
const int MBBMappingIndex) {
1162 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1163 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1165 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1168 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1173#ifdef LLVM_HAVE_TFLITE
1177 return new DevelopmentModeEvictionAdvisorAnalysisLegacy();
1180int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1182 unsigned OrderLimit,
uint8_t CostPerUseLimit,
1186 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1187 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1189 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1190 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1202 if (TrainingLog.empty())
1207 if (Log->hasObservationInProgress())
1208 Log->logReward<
float>(0.0);
1210 Log->startObservation();
1211 size_t CurrentFeature = 0;
1213 ? FeatureIDs::FeaturesWithDevelopmentCount
1215 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1216 Log->logTensorValue(CurrentFeature,
1217 reinterpret_cast<const char *
>(
1218 getRunner().getTensorUntyped(CurrentFeature)));
1221 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().
size();
1222 ++
I, ++CurrentFeature)
1223 Log->logTensorValue(
1225 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1227 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1228 Log->endObservation();
1233 std::optional<float> CachedReward;
1234 auto GetReward = [&]() {
1236 CachedReward =
static_cast<float>(
1238 MF, getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI())
1240 return *CachedReward;
1243 getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().logRewardIfNeeded(
1245 getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().logRewardIfNeeded(
1251RegAllocEvictionAdvisorProvider *
1253 return new ReleaseModeEvictionAdvisorProvider(Ctx);
1258#if defined(LLVM_HAVE_TFLITE)
1259 return new DevelopmentModeEvictionAdvisorProvider(Ctx);
1268 ?
new ReleaseModeEvictionAdvisorAnalysisLegacy()
1273#if !defined(LLVM_HAVE_TFLITE)
1274bool RegAllocScoring::runOnMachineFunction(
MachineFunction &) {
return false; }
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-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 <inliner-interactive-channel-base>.in, while the " "outgoing name should be <inliner-interactive-channel-base>.out"))
static const bool EnableDevelopmentFeatures
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 _FEATURE_IDX_SIMPLE(_, name, __, ___)
#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
#define SET(ID, TYPE, VAL)
#define _RESET(TYPE, NAME, SHAPE, __)
#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
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 <regalloc-evict-interactive-channel-base>.in, while the " "outgoing name should be " "<regalloc-evict-interactive-channel-base>.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.
SlotIndex getNextIndex() const
Returns the next index.
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.
void push_back(const T &Elt)
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()
static const int ModelMaxSupportedInstructionCount
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<X> - Return the argument parameter cast to the specified type.
RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()
static const int64_t ModelMaxSupportedMBBCount
RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI_FOR_TEST void extractInstructionFeatures(llvm::SmallVectorImpl< LRStartEndInfo > &LRPosInfo, MLModelRunner *RegallocRunner, function_ref< int(SlotIndex)> GetOpcode, function_ref< float(SlotIndex)> GetMBBFreq, function_ref< MachineBasicBlock *(SlotIndex)> GetMBBReference, const int InstructionsIndex, const int InstructionsMappingIndex, const int MBBFreqIndex, const int MBBMappingIndex, const SlotIndex LastIndex)
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.
unsigned MCRegUnit
Register units are used to compute register aliasing.
LLVM_ABI FunctionPass * createRegAllocScoringPass()
When learning an eviction policy, extract score(reward) information, otherwise this does nothing.
bool isa(const From &Val)
isa<X> - 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)
LLVM_ABI_FOR_TEST void extractMBBFrequency(const SlotIndex CurrentIndex, const size_t CurrentInstructionIndex, std::map< MachineBasicBlock *, size_t > &VisitedMBBs, function_ref< float(SlotIndex)> GetMBBFreq, MachineBasicBlock *CurrentMBBReference, MLModelRunner *RegallocRunner, const int MBBFreqIndex, const int MBBMappingIndex)
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.