19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)
46#define DEBUG_TYPE "ml-regalloc"
49#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)
50#include "RegallocEvictModel.h"
57 "regalloc-evict-interactive-channel-base",
cl::Hidden,
59 "Base file path for the interactive mode. The incoming filename should "
60 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
61 "outgoing name should be "
62 "<regalloc-evict-interactive-channel-base>.out"));
65#ifdef LLVM_HAVE_TFLITE
71 cl::desc(
"Training log for the register allocator eviction model"));
75 cl::desc(
"The model being trained for register allocation eviction"));
78 "regalloc-enable-development-features",
cl::Hidden,
79 cl::desc(
"Whether or not to enable features under development for the ML "
103 return "Register Allocation Pass Scoring";
125 "Register Allocation Scoring Pass",
false,
false)
133static const int OpcodeValueCutoff = 17716;
157#define RA_EVICT_FEATURES_LIST(M) \
158 M(int64_t, mask, PerLiveRangeShape, \
159 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
161 "can't be evicted)") \
162 M(int64_t, is_free, PerLiveRangeShape, \
163 "boolean values, 1 if this phys reg is actually free (no interferences)") \
164 M(float, nr_urgent, PerLiveRangeShape, \
165 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
166 "to break cascades") \
167 M(float, nr_broken_hints, PerLiveRangeShape, \
168 "if this position were evicted, how many broken hints would there be") \
169 M(int64_t, is_hint, PerLiveRangeShape, \
170 "is this a preferred phys reg for the candidate") \
171 M(int64_t, is_local, PerLiveRangeShape, \
172 "is this live range local to a basic block") \
173 M(float, nr_rematerializable, PerLiveRangeShape, \
174 "nr rematerializable ranges") \
175 M(float, nr_defs_and_uses, PerLiveRangeShape, \
176 "bb freq - weighed nr defs and uses") \
177 M(float, weighed_reads_by_max, PerLiveRangeShape, \
178 "bb freq - weighed nr of reads, normalized") \
179 M(float, weighed_writes_by_max, PerLiveRangeShape, \
180 "bb feq - weighed nr of writes, normalized") \
181 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
182 "bb freq - weighed nr of uses that are both read and writes, normalized") \
183 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
184 "bb freq - weighed nr of uses that are indvars, normalized") \
185 M(float, hint_weights_by_max, PerLiveRangeShape, \
186 "bb freq - weighed nr of uses that are hints, normalized") \
187 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
188 "the freq in the start block, normalized") \
189 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
190 "freq of end block, normalized") \
191 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
192 "hottest BB freq, normalized") \
193 M(float, liverange_size, PerLiveRangeShape, \
194 "size (instr index diff) of the LR") \
195 M(float, use_def_density, PerLiveRangeShape, \
196 "the max weight, as computed by the manual heuristic") \
197 M(int64_t, max_stage, PerLiveRangeShape, \
198 "largest stage of an interval in this LR") \
199 M(int64_t, min_stage, PerLiveRangeShape, \
200 "lowest stage of an interval in this LR") \
201 M(float, progress, {1}, "ratio of current queue size to initial size")
203#ifdef LLVM_HAVE_TFLITE
204#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M) \
205 M(int64_t, instructions, InstructionsShape, \
206 "Opcodes of the instructions covered by the eviction problem")
208#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M) \
209 M(int64_t, instructions_mapping, InstructionsMappingShape, \
210 "A binary matrix mapping LRs to instruction opcodes") \
211 M(float, mbb_frequencies, MBBFrequencyShape, \
212 "A vector of machine basic block frequencies") \
213 M(int64_t, mbb_mapping, InstructionsShape, \
214 "A vector of indicies mapping instructions to MBBs")
216#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
217#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
224#define DecisionName "index_to_evict"
230#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
231#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
233#ifdef LLVM_HAVE_TFLITE
240#undef _FEATURE_IDX_SIMPLE
247template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
248 size_t Ret =
sizeof(
T);
249 for (
const auto V : Shape)
255#define _RESET(TYPE, NAME, SHAPE, __) \
256 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
257 getTotalSize<TYPE>(SHAPE));
268struct LIFeatureComponents {
272 double IndVarUpdates = 0;
273 double HintWeights = 0.0;
274 int64_t NrDefsAndUses = 0;
275 float HottestBlockFreq = 0.0;
276 bool IsRemat =
false;
279using CandidateRegList =
281using FeaturesListNormalizer =
305 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
307 unsigned OrderLimit, uint8_t CostPerUseLimit,
323 uint8_t CostPerUseLimit,
328 int64_t IsHint, int64_t LocalIntfsCount,
float NrUrgent,
336 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
340 const LIFeatureComponents &
354 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
355 const float InitialQSize;
361#define _DECL_FEATURES(type, name, shape, _) \
362 TensorSpec::createSpec<type>(#name, shape),
367class ReleaseModeEvictionAdvisorAnalysis final
370 ReleaseModeEvictionAdvisorAnalysis()
394 std::unique_ptr<RegAllocEvictionAdvisor>
398 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
401 Runner = std::make_unique<InteractiveModelRunner>(
406 return std::make_unique<MLEvictAdvisor>(
407 MF,
RA, Runner.get(), getAnalysis<MachineBlockFrequencyInfo>(),
408 getAnalysis<MachineLoopInfo>());
410 std::unique_ptr<MLModelRunner> Runner;
418#ifdef LLVM_HAVE_TFLITE
419static const TensorSpec Reward = TensorSpec::createSpec<float>(
"reward", {1});
425#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
426 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
428class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
434 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
437 int64_t tryFindEvictionCandidatePosition(
439 unsigned OrderLimit, uint8_t CostPerUseLimit,
445class DevelopmentModeEvictionAdvisorAnalysis final
448 DevelopmentModeEvictionAdvisorAnalysis()
454 TrainingInputFeatures = {
458 TensorSpec::createSpec<float>(
"action_discount", {1}),
459 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
460 TensorSpec::createSpec<float>(
"action_reward", {1})};
463 TrainingInputFeatures = {
465 TensorSpec::createSpec<float>(
"action_discount", {1}),
466 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
467 TensorSpec::createSpec<float>(
"action_reward", {1})};
477 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
483 if (Log->currentContext() != MF.
getName()) {
485 "The training log context shouldn't have had changed.");
487 if (Log->hasObservationInProgress())
488 Log->logReward<
float>(GetReward());
493 std::vector<TensorSpec> TrainingInputFeatures;
503 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
504 Ctx.
emitError(
"Regalloc development mode should be requested with at "
505 "least logging enabled and/or a training model");
508 if (ModelUnderTraining.empty())
509 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
511 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
512 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
514 Ctx.
emitError(
"Regalloc: could not set up the model runner");
517 if (TrainingLog.empty())
520 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
522 M.getContext().emitError(EC.message() +
":" + TrainingLog);
526 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
533 Log = std::make_unique<Logger>(std::move(
OS), LFS, Reward,
538 std::unique_ptr<RegAllocEvictionAdvisor>
543 Log->switchContext(MF.
getName());
544 return std::make_unique<DevelopmentModeEvictAdvisor>(
545 MF,
RA, Runner.get(), getAnalysis<MachineBlockFrequencyInfo>(),
546 getAnalysis<MachineLoopInfo>(), Log.get());
549 std::unique_ptr<MLModelRunner> Runner;
550 std::unique_ptr<Logger> Log;
559 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
561 if (
MRI.reg_nodbg_empty(Reg))
574 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
577 DoNotNormalize.set(FeatureIDs::mask);
578 DoNotNormalize.set(FeatureIDs::is_free);
579 DoNotNormalize.set(FeatureIDs::is_hint);
580 DoNotNormalize.set(FeatureIDs::is_local);
581 DoNotNormalize.set(FeatureIDs::min_stage);
582 DoNotNormalize.set(FeatureIDs::max_stage);
583 DoNotNormalize.set(FeatureIDs::progress);
586int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
595bool MLEvictAdvisor::loadInterferenceFeatures(
606 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
607 int64_t LocalIntfs = 0;
608 float NrUrgent = 0.0f;
611 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
619 if (IFIntervals.empty() && InterferingIntervals.
empty())
623 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
625 assert(Intf->reg().isVirtual() &&
626 "Only expecting virtual register interference from query");
633 if (FixedRegisters.
count(Intf->reg()))
635 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
639 (Intf->isSpillable() ||
640 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
641 RegClassInfo.getNumAllocatableRegs(
642 MRI->getRegClass(Intf->reg())));
644 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
645 if (Cascade <= IntfCascade) {
651 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
652 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
657 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
658 NrUrgent, LRPosInfo);
662MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
664 uint8_t CostPerUseLimit,
const SmallVirtRegSet &FixedRegisters)
const {
665 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
666 if (!MaybeOrderLimit)
668 unsigned OrderLimit = *MaybeOrderLimit;
676 const bool MustFindEviction =
677 (!VirtReg.
isSpillable() && CostPerUseLimit ==
static_cast<uint8_t
>(~0
u));
682 resetInputs(*Runner);
687 CandidateRegList Regs;
688 Regs.fill({0,
false});
694 FeaturesListNormalizer Largest(FeatureIDs::FeatureCount, 0.0);
706 assert(!Regs[Pos].second);
708 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
711 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
712 Largest, Pos, LRPosInfo)) {
714 Regs[Pos] = std::make_pair(PhysReg,
true);
719 assert(!MustFindEviction);
722 const size_t ValidPosLimit = Pos;
726 if (!MustFindEviction)
731 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
732 "nothing to allocate initially.");
733#ifdef LLVM_HAVE_TFLITE
738 auto *CurrentMachineInstruction =
739 LIS->getInstructionFromIndex(InputIndex);
740 if (!CurrentMachineInstruction) {
743 return CurrentMachineInstruction->getOpcode();
746 auto *CurrentMachineInstruction =
747 LIS->getInstructionFromIndex(InputIndex);
749 CurrentMachineInstruction->getParent());
752 auto *CurrentMachineInstruction =
753 LIS->getInstructionFromIndex(InputIndex);
754 return CurrentMachineInstruction->
getParent();
756 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
757 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
758 LIS->getSlotIndexes()->getLastIndex());
762 for (
auto &V : Largest)
772 *Runner->
getTensor<
float>(FeatureIDs::progress) =
773 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
776 size_t CandidatePos = tryFindEvictionCandidatePosition(
777 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
780 assert(Regs[CandidatePos].second);
782 assert(!MustFindEviction);
785 assert(CandidatePos < ValidPosLimit);
787 return Regs[CandidatePos].first;
790const LIFeatureComponents &
791MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
793 LIFeatureComponents
Empty;
794 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
795 LIFeatureComponents &
Ret =
I.first->getSecond();
803 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
804 E =
MRI->reg_instr_nodbg_end();
812 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
816 std::tie(Reads,
Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
819 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
825 auto *
MBB =
MI->getParent();
829 if (
Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
830 Ret.IndVarUpdates += Freq;
833 Ret.HintWeights += Freq;
842void MLEvictAdvisor::extractFeatures(
845 int64_t LocalIntfsCount,
float NrUrgent,
847 int64_t NrDefsAndUses = 0;
848 int64_t NrBrokenHints = 0;
852 double IndVarUpdates = 0.0;
853 double HintWeights = 0.0;
854 float StartBBFreq = 0.0;
855 float EndBBFreq = 0.0;
856 float HottestBlockFreq = 0.0;
857 int32_t NrRematerializable = 0;
858 float TotalWeight = 0.0;
860 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
861 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
862 int64_t MaxStage = 0;
864 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
866 for (
const auto *L : Intervals) {
868 MaxStage = std::max<int64_t>(
869 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
870 MinStage = std::min<int64_t>(
871 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
873 TotalWeight = std::max(TotalWeight, LI.
weight());
880 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
881 NrBrokenHints += VRM->hasPreferredPhys(LI.
reg());
883 NrDefsAndUses += LIFC.NrDefsAndUses;
884 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
889 IndVarUpdates += LIFC.IndVarUpdates;
891 HintWeights += LIFC.HintWeights;
892 NrRematerializable += LIFC.IsRemat;
895 for (
auto CurrentSegment : LI) {
902 if (!Intervals.empty()) {
905 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
906 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
912#define SET(ID, TYPE, VAL) \
914 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
915 if (!DoNotNormalize.test(FeatureIDs::ID)) \
916 Largest[FeatureIDs::ID] = \
917 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
919 SET(mask, int64_t, 1);
920 SET(is_free, int64_t, Intervals.empty());
921 SET(nr_urgent,
float, NrUrgent);
922 SET(nr_broken_hints,
float, NrBrokenHints);
923 SET(is_hint, int64_t, IsHint);
924 SET(is_local, int64_t, LocalIntfsCount);
925 SET(nr_rematerializable,
float, NrRematerializable);
926 SET(nr_defs_and_uses,
float, NrDefsAndUses);
927 SET(weighed_reads_by_max,
float, R);
928 SET(weighed_writes_by_max,
float, W);
929 SET(weighed_read_writes_by_max,
float, RW);
930 SET(weighed_indvars_by_max,
float, IndVarUpdates);
931 SET(hint_weights_by_max,
float, HintWeights);
932 SET(start_bb_freq_by_max,
float, StartBBFreq);
933 SET(end_bb_freq_by_max,
float, EndBBFreq);
934 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
935 SET(liverange_size,
float,
Size);
936 SET(use_def_density,
float, TotalWeight);
937 SET(max_stage, int64_t, MaxStage);
938 SET(min_stage, int64_t, MinStage);
947 const int InstructionsIndex,
const int InstructionsMappingIndex,
948 const int MBBFreqIndex,
const int MBBMappingIndex,
968 size_t InstructionIndex = 0;
969 size_t CurrentSegmentIndex = 0;
970 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
971 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
972 size_t CurrentMBBIndex = 0;
984 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].
End &&
986 int CurrentOpcode = GetOpcode(CurrentIndex);
988 if (CurrentOpcode == -1) {
991 if (CurrentIndex >= LastIndex) {
998 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
999 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1003 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1004 MBBFreqIndex, MBBMappingIndex);
1006 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1007 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1008 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1010 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1012 InstructionsMappingIndex)[CurrentSegmentPosition *
1014 InstructionIndex] = 1;
1023 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1024 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1025 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1026 auto OverlapCurrentSegmentPosition =
1027 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1028 if (LRPosInfo[OverlapCheckCurrentSegment].
End >= CurrentIndex) {
1030 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1032 InstructionIndex] = 1;
1034 ++OverlapCheckCurrentSegment;
1037 if (CurrentIndex >= LastIndex) {
1044 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1051 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1052 LRPosInfo[CurrentSegmentIndex].
End) {
1053 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1055 ++CurrentSegmentIndex;
1060 const size_t CurrentInstructionIndex,
1061 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1065 const int MBBMappingIndex) {
1066 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1067 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1069 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1072 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1077#ifdef LLVM_HAVE_TFLITE
1080 return new DevelopmentModeEvictionAdvisorAnalysis();
1083int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1085 unsigned OrderLimit, uint8_t CostPerUseLimit,
1088 if (isa<ModelUnderTrainingRunner>(getRunner())) {
1089 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1090 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1092 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1093 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1105 if (TrainingLog.empty())
1110 if (Log->hasObservationInProgress())
1111 Log->logReward<
float>(0.0);
1113 Log->startObservation();
1114 size_t CurrentFeature = 0;
1116 ? FeatureIDs::FeaturesWithDevelopmentCount
1117 : FeatureIDs::FeatureCount;
1118 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1119 Log->logTensorValue(CurrentFeature,
1120 reinterpret_cast<const char *
>(
1121 getRunner().getTensorUntyped(CurrentFeature)));
1123 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(&getRunner()))
1124 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().size();
1125 ++
I, ++CurrentFeature)
1126 Log->logTensorValue(
1128 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1130 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1131 Log->endObservation();
1136 std::optional<float> CachedReward;
1137 auto GetReward = [&]() {
1139 CachedReward =
static_cast<float>(
1142 return *CachedReward;
1145 getAnalysis<RegAllocEvictionAdvisorAnalysis>().logRewardIfNeeded(MF,
1147 getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
1154 return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
1156 ?
new ReleaseModeEvictionAdvisorAnalysis()
1161#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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
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)
#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)
void extractInstructionFeatures(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 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, _)
static const int ModelMaxSupportedInstructionCount
static const int64_t CandidateVirtRegPos
static const int64_t ModelMaxSupportedMBBCount
static const int64_t NumberOfInterferences
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(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.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
MLModelRunner interface: abstraction of a mechanism for evaluating a tensorflow "saved 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...
float 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.
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.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
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.
static const std::vector< int64_t > PerLiveRangeShape