19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)
48#define DEBUG_TYPE "ml-regalloc"
51#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)
52#include "RegAllocEvictModel.h"
59 "regalloc-evict-interactive-channel-base",
cl::Hidden,
61 "Base file path for the interactive mode. The incoming filename should "
62 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
63 "outgoing name should be "
64 "<regalloc-evict-interactive-channel-base>.out"));
67#ifdef LLVM_HAVE_TFLITE
73 cl::desc(
"Training log for the register allocator eviction model"));
77 cl::desc(
"The model being trained for register allocation eviction"));
80 "regalloc-enable-development-features",
cl::Hidden,
81 cl::desc(
"Whether or not to enable features under development for the ML "
105 return "Register Allocation Pass Scoring";
127 "Register Allocation Scoring Pass",
false,
false)
135static const int OpcodeValueCutoff = 17716;
159#define RA_EVICT_FEATURES_LIST(M) \
160 M(int64_t, mask, PerLiveRangeShape, \
161 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
163 "can't be evicted)") \
164 M(int64_t, is_free, PerLiveRangeShape, \
165 "boolean values, 1 if this phys reg is actually free (no interferences)") \
166 M(float, nr_urgent, PerLiveRangeShape, \
167 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
168 "to break cascades") \
169 M(float, nr_broken_hints, PerLiveRangeShape, \
170 "if this position were evicted, how many broken hints would there be") \
171 M(int64_t, is_hint, PerLiveRangeShape, \
172 "is this a preferred phys reg for the candidate") \
173 M(int64_t, is_local, PerLiveRangeShape, \
174 "is this live range local to a basic block") \
175 M(float, nr_rematerializable, PerLiveRangeShape, \
176 "nr rematerializable ranges") \
177 M(float, nr_defs_and_uses, PerLiveRangeShape, \
178 "bb freq - weighed nr defs and uses") \
179 M(float, weighed_reads_by_max, PerLiveRangeShape, \
180 "bb freq - weighed nr of reads, normalized") \
181 M(float, weighed_writes_by_max, PerLiveRangeShape, \
182 "bb feq - weighed nr of writes, normalized") \
183 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
184 "bb freq - weighed nr of uses that are both read and writes, normalized") \
185 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
186 "bb freq - weighed nr of uses that are indvars, normalized") \
187 M(float, hint_weights_by_max, PerLiveRangeShape, \
188 "bb freq - weighed nr of uses that are hints, normalized") \
189 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
190 "the freq in the start block, normalized") \
191 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
192 "freq of end block, normalized") \
193 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
194 "hottest BB freq, normalized") \
195 M(float, liverange_size, PerLiveRangeShape, \
196 "size (instr index diff) of the LR") \
197 M(float, use_def_density, PerLiveRangeShape, \
198 "the max weight, as computed by the manual heuristic") \
199 M(int64_t, max_stage, PerLiveRangeShape, \
200 "largest stage of an interval in this LR") \
201 M(int64_t, min_stage, PerLiveRangeShape, \
202 "lowest stage of an interval in this LR") \
203 M(float, progress, {1}, "ratio of current queue size to initial size")
205#ifdef LLVM_HAVE_TFLITE
206#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M) \
207 M(int64_t, instructions, InstructionsShape, \
208 "Opcodes of the instructions covered by the eviction problem")
210#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M) \
211 M(int64_t, instructions_mapping, InstructionsMappingShape, \
212 "A binary matrix mapping LRs to instruction opcodes") \
213 M(float, mbb_frequencies, MBBFrequencyShape, \
214 "A vector of machine basic block frequencies") \
215 M(int64_t, mbb_mapping, InstructionsShape, \
216 "A vector of indices mapping instructions to MBBs")
218#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
219#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
226#define DecisionName "index_to_evict"
232#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
233#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
235#ifdef LLVM_HAVE_TFLITE
242#undef _FEATURE_IDX_SIMPLE
249template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
250 size_t Ret =
sizeof(
T);
251 for (
const auto V : Shape)
257#define _RESET(TYPE, NAME, SHAPE, __) \
258 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
259 getTotalSize<TYPE>(SHAPE));
270struct LIFeatureComponents {
274 double IndVarUpdates = 0;
275 double HintWeights = 0.0;
276 int64_t NrDefsAndUses = 0;
277 float HottestBlockFreq = 0.0;
278 bool IsRemat =
false;
281using CandidateRegList =
283using FeaturesListNormalizer =
307 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
309 unsigned OrderLimit, uint8_t CostPerUseLimit,
325 uint8_t CostPerUseLimit,
330 int64_t IsHint, int64_t LocalIntfsCount,
float NrUrgent,
338 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
342 const LIFeatureComponents &
356 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
357 const float InitialQSize;
363#define _DECL_FEATURES(type, name, shape, _) \
364 TensorSpec::createSpec<type>(#name, shape),
369class ReleaseModeEvictionAdvisorAnalysis final
372 ReleaseModeEvictionAdvisorAnalysis()
396 std::unique_ptr<RegAllocEvictionAdvisor>
400 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
403 Runner = std::make_unique<InteractiveModelRunner>(
408 return std::make_unique<MLEvictAdvisor>(
409 MF,
RA, Runner.get(),
410 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI(),
411 getAnalysis<MachineLoopInfoWrapperPass>().getLI());
413 std::unique_ptr<MLModelRunner> Runner;
421#ifdef LLVM_HAVE_TFLITE
422static const TensorSpec Reward = TensorSpec::createSpec<float>(
"reward", {1});
428#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
429 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
431class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
437 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
440 int64_t tryFindEvictionCandidatePosition(
442 unsigned OrderLimit, uint8_t CostPerUseLimit,
448class DevelopmentModeEvictionAdvisorAnalysis final
451 DevelopmentModeEvictionAdvisorAnalysis()
457 TrainingInputFeatures = {
461 TensorSpec::createSpec<float>(
"action_discount", {1}),
462 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
463 TensorSpec::createSpec<float>(
"action_reward", {1})};
466 TrainingInputFeatures = {
468 TensorSpec::createSpec<float>(
"action_discount", {1}),
469 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
470 TensorSpec::createSpec<float>(
"action_reward", {1})};
480 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
486 if (Log->currentContext() != MF.
getName()) {
488 "The training log context shouldn't have had changed.");
490 if (Log->hasObservationInProgress())
491 Log->logReward<
float>(GetReward());
496 std::vector<TensorSpec> TrainingInputFeatures;
506 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
507 Ctx.
emitError(
"Regalloc development mode should be requested with at "
508 "least logging enabled and/or a training model");
511 if (ModelUnderTraining.empty())
512 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
514 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
515 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
517 Ctx.
emitError(
"Regalloc: could not set up the model runner");
520 if (TrainingLog.empty())
523 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
525 M.getContext().emitError(EC.message() +
":" + TrainingLog);
529 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
536 Log = std::make_unique<Logger>(std::move(
OS), LFS, Reward,
541 std::unique_ptr<RegAllocEvictionAdvisor>
546 Log->switchContext(MF.
getName());
547 return std::make_unique<DevelopmentModeEvictAdvisor>(
548 MF,
RA, Runner.get(),
549 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI(),
550 getAnalysis<MachineLoopInfoWrapperPass>().getLI(), Log.get());
553 std::unique_ptr<MLModelRunner> Runner;
554 std::unique_ptr<Logger> Log;
563 for (
unsigned I = 0, E =
MRI.getNumVirtRegs();
I != E; ++
I) {
565 if (
MRI.reg_nodbg_empty(Reg))
578 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
581 DoNotNormalize.set(FeatureIDs::mask);
582 DoNotNormalize.set(FeatureIDs::is_free);
583 DoNotNormalize.set(FeatureIDs::is_hint);
584 DoNotNormalize.set(FeatureIDs::is_local);
585 DoNotNormalize.set(FeatureIDs::min_stage);
586 DoNotNormalize.set(FeatureIDs::max_stage);
587 DoNotNormalize.set(FeatureIDs::progress);
590int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
599bool MLEvictAdvisor::loadInterferenceFeatures(
610 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
611 int64_t LocalIntfs = 0;
612 float NrUrgent = 0.0f;
615 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
623 if (IFIntervals.empty() && InterferingIntervals.
empty())
627 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
629 assert(Intf->reg().isVirtual() &&
630 "Only expecting virtual register interference from query");
637 if (FixedRegisters.
count(Intf->reg()))
639 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
643 (Intf->isSpillable() ||
644 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
645 RegClassInfo.getNumAllocatableRegs(
646 MRI->getRegClass(Intf->reg())));
648 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
649 if (Cascade <= IntfCascade) {
655 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
656 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
661 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
662 NrUrgent, LRPosInfo);
666MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
668 uint8_t CostPerUseLimit,
const SmallVirtRegSet &FixedRegisters)
const {
669 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
670 if (!MaybeOrderLimit)
672 unsigned OrderLimit = *MaybeOrderLimit;
680 const bool MustFindEviction =
681 (!VirtReg.
isSpillable() && CostPerUseLimit ==
static_cast<uint8_t
>(~0
u));
686 resetInputs(*Runner);
691 CandidateRegList Regs;
692 Regs.fill({0,
false});
698 FeaturesListNormalizer Largest(FeatureIDs::FeatureCount, 0.0);
710 assert(!Regs[Pos].second);
712 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
715 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
716 Largest, Pos, LRPosInfo)) {
718 Regs[Pos] = std::make_pair(PhysReg,
true);
723 assert(!MustFindEviction);
726 const size_t ValidPosLimit = Pos;
730 if (!MustFindEviction)
735 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
736 "nothing to allocate initially.");
737#ifdef LLVM_HAVE_TFLITE
742 auto *CurrentMachineInstruction =
743 LIS->getInstructionFromIndex(InputIndex);
744 if (!CurrentMachineInstruction) {
747 return CurrentMachineInstruction->getOpcode();
750 auto *CurrentMachineInstruction =
751 LIS->getInstructionFromIndex(InputIndex);
753 CurrentMachineInstruction->getParent());
756 auto *CurrentMachineInstruction =
757 LIS->getInstructionFromIndex(InputIndex);
758 return CurrentMachineInstruction->
getParent();
760 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
761 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
762 LIS->getSlotIndexes()->getLastIndex());
766 for (
auto &V : Largest)
776 *Runner->
getTensor<
float>(FeatureIDs::progress) =
777 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
780 size_t CandidatePos = tryFindEvictionCandidatePosition(
781 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
784 assert(Regs[CandidatePos].second);
786 assert(!MustFindEviction);
789 assert(CandidatePos < ValidPosLimit);
791 return Regs[CandidatePos].first;
794const LIFeatureComponents &
795MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
797 LIFeatureComponents
Empty;
798 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
799 LIFeatureComponents &
Ret =
I.first->getSecond();
807 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
808 E =
MRI->reg_instr_nodbg_end();
816 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
820 std::tie(Reads,
Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
823 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
829 auto *
MBB =
MI->getParent();
833 if (
Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
834 Ret.IndVarUpdates += Freq;
837 Ret.HintWeights += Freq;
846void MLEvictAdvisor::extractFeatures(
849 int64_t LocalIntfsCount,
float NrUrgent,
851 int64_t NrDefsAndUses = 0;
852 int64_t NrBrokenHints = 0;
856 double IndVarUpdates = 0.0;
857 double HintWeights = 0.0;
858 float StartBBFreq = 0.0;
859 float EndBBFreq = 0.0;
860 float HottestBlockFreq = 0.0;
861 int32_t NrRematerializable = 0;
862 float TotalWeight = 0.0;
864 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
865 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
866 int64_t MaxStage = 0;
868 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
870 for (
const auto *L : Intervals) {
872 MaxStage = std::max<int64_t>(
873 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
874 MinStage = std::min<int64_t>(
875 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
877 TotalWeight = std::max(TotalWeight, LI.
weight());
884 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
885 NrBrokenHints += VRM->hasPreferredPhys(LI.
reg());
887 NrDefsAndUses += LIFC.NrDefsAndUses;
888 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
893 IndVarUpdates += LIFC.IndVarUpdates;
895 HintWeights += LIFC.HintWeights;
896 NrRematerializable += LIFC.IsRemat;
899 for (
auto CurrentSegment : LI) {
906 if (!Intervals.empty()) {
909 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
910 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
916#define SET(ID, TYPE, VAL) \
918 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
919 if (!DoNotNormalize.test(FeatureIDs::ID)) \
920 Largest[FeatureIDs::ID] = \
921 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
923 SET(mask, int64_t, 1);
924 SET(is_free, int64_t, Intervals.empty());
925 SET(nr_urgent,
float, NrUrgent);
926 SET(nr_broken_hints,
float, NrBrokenHints);
927 SET(is_hint, int64_t, IsHint);
928 SET(is_local, int64_t, LocalIntfsCount);
929 SET(nr_rematerializable,
float, NrRematerializable);
930 SET(nr_defs_and_uses,
float, NrDefsAndUses);
931 SET(weighed_reads_by_max,
float, R);
932 SET(weighed_writes_by_max,
float, W);
933 SET(weighed_read_writes_by_max,
float, RW);
934 SET(weighed_indvars_by_max,
float, IndVarUpdates);
935 SET(hint_weights_by_max,
float, HintWeights);
936 SET(start_bb_freq_by_max,
float, StartBBFreq);
937 SET(end_bb_freq_by_max,
float, EndBBFreq);
938 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
939 SET(liverange_size,
float,
Size);
940 SET(use_def_density,
float, TotalWeight);
941 SET(max_stage, int64_t, MaxStage);
942 SET(min_stage, int64_t, MinStage);
951 const int InstructionsIndex,
const int InstructionsMappingIndex,
952 const int MBBFreqIndex,
const int MBBMappingIndex,
972 size_t InstructionIndex = 0;
973 size_t CurrentSegmentIndex = 0;
974 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
975 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
976 size_t CurrentMBBIndex = 0;
988 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].
End &&
990 int CurrentOpcode = GetOpcode(CurrentIndex);
992 if (CurrentOpcode == -1) {
995 if (CurrentIndex >= LastIndex) {
1002 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1003 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1007 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1008 MBBFreqIndex, MBBMappingIndex);
1010 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1011 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1012 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1014 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1016 InstructionsMappingIndex)[CurrentSegmentPosition *
1018 InstructionIndex] = 1;
1027 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1028 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1029 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1030 auto OverlapCurrentSegmentPosition =
1031 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1032 if (LRPosInfo[OverlapCheckCurrentSegment].
End >= CurrentIndex) {
1034 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1036 InstructionIndex] = 1;
1038 ++OverlapCheckCurrentSegment;
1041 if (CurrentIndex >= LastIndex) {
1048 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1055 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1056 LRPosInfo[CurrentSegmentIndex].
End) {
1057 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1059 ++CurrentSegmentIndex;
1064 const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
1065 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1068 const int MBBFreqIndex,
const int MBBMappingIndex) {
1069 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1070 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1072 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1075 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1080#ifdef LLVM_HAVE_TFLITE
1083 return new DevelopmentModeEvictionAdvisorAnalysis();
1086int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1088 unsigned OrderLimit, uint8_t CostPerUseLimit,
1091 if (isa<ModelUnderTrainingRunner>(getRunner())) {
1092 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1093 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1095 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1096 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1108 if (TrainingLog.empty())
1113 if (Log->hasObservationInProgress())
1114 Log->logReward<
float>(0.0);
1116 Log->startObservation();
1117 size_t CurrentFeature = 0;
1119 ? FeatureIDs::FeaturesWithDevelopmentCount
1120 : FeatureIDs::FeatureCount;
1121 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1122 Log->logTensorValue(CurrentFeature,
1123 reinterpret_cast<const char *
>(
1124 getRunner().getTensorUntyped(CurrentFeature)));
1126 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(&getRunner()))
1127 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().size();
1128 ++
I, ++CurrentFeature)
1129 Log->logTensorValue(
1131 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1133 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1134 Log->endObservation();
1139 std::optional<float> CachedReward;
1140 auto GetReward = [&]() {
1142 CachedReward =
static_cast<float>(
1144 MF, getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI())
1146 return *CachedReward;
1149 getAnalysis<RegAllocEvictionAdvisorAnalysis>().logRewardIfNeeded(MF,
1151 getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
1158 return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
1160 ?
new ReleaseModeEvictionAdvisorAnalysis()
1165#if !defined(LLVM_HAVE_TFLITE)
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
SmallVector< uint32_t, 0 > Writes
@ Available
We know the block is fully available. This is a fixpoint.
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
#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, _)
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
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.
void emitError(uint64_t LocCookie, 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)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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_iterator - This class provides iterator support for machine operands in the function that...
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 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.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual std::unique_ptr< RegAllocEvictionAdvisor > getAdvisor(const MachineFunction &MF, const RAGreedy &RA)=0
Get an advisor for the given context (i.e. machine function, etc)
virtual void logRewardIfNeeded(const MachineFunction &MF, llvm::function_ref< float()> GetReward)
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.
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
void getAnalysisUsage(AnalysisUsage &AU) const override
RegAllocReward analysis usage.
~RegAllocScoring() override=default
bool runOnMachineFunction(MachineFunction &) override
Performs this pass.
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
static Register copyHint(const MachineInstr *MI, unsigned Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)
Return the preferred allocation register for reg, given a COPY instruction.
static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const TargetInstrInfo &TII)
Determine if all values in LI are rematerializable.
An efficient, type-erasing, non-owning reference to a callable.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
static const int ModelMaxSupportedInstructionCount
static const int64_t ModelMaxSupportedMBBCount
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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)
const char *const DecisionName
static const std::vector< TensorSpec > InputFeatures
@ RS_Done
There is nothing more we can do to this live range.
FunctionPass * createRegAllocScoringPass()
When learning an eviction policy, extract score(reward) information, otherwise this does nothing.
void initializeRegAllocScoringPass(PassRegistry &)
RegAllocEvictionAdvisorAnalysis * createReleaseModeAdvisor()
RegAllocEvictionAdvisorAnalysis * createDevelopmentModeAdvisor()
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.
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
static const int64_t CandidateVirtRegPos
Implement std::hash so that hash_code can be used in STL containers.