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(), getAnalysis<MachineBlockFrequencyInfo>(),
410 getAnalysis<MachineLoopInfo>());
412 std::unique_ptr<MLModelRunner> Runner;
420#ifdef LLVM_HAVE_TFLITE
421static const TensorSpec Reward = TensorSpec::createSpec<float>(
"reward", {1});
427#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
428 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
430class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
436 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
439 int64_t tryFindEvictionCandidatePosition(
441 unsigned OrderLimit, uint8_t CostPerUseLimit,
447class DevelopmentModeEvictionAdvisorAnalysis final
450 DevelopmentModeEvictionAdvisorAnalysis()
456 TrainingInputFeatures = {
460 TensorSpec::createSpec<float>(
"action_discount", {1}),
461 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
462 TensorSpec::createSpec<float>(
"action_reward", {1})};
465 TrainingInputFeatures = {
467 TensorSpec::createSpec<float>(
"action_discount", {1}),
468 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
469 TensorSpec::createSpec<float>(
"action_reward", {1})};
479 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
485 if (Log->currentContext() != MF.
getName()) {
487 "The training log context shouldn't have had changed.");
489 if (Log->hasObservationInProgress())
490 Log->logReward<
float>(GetReward());
495 std::vector<TensorSpec> TrainingInputFeatures;
505 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
506 Ctx.
emitError(
"Regalloc development mode should be requested with at "
507 "least logging enabled and/or a training model");
510 if (ModelUnderTraining.empty())
511 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
513 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
514 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
516 Ctx.
emitError(
"Regalloc: could not set up the model runner");
519 if (TrainingLog.empty())
522 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
524 M.getContext().emitError(EC.message() +
":" + TrainingLog);
528 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
535 Log = std::make_unique<Logger>(std::move(
OS), LFS, Reward,
540 std::unique_ptr<RegAllocEvictionAdvisor>
545 Log->switchContext(MF.
getName());
546 return std::make_unique<DevelopmentModeEvictAdvisor>(
547 MF,
RA, Runner.get(), getAnalysis<MachineBlockFrequencyInfo>(),
548 getAnalysis<MachineLoopInfo>(), Log.get());
551 std::unique_ptr<MLModelRunner> Runner;
552 std::unique_ptr<Logger> Log;
561 for (
unsigned I = 0, E =
MRI.getNumVirtRegs();
I != E; ++
I) {
563 if (
MRI.reg_nodbg_empty(Reg))
576 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
579 DoNotNormalize.set(FeatureIDs::mask);
580 DoNotNormalize.set(FeatureIDs::is_free);
581 DoNotNormalize.set(FeatureIDs::is_hint);
582 DoNotNormalize.set(FeatureIDs::is_local);
583 DoNotNormalize.set(FeatureIDs::min_stage);
584 DoNotNormalize.set(FeatureIDs::max_stage);
585 DoNotNormalize.set(FeatureIDs::progress);
588int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
597bool MLEvictAdvisor::loadInterferenceFeatures(
608 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
609 int64_t LocalIntfs = 0;
610 float NrUrgent = 0.0f;
613 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
621 if (IFIntervals.empty() && InterferingIntervals.
empty())
625 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
627 assert(Intf->reg().isVirtual() &&
628 "Only expecting virtual register interference from query");
635 if (FixedRegisters.
count(Intf->reg()))
637 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
641 (Intf->isSpillable() ||
642 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
643 RegClassInfo.getNumAllocatableRegs(
644 MRI->getRegClass(Intf->reg())));
646 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
647 if (Cascade <= IntfCascade) {
653 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
654 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
659 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
660 NrUrgent, LRPosInfo);
664MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
666 uint8_t CostPerUseLimit,
const SmallVirtRegSet &FixedRegisters)
const {
667 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
668 if (!MaybeOrderLimit)
670 unsigned OrderLimit = *MaybeOrderLimit;
678 const bool MustFindEviction =
679 (!VirtReg.
isSpillable() && CostPerUseLimit ==
static_cast<uint8_t
>(~0
u));
684 resetInputs(*Runner);
689 CandidateRegList Regs;
690 Regs.fill({0,
false});
696 FeaturesListNormalizer Largest(FeatureIDs::FeatureCount, 0.0);
708 assert(!Regs[Pos].second);
710 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
713 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
714 Largest, Pos, LRPosInfo)) {
716 Regs[Pos] = std::make_pair(PhysReg,
true);
721 assert(!MustFindEviction);
724 const size_t ValidPosLimit = Pos;
728 if (!MustFindEviction)
733 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
734 "nothing to allocate initially.");
735#ifdef LLVM_HAVE_TFLITE
740 auto *CurrentMachineInstruction =
741 LIS->getInstructionFromIndex(InputIndex);
742 if (!CurrentMachineInstruction) {
745 return CurrentMachineInstruction->getOpcode();
748 auto *CurrentMachineInstruction =
749 LIS->getInstructionFromIndex(InputIndex);
751 CurrentMachineInstruction->getParent());
754 auto *CurrentMachineInstruction =
755 LIS->getInstructionFromIndex(InputIndex);
756 return CurrentMachineInstruction->
getParent();
758 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
759 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
760 LIS->getSlotIndexes()->getLastIndex());
764 for (
auto &V : Largest)
774 *Runner->
getTensor<
float>(FeatureIDs::progress) =
775 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
778 size_t CandidatePos = tryFindEvictionCandidatePosition(
779 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
782 assert(Regs[CandidatePos].second);
784 assert(!MustFindEviction);
787 assert(CandidatePos < ValidPosLimit);
789 return Regs[CandidatePos].first;
792const LIFeatureComponents &
793MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
795 LIFeatureComponents
Empty;
796 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
797 LIFeatureComponents &
Ret =
I.first->getSecond();
805 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
806 E =
MRI->reg_instr_nodbg_end();
814 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
818 std::tie(Reads,
Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
821 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
827 auto *
MBB =
MI->getParent();
831 if (
Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
832 Ret.IndVarUpdates += Freq;
835 Ret.HintWeights += Freq;
844void MLEvictAdvisor::extractFeatures(
847 int64_t LocalIntfsCount,
float NrUrgent,
849 int64_t NrDefsAndUses = 0;
850 int64_t NrBrokenHints = 0;
854 double IndVarUpdates = 0.0;
855 double HintWeights = 0.0;
856 float StartBBFreq = 0.0;
857 float EndBBFreq = 0.0;
858 float HottestBlockFreq = 0.0;
859 int32_t NrRematerializable = 0;
860 float TotalWeight = 0.0;
862 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
863 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
864 int64_t MaxStage = 0;
866 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
868 for (
const auto *L : Intervals) {
870 MaxStage = std::max<int64_t>(
871 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
872 MinStage = std::min<int64_t>(
873 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
875 TotalWeight = std::max(TotalWeight, LI.
weight());
882 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
883 NrBrokenHints += VRM->hasPreferredPhys(LI.
reg());
885 NrDefsAndUses += LIFC.NrDefsAndUses;
886 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
891 IndVarUpdates += LIFC.IndVarUpdates;
893 HintWeights += LIFC.HintWeights;
894 NrRematerializable += LIFC.IsRemat;
897 for (
auto CurrentSegment : LI) {
904 if (!Intervals.empty()) {
907 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
908 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
914#define SET(ID, TYPE, VAL) \
916 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
917 if (!DoNotNormalize.test(FeatureIDs::ID)) \
918 Largest[FeatureIDs::ID] = \
919 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
921 SET(mask, int64_t, 1);
922 SET(is_free, int64_t, Intervals.empty());
923 SET(nr_urgent,
float, NrUrgent);
924 SET(nr_broken_hints,
float, NrBrokenHints);
925 SET(is_hint, int64_t, IsHint);
926 SET(is_local, int64_t, LocalIntfsCount);
927 SET(nr_rematerializable,
float, NrRematerializable);
928 SET(nr_defs_and_uses,
float, NrDefsAndUses);
929 SET(weighed_reads_by_max,
float, R);
930 SET(weighed_writes_by_max,
float, W);
931 SET(weighed_read_writes_by_max,
float, RW);
932 SET(weighed_indvars_by_max,
float, IndVarUpdates);
933 SET(hint_weights_by_max,
float, HintWeights);
934 SET(start_bb_freq_by_max,
float, StartBBFreq);
935 SET(end_bb_freq_by_max,
float, EndBBFreq);
936 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
937 SET(liverange_size,
float,
Size);
938 SET(use_def_density,
float, TotalWeight);
939 SET(max_stage, int64_t, MaxStage);
940 SET(min_stage, int64_t, MinStage);
949 const int InstructionsIndex,
const int InstructionsMappingIndex,
950 const int MBBFreqIndex,
const int MBBMappingIndex,
970 size_t InstructionIndex = 0;
971 size_t CurrentSegmentIndex = 0;
972 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
973 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
974 size_t CurrentMBBIndex = 0;
986 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].
End &&
988 int CurrentOpcode = GetOpcode(CurrentIndex);
990 if (CurrentOpcode == -1) {
993 if (CurrentIndex >= LastIndex) {
1000 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1001 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1005 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1006 MBBFreqIndex, MBBMappingIndex);
1008 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1009 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1010 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1012 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1014 InstructionsMappingIndex)[CurrentSegmentPosition *
1016 InstructionIndex] = 1;
1025 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1026 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1027 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1028 auto OverlapCurrentSegmentPosition =
1029 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1030 if (LRPosInfo[OverlapCheckCurrentSegment].
End >= CurrentIndex) {
1032 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1034 InstructionIndex] = 1;
1036 ++OverlapCheckCurrentSegment;
1039 if (CurrentIndex >= LastIndex) {
1046 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1053 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1054 LRPosInfo[CurrentSegmentIndex].
End) {
1055 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1057 ++CurrentSegmentIndex;
1062 const size_t CurrentInstructionIndex,
1063 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1067 const int MBBMappingIndex) {
1068 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1069 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1071 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1074 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1079#ifdef LLVM_HAVE_TFLITE
1082 return new DevelopmentModeEvictionAdvisorAnalysis();
1085int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1087 unsigned OrderLimit, uint8_t CostPerUseLimit,
1090 if (isa<ModelUnderTrainingRunner>(getRunner())) {
1091 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1092 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1094 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1095 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1107 if (TrainingLog.empty())
1112 if (Log->hasObservationInProgress())
1113 Log->logReward<
float>(0.0);
1115 Log->startObservation();
1116 size_t CurrentFeature = 0;
1118 ? FeatureIDs::FeaturesWithDevelopmentCount
1119 : FeatureIDs::FeatureCount;
1120 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1121 Log->logTensorValue(CurrentFeature,
1122 reinterpret_cast<const char *
>(
1123 getRunner().getTensorUntyped(CurrentFeature)));
1125 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(&getRunner()))
1126 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().size();
1127 ++
I, ++CurrentFeature)
1128 Log->logTensorValue(
1130 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1132 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1133 Log->endObservation();
1138 std::optional<float> CachedReward;
1139 auto GetReward = [&]() {
1141 CachedReward =
static_cast<float>(
1144 return *CachedReward;
1147 getAnalysis<RegAllocEvictionAdvisorAnalysis>().logRewardIfNeeded(MF,
1149 getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
1156 return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
1158 ?
new ReleaseModeEvictionAdvisorAnalysis()
1163#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
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
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
static const TensorSpec DecisionSpec
RegAllocScore calculateRegAllocScore(const MachineFunction &MF, const MachineBlockFrequencyInfo &MBFI)
Calculate a score.
auto reverse(ContainerTy &&C)
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
Implement std::hash so that hash_code can be used in STL containers.