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"));
68 cl::desc(
"The maximum number of times a live range can be "
69 "evicted before preventing it from being evicted"),
73#ifdef LLVM_HAVE_TFLITE
79 cl::desc(
"Training log for the register allocator eviction model"));
83 cl::desc(
"The model being trained for register allocation eviction"));
86 "regalloc-enable-development-features",
cl::Hidden,
87 cl::desc(
"Whether or not to enable features under development for the ML "
111 return "Register Allocation Pass Scoring";
133 "Register Allocation Scoring Pass",
false,
false)
141static const int OpcodeValueCutoff = 17716;
165#define RA_EVICT_FEATURES_LIST(M) \
166 M(int64_t, mask, PerLiveRangeShape, \
167 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
169 "can't be evicted)") \
170 M(int64_t, is_free, PerLiveRangeShape, \
171 "boolean values, 1 if this phys reg is actually free (no interferences)") \
172 M(float, nr_urgent, PerLiveRangeShape, \
173 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
174 "to break cascades") \
175 M(float, nr_broken_hints, PerLiveRangeShape, \
176 "if this position were evicted, how many broken hints would there be") \
177 M(int64_t, is_hint, PerLiveRangeShape, \
178 "is this a preferred phys reg for the candidate") \
179 M(int64_t, is_local, PerLiveRangeShape, \
180 "is this live range local to a basic block") \
181 M(float, nr_rematerializable, PerLiveRangeShape, \
182 "nr rematerializable ranges") \
183 M(float, nr_defs_and_uses, PerLiveRangeShape, \
184 "bb freq - weighed nr defs and uses") \
185 M(float, weighed_reads_by_max, PerLiveRangeShape, \
186 "bb freq - weighed nr of reads, normalized") \
187 M(float, weighed_writes_by_max, PerLiveRangeShape, \
188 "bb feq - weighed nr of writes, normalized") \
189 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
190 "bb freq - weighed nr of uses that are both read and writes, normalized") \
191 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
192 "bb freq - weighed nr of uses that are indvars, normalized") \
193 M(float, hint_weights_by_max, PerLiveRangeShape, \
194 "bb freq - weighed nr of uses that are hints, normalized") \
195 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
196 "the freq in the start block, normalized") \
197 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
198 "freq of end block, normalized") \
199 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
200 "hottest BB freq, normalized") \
201 M(float, liverange_size, PerLiveRangeShape, \
202 "size (instr index diff) of the LR") \
203 M(float, use_def_density, PerLiveRangeShape, \
204 "the max weight, as computed by the manual heuristic") \
205 M(int64_t, max_stage, PerLiveRangeShape, \
206 "largest stage of an interval in this LR") \
207 M(int64_t, min_stage, PerLiveRangeShape, \
208 "lowest stage of an interval in this LR") \
209 M(float, progress, {1}, "ratio of current queue size to initial size")
211#ifdef LLVM_HAVE_TFLITE
212#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M) \
213 M(int64_t, instructions, InstructionsShape, \
214 "Opcodes of the instructions covered by the eviction problem")
216#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M) \
217 M(int64_t, instructions_mapping, InstructionsMappingShape, \
218 "A binary matrix mapping LRs to instruction opcodes") \
219 M(float, mbb_frequencies, MBBFrequencyShape, \
220 "A vector of machine basic block frequencies") \
221 M(int64_t, mbb_mapping, InstructionsShape, \
222 "A vector of indices mapping instructions to MBBs")
224#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
225#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
232#define DecisionName "index_to_evict"
238#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
239#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
241#ifdef LLVM_HAVE_TFLITE
248#undef _FEATURE_IDX_SIMPLE
255template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
256 size_t Ret =
sizeof(
T);
257 for (
const auto V : Shape)
263#define _RESET(TYPE, NAME, SHAPE, __) \
264 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
265 getTotalSize<TYPE>(SHAPE));
276struct LIFeatureComponents {
280 double IndVarUpdates = 0;
281 double HintWeights = 0.0;
282 int64_t NumDefsAndUses = 0;
283 float HottestBlockFreq = 0.0;
284 bool IsRemat =
false;
287using CandidateRegList =
289using FeaturesListNormalizer =
313 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
315 unsigned OrderLimit,
uint8_t CostPerUseLimit,
336 int64_t IsHint, int64_t LocalIntfsCount,
float NumUrgent,
344 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
348 const LIFeatureComponents &
362 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
363 const float InitialQSize;
369#define _DECL_FEATURES(type, name, shape, _) \
370 TensorSpec::createSpec<type>(#name, shape),
375class ReleaseModeEvictionAdvisorAnalysis final
378 ReleaseModeEvictionAdvisorAnalysis()
402 std::unique_ptr<RegAllocEvictionAdvisor>
406 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
409 Runner = std::make_unique<InteractiveModelRunner>(
414 return std::make_unique<MLEvictAdvisor>(
415 MF,
RA, Runner.get(),
416 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI(),
417 getAnalysis<MachineLoopInfoWrapperPass>().getLI());
419 std::unique_ptr<MLModelRunner> Runner;
427#ifdef LLVM_HAVE_TFLITE
428static const TensorSpec Reward = TensorSpec::createSpec<float>(
"reward", {1});
434#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
435 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
437class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
443 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
446 int64_t tryFindEvictionCandidatePosition(
448 unsigned OrderLimit,
uint8_t CostPerUseLimit,
454class DevelopmentModeEvictionAdvisorAnalysis final
457 DevelopmentModeEvictionAdvisorAnalysis()
463 TrainingInputFeatures = {
467 TensorSpec::createSpec<float>(
"action_discount", {1}),
468 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
469 TensorSpec::createSpec<float>(
"action_reward", {1})};
472 TrainingInputFeatures = {
474 TensorSpec::createSpec<float>(
"action_discount", {1}),
475 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
476 TensorSpec::createSpec<float>(
"action_reward", {1})};
486 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
492 if (Log->currentContext() != MF.
getName()) {
494 "The training log context shouldn't have had changed.");
496 if (Log->hasObservationInProgress())
497 Log->logReward<
float>(GetReward());
502 std::vector<TensorSpec> TrainingInputFeatures;
512 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
513 Ctx.
emitError(
"Regalloc development mode should be requested with at "
514 "least logging enabled and/or a training model");
517 if (ModelUnderTraining.empty())
518 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
520 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
521 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
523 Ctx.
emitError(
"Regalloc: could not set up the model runner");
526 if (TrainingLog.empty())
529 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
531 M.getContext().emitError(EC.message() +
":" + TrainingLog);
535 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
542 Log = std::make_unique<Logger>(std::move(
OS), LFS, Reward,
547 std::unique_ptr<RegAllocEvictionAdvisor>
552 Log->switchContext(MF.
getName());
553 return std::make_unique<DevelopmentModeEvictAdvisor>(
554 MF,
RA, Runner.get(),
555 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI(),
556 getAnalysis<MachineLoopInfoWrapperPass>().getLI(), Log.get());
559 std::unique_ptr<MLModelRunner> Runner;
560 std::unique_ptr<Logger> Log;
568 unsigned NumUsedRegs = 0;
569 for (
unsigned I = 0, E =
MRI.getNumVirtRegs();
I != E; ++
I) {
571 if (!
MRI.reg_nodbg_empty(Reg))
574 return static_cast<float>(NumUsedRegs);
583 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
586 DoNotNormalize.set(FeatureIDs::mask);
587 DoNotNormalize.set(FeatureIDs::is_free);
588 DoNotNormalize.set(FeatureIDs::is_hint);
589 DoNotNormalize.set(FeatureIDs::is_local);
590 DoNotNormalize.set(FeatureIDs::min_stage);
591 DoNotNormalize.set(FeatureIDs::max_stage);
592 DoNotNormalize.set(FeatureIDs::progress);
595int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
604bool MLEvictAdvisor::loadInterferenceFeatures(
615 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
616 int64_t LocalIntfs = 0;
617 float NumUrgent = 0.0f;
620 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
628 if (IFIntervals.empty() && InterferingIntervals.
empty())
632 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
634 assert(Intf->reg().isVirtual() &&
635 "Only expecting virtual register interference from query");
642 if (FixedRegisters.
count(Intf->reg()))
644 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
648 (Intf->isSpillable() ||
649 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
650 RegClassInfo.getNumAllocatableRegs(
651 MRI->getRegClass(Intf->reg())));
653 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
664 if (Cascade <= IntfCascade) {
670 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
671 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
676 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
677 NumUrgent, LRPosInfo);
681MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
684 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
685 if (!MaybeOrderLimit)
687 unsigned OrderLimit = *MaybeOrderLimit;
695 const bool MustFindEviction =
701 resetInputs(*Runner);
706 CandidateRegList Regs;
707 Regs.fill({0,
false});
713 FeaturesListNormalizer Largest(FeatureIDs::FeatureCount, 0.0);
725 assert(!Regs[Pos].second);
727 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
730 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
731 Largest, Pos, LRPosInfo)) {
733 Regs[Pos] = std::make_pair(PhysReg,
true);
738 assert(!MustFindEviction);
741 const size_t ValidPosLimit = Pos;
745 if (!MustFindEviction)
750 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
751 "nothing to allocate initially.");
752#ifdef LLVM_HAVE_TFLITE
757 auto *CurrentMachineInstruction =
758 LIS->getInstructionFromIndex(InputIndex);
759 if (!CurrentMachineInstruction) {
762 return CurrentMachineInstruction->getOpcode();
765 auto *CurrentMachineInstruction =
766 LIS->getInstructionFromIndex(InputIndex);
768 CurrentMachineInstruction->getParent());
771 auto *CurrentMachineInstruction =
772 LIS->getInstructionFromIndex(InputIndex);
773 return CurrentMachineInstruction->
getParent();
775 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
776 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
777 LIS->getSlotIndexes()->getLastIndex());
781 for (
auto &V : Largest)
791 *Runner->
getTensor<
float>(FeatureIDs::progress) =
792 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
795 size_t CandidatePos = tryFindEvictionCandidatePosition(
796 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
799 assert(Regs[CandidatePos].second);
801 assert(!MustFindEviction);
804 assert(CandidatePos < ValidPosLimit);
806 return Regs[CandidatePos].first;
809const LIFeatureComponents &
810MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
812 LIFeatureComponents
Empty;
813 auto I = CachedFeatures.insert(std::make_pair(
ID, Empty));
814 LIFeatureComponents &
Ret =
I.first->getSecond();
822 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
823 E =
MRI->reg_instr_nodbg_end();
827 ++
Ret.NumDefsAndUses;
831 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
835 std::tie(Reads,
Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
838 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
844 auto *
MBB =
MI->getParent();
848 if (
Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
849 Ret.IndVarUpdates += Freq;
852 Ret.HintWeights += Freq;
861void MLEvictAdvisor::extractFeatures(
864 int64_t LocalIntfsCount,
float NumUrgent,
866 int64_t NumDefsAndUses = 0;
867 int64_t NumBrokenHints = 0;
871 double IndVarUpdates = 0.0;
872 double HintWeights = 0.0;
873 float StartBBFreq = 0.0;
874 float EndBBFreq = 0.0;
875 float HottestBlockFreq = 0.0;
876 int32_t NumRematerializable = 0;
877 float TotalWeight = 0.0;
879 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
880 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
881 int64_t MaxStage = 0;
883 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
885 for (
const auto *L : Intervals) {
887 MaxStage = std::max<int64_t>(
888 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
889 MinStage = std::min<int64_t>(
890 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
892 TotalWeight = std::max(TotalWeight, LI.
weight());
899 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
900 NumBrokenHints += VRM->hasPreferredPhys(LI.
reg());
902 NumDefsAndUses += LIFC.NumDefsAndUses;
903 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
908 IndVarUpdates += LIFC.IndVarUpdates;
910 HintWeights += LIFC.HintWeights;
911 NumRematerializable += LIFC.IsRemat;
914 for (
auto CurrentSegment : LI) {
921 if (!Intervals.empty()) {
924 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
925 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
931#define SET(ID, TYPE, VAL) \
933 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
934 if (!DoNotNormalize.test(FeatureIDs::ID)) \
935 Largest[FeatureIDs::ID] = \
936 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
938 SET(mask, int64_t, 1);
939 SET(is_free, int64_t, Intervals.empty());
940 SET(nr_urgent,
float, NumUrgent);
941 SET(nr_broken_hints,
float, NumBrokenHints);
942 SET(is_hint, int64_t, IsHint);
943 SET(is_local, int64_t, LocalIntfsCount);
944 SET(nr_rematerializable,
float, NumRematerializable);
945 SET(nr_defs_and_uses,
float, NumDefsAndUses);
946 SET(weighed_reads_by_max,
float, R);
947 SET(weighed_writes_by_max,
float, W);
948 SET(weighed_read_writes_by_max,
float, RW);
949 SET(weighed_indvars_by_max,
float, IndVarUpdates);
950 SET(hint_weights_by_max,
float, HintWeights);
951 SET(start_bb_freq_by_max,
float, StartBBFreq);
952 SET(end_bb_freq_by_max,
float, EndBBFreq);
953 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
954 SET(liverange_size,
float,
Size);
955 SET(use_def_density,
float, TotalWeight);
956 SET(max_stage, int64_t, MaxStage);
957 SET(min_stage, int64_t, MinStage);
966 const int InstructionsIndex,
const int InstructionsMappingIndex,
967 const int MBBFreqIndex,
const int MBBMappingIndex,
987 size_t InstructionIndex = 0;
988 size_t CurrentSegmentIndex = 0;
989 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
990 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
991 size_t CurrentMBBIndex = 0;
1003 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].
End &&
1005 int CurrentOpcode = GetOpcode(CurrentIndex);
1007 if (CurrentOpcode == -1) {
1010 if (CurrentIndex >= LastIndex) {
1017 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1018 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1022 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1023 MBBFreqIndex, MBBMappingIndex);
1025 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1026 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1027 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1029 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1031 InstructionsMappingIndex)[CurrentSegmentPosition *
1033 InstructionIndex] = 1;
1042 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1043 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1044 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1045 auto OverlapCurrentSegmentPosition =
1046 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1047 if (LRPosInfo[OverlapCheckCurrentSegment].
End >= CurrentIndex) {
1049 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1051 InstructionIndex] = 1;
1053 ++OverlapCheckCurrentSegment;
1056 if (CurrentIndex >= LastIndex) {
1063 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1070 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1071 LRPosInfo[CurrentSegmentIndex].
End) {
1072 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1074 ++CurrentSegmentIndex;
1079 const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
1080 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1083 const int MBBFreqIndex,
const int MBBMappingIndex) {
1084 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1085 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1087 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1090 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1095#ifdef LLVM_HAVE_TFLITE
1098 return new DevelopmentModeEvictionAdvisorAnalysis();
1101int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1103 unsigned OrderLimit,
uint8_t CostPerUseLimit,
1106 if (isa<ModelUnderTrainingRunner>(getRunner())) {
1107 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1108 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1110 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1111 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1123 if (TrainingLog.empty())
1128 if (Log->hasObservationInProgress())
1129 Log->logReward<
float>(0.0);
1131 Log->startObservation();
1132 size_t CurrentFeature = 0;
1134 ? FeatureIDs::FeaturesWithDevelopmentCount
1135 : FeatureIDs::FeatureCount;
1136 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1137 Log->logTensorValue(CurrentFeature,
1138 reinterpret_cast<const char *
>(
1139 getRunner().getTensorUntyped(CurrentFeature)));
1141 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(&getRunner()))
1142 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().size();
1143 ++
I, ++CurrentFeature)
1144 Log->logTensorValue(
1146 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1148 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1149 Log->endObservation();
1154 std::optional<float> CachedReward;
1155 auto GetReward = [&]() {
1157 CachedReward =
static_cast<float>(
1159 MF, getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI())
1161 return *CachedReward;
1164 getAnalysis<RegAllocEvictionAdvisorAnalysis>().logRewardIfNeeded(MF,
1166 getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
1173 return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
1175 ?
new ReleaseModeEvictionAdvisorAnalysis()
1180#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.
Module.h This file contains the declarations for the Module class.
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, __)
static cl::opt< unsigned > MaxCascade("mlregalloc-max-cascade", cl::Hidden, cl::desc("The maximum number of times a live range can be " "evicted before preventing it from being evicted"), cl::init(20))
#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
#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(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)
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.
initializer< Ty > init(const Ty &Val)
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.