19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)
47#define DEBUG_TYPE "ml-regalloc"
50#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)
51#include "RegAllocEvictModel.h"
58 "regalloc-evict-interactive-channel-base",
cl::Hidden,
60 "Base file path for the interactive mode. The incoming filename should "
61 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
62 "outgoing name should be "
63 "<regalloc-evict-interactive-channel-base>.out"));
66#ifdef LLVM_HAVE_TFLITE
72 cl::desc(
"Training log for the register allocator eviction model"));
76 cl::desc(
"The model being trained for register allocation eviction"));
79 "regalloc-enable-development-features",
cl::Hidden,
80 cl::desc(
"Whether or not to enable features under development for the ML "
104 return "Register Allocation Pass Scoring";
126 "Register Allocation Scoring Pass",
false,
false)
134static const int OpcodeValueCutoff = 17716;
158#define RA_EVICT_FEATURES_LIST(M) \
159 M(int64_t, mask, PerLiveRangeShape, \
160 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
162 "can't be evicted)") \
163 M(int64_t, is_free, PerLiveRangeShape, \
164 "boolean values, 1 if this phys reg is actually free (no interferences)") \
165 M(float, nr_urgent, PerLiveRangeShape, \
166 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
167 "to break cascades") \
168 M(float, nr_broken_hints, PerLiveRangeShape, \
169 "if this position were evicted, how many broken hints would there be") \
170 M(int64_t, is_hint, PerLiveRangeShape, \
171 "is this a preferred phys reg for the candidate") \
172 M(int64_t, is_local, PerLiveRangeShape, \
173 "is this live range local to a basic block") \
174 M(float, nr_rematerializable, PerLiveRangeShape, \
175 "nr rematerializable ranges") \
176 M(float, nr_defs_and_uses, PerLiveRangeShape, \
177 "bb freq - weighed nr defs and uses") \
178 M(float, weighed_reads_by_max, PerLiveRangeShape, \
179 "bb freq - weighed nr of reads, normalized") \
180 M(float, weighed_writes_by_max, PerLiveRangeShape, \
181 "bb feq - weighed nr of writes, normalized") \
182 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
183 "bb freq - weighed nr of uses that are both read and writes, normalized") \
184 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
185 "bb freq - weighed nr of uses that are indvars, normalized") \
186 M(float, hint_weights_by_max, PerLiveRangeShape, \
187 "bb freq - weighed nr of uses that are hints, normalized") \
188 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
189 "the freq in the start block, normalized") \
190 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
191 "freq of end block, normalized") \
192 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
193 "hottest BB freq, normalized") \
194 M(float, liverange_size, PerLiveRangeShape, \
195 "size (instr index diff) of the LR") \
196 M(float, use_def_density, PerLiveRangeShape, \
197 "the max weight, as computed by the manual heuristic") \
198 M(int64_t, max_stage, PerLiveRangeShape, \
199 "largest stage of an interval in this LR") \
200 M(int64_t, min_stage, PerLiveRangeShape, \
201 "lowest stage of an interval in this LR") \
202 M(float, progress, {1}, "ratio of current queue size to initial size")
204#ifdef LLVM_HAVE_TFLITE
205#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M) \
206 M(int64_t, instructions, InstructionsShape, \
207 "Opcodes of the instructions covered by the eviction problem")
209#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M) \
210 M(int64_t, instructions_mapping, InstructionsMappingShape, \
211 "A binary matrix mapping LRs to instruction opcodes") \
212 M(float, mbb_frequencies, MBBFrequencyShape, \
213 "A vector of machine basic block frequencies") \
214 M(int64_t, mbb_mapping, InstructionsShape, \
215 "A vector of indicies mapping instructions to MBBs")
217#define RA_EVICT_FIRST_DEVELOPMENT_FEATURE(M)
218#define RA_EVICT_REST_DEVELOPMENT_FEATURES(M)
225#define DecisionName "index_to_evict"
231#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
232#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
234#ifdef LLVM_HAVE_TFLITE
241#undef _FEATURE_IDX_SIMPLE
248template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
249 size_t Ret =
sizeof(
T);
250 for (
const auto V : Shape)
256#define _RESET(TYPE, NAME, SHAPE, __) \
257 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
258 getTotalSize<TYPE>(SHAPE));
269struct LIFeatureComponents {
273 double IndVarUpdates = 0;
274 double HintWeights = 0.0;
275 int64_t NrDefsAndUses = 0;
276 float HottestBlockFreq = 0.0;
277 bool IsRemat =
false;
280using CandidateRegList =
282using FeaturesListNormalizer =
306 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
308 unsigned OrderLimit, uint8_t CostPerUseLimit,
324 uint8_t CostPerUseLimit,
329 int64_t IsHint, int64_t LocalIntfsCount,
float NrUrgent,
337 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
341 const LIFeatureComponents &
355 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
356 const float InitialQSize;
362#define _DECL_FEATURES(type, name, shape, _) \
363 TensorSpec::createSpec<type>(#name, shape),
368class ReleaseModeEvictionAdvisorAnalysis final
371 ReleaseModeEvictionAdvisorAnalysis()
395 std::unique_ptr<RegAllocEvictionAdvisor>
399 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
402 Runner = std::make_unique<InteractiveModelRunner>(
407 return std::make_unique<MLEvictAdvisor>(
408 MF,
RA, Runner.get(), getAnalysis<MachineBlockFrequencyInfo>(),
409 getAnalysis<MachineLoopInfo>());
411 std::unique_ptr<MLModelRunner> Runner;
419#ifdef LLVM_HAVE_TFLITE
420static const TensorSpec Reward = TensorSpec::createSpec<float>(
"reward", {1});
426#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
427 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
429class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
435 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
438 int64_t tryFindEvictionCandidatePosition(
440 unsigned OrderLimit, uint8_t CostPerUseLimit,
446class DevelopmentModeEvictionAdvisorAnalysis final
449 DevelopmentModeEvictionAdvisorAnalysis()
455 TrainingInputFeatures = {
459 TensorSpec::createSpec<float>(
"action_discount", {1}),
460 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
461 TensorSpec::createSpec<float>(
"action_reward", {1})};
464 TrainingInputFeatures = {
466 TensorSpec::createSpec<float>(
"action_discount", {1}),
467 TensorSpec::createSpec<int32_t>(
"action_step_type", {1}),
468 TensorSpec::createSpec<float>(
"action_reward", {1})};
478 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
484 if (Log->currentContext() != MF.
getName()) {
486 "The training log context shouldn't have had changed.");
488 if (Log->hasObservationInProgress())
489 Log->logReward<
float>(GetReward());
494 std::vector<TensorSpec> TrainingInputFeatures;
504 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
505 Ctx.
emitError(
"Regalloc development mode should be requested with at "
506 "least logging enabled and/or a training model");
509 if (ModelUnderTraining.empty())
510 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
512 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
513 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
515 Ctx.
emitError(
"Regalloc: could not set up the model runner");
518 if (TrainingLog.empty())
521 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
523 M.getContext().emitError(EC.message() +
":" + TrainingLog);
527 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
534 Log = std::make_unique<Logger>(std::move(
OS), LFS, Reward,
539 std::unique_ptr<RegAllocEvictionAdvisor>
544 Log->switchContext(MF.
getName());
545 return std::make_unique<DevelopmentModeEvictAdvisor>(
546 MF,
RA, Runner.get(), getAnalysis<MachineBlockFrequencyInfo>(),
547 getAnalysis<MachineLoopInfo>(), Log.get());
550 std::unique_ptr<MLModelRunner> Runner;
551 std::unique_ptr<Logger> Log;
560 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
562 if (
MRI.reg_nodbg_empty(Reg))
575 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
578 DoNotNormalize.set(FeatureIDs::mask);
579 DoNotNormalize.set(FeatureIDs::is_free);
580 DoNotNormalize.set(FeatureIDs::is_hint);
581 DoNotNormalize.set(FeatureIDs::is_local);
582 DoNotNormalize.set(FeatureIDs::min_stage);
583 DoNotNormalize.set(FeatureIDs::max_stage);
584 DoNotNormalize.set(FeatureIDs::progress);
587int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
596bool MLEvictAdvisor::loadInterferenceFeatures(
607 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
608 int64_t LocalIntfs = 0;
609 float NrUrgent = 0.0f;
612 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
620 if (IFIntervals.empty() && InterferingIntervals.
empty())
624 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
626 assert(Intf->reg().isVirtual() &&
627 "Only expecting virtual register interference from query");
634 if (FixedRegisters.
count(Intf->reg()))
636 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
640 (Intf->isSpillable() ||
641 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
642 RegClassInfo.getNumAllocatableRegs(
643 MRI->getRegClass(Intf->reg())));
645 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
646 if (Cascade <= IntfCascade) {
652 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
653 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
658 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
659 NrUrgent, LRPosInfo);
663MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
665 uint8_t CostPerUseLimit,
const SmallVirtRegSet &FixedRegisters)
const {
666 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
667 if (!MaybeOrderLimit)
669 unsigned OrderLimit = *MaybeOrderLimit;
677 const bool MustFindEviction =
678 (!VirtReg.
isSpillable() && CostPerUseLimit ==
static_cast<uint8_t
>(~0
u));
683 resetInputs(*Runner);
688 CandidateRegList Regs;
689 Regs.fill({0,
false});
695 FeaturesListNormalizer Largest(FeatureIDs::FeatureCount, 0.0);
707 assert(!Regs[Pos].second);
709 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
712 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
713 Largest, Pos, LRPosInfo)) {
715 Regs[Pos] = std::make_pair(PhysReg,
true);
720 assert(!MustFindEviction);
723 const size_t ValidPosLimit = Pos;
727 if (!MustFindEviction)
732 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
733 "nothing to allocate initially.");
734#ifdef LLVM_HAVE_TFLITE
739 auto *CurrentMachineInstruction =
740 LIS->getInstructionFromIndex(InputIndex);
741 if (!CurrentMachineInstruction) {
744 return CurrentMachineInstruction->getOpcode();
747 auto *CurrentMachineInstruction =
748 LIS->getInstructionFromIndex(InputIndex);
750 CurrentMachineInstruction->getParent());
753 auto *CurrentMachineInstruction =
754 LIS->getInstructionFromIndex(InputIndex);
755 return CurrentMachineInstruction->
getParent();
757 FeatureIDs::instructions, FeatureIDs::instructions_mapping,
758 FeatureIDs::mbb_frequencies, FeatureIDs::mbb_mapping,
759 LIS->getSlotIndexes()->getLastIndex());
763 for (
auto &V : Largest)
773 *Runner->
getTensor<
float>(FeatureIDs::progress) =
774 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
777 size_t CandidatePos = tryFindEvictionCandidatePosition(
778 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
781 assert(Regs[CandidatePos].second);
783 assert(!MustFindEviction);
786 assert(CandidatePos < ValidPosLimit);
788 return Regs[CandidatePos].first;
791const LIFeatureComponents &
792MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
794 LIFeatureComponents
Empty;
795 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
796 LIFeatureComponents &
Ret =
I.first->getSecond();
804 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
805 E =
MRI->reg_instr_nodbg_end();
813 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
817 std::tie(Reads,
Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
820 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
826 auto *
MBB =
MI->getParent();
830 if (
Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
831 Ret.IndVarUpdates += Freq;
834 Ret.HintWeights += Freq;
843void MLEvictAdvisor::extractFeatures(
846 int64_t LocalIntfsCount,
float NrUrgent,
848 int64_t NrDefsAndUses = 0;
849 int64_t NrBrokenHints = 0;
853 double IndVarUpdates = 0.0;
854 double HintWeights = 0.0;
855 float StartBBFreq = 0.0;
856 float EndBBFreq = 0.0;
857 float HottestBlockFreq = 0.0;
858 int32_t NrRematerializable = 0;
859 float TotalWeight = 0.0;
861 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
862 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
863 int64_t MaxStage = 0;
865 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
867 for (
const auto *L : Intervals) {
869 MaxStage = std::max<int64_t>(
870 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
871 MinStage = std::min<int64_t>(
872 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
874 TotalWeight = std::max(TotalWeight, LI.
weight());
881 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
882 NrBrokenHints += VRM->hasPreferredPhys(LI.
reg());
884 NrDefsAndUses += LIFC.NrDefsAndUses;
885 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
890 IndVarUpdates += LIFC.IndVarUpdates;
892 HintWeights += LIFC.HintWeights;
893 NrRematerializable += LIFC.IsRemat;
896 for (
auto CurrentSegment : LI) {
903 if (!Intervals.empty()) {
906 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
907 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
913#define SET(ID, TYPE, VAL) \
915 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
916 if (!DoNotNormalize.test(FeatureIDs::ID)) \
917 Largest[FeatureIDs::ID] = \
918 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
920 SET(mask, int64_t, 1);
921 SET(is_free, int64_t, Intervals.empty());
922 SET(nr_urgent,
float, NrUrgent);
923 SET(nr_broken_hints,
float, NrBrokenHints);
924 SET(is_hint, int64_t, IsHint);
925 SET(is_local, int64_t, LocalIntfsCount);
926 SET(nr_rematerializable,
float, NrRematerializable);
927 SET(nr_defs_and_uses,
float, NrDefsAndUses);
928 SET(weighed_reads_by_max,
float, R);
929 SET(weighed_writes_by_max,
float, W);
930 SET(weighed_read_writes_by_max,
float, RW);
931 SET(weighed_indvars_by_max,
float, IndVarUpdates);
932 SET(hint_weights_by_max,
float, HintWeights);
933 SET(start_bb_freq_by_max,
float, StartBBFreq);
934 SET(end_bb_freq_by_max,
float, EndBBFreq);
935 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
936 SET(liverange_size,
float,
Size);
937 SET(use_def_density,
float, TotalWeight);
938 SET(max_stage, int64_t, MaxStage);
939 SET(min_stage, int64_t, MinStage);
948 const int InstructionsIndex,
const int InstructionsMappingIndex,
949 const int MBBFreqIndex,
const int MBBMappingIndex,
969 size_t InstructionIndex = 0;
970 size_t CurrentSegmentIndex = 0;
971 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
972 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
973 size_t CurrentMBBIndex = 0;
985 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].
End &&
987 int CurrentOpcode = GetOpcode(CurrentIndex);
989 if (CurrentOpcode == -1) {
992 if (CurrentIndex >= LastIndex) {
999 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1000 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1004 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1005 MBBFreqIndex, MBBMappingIndex);
1007 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1008 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1009 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1011 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1013 InstructionsMappingIndex)[CurrentSegmentPosition *
1015 InstructionIndex] = 1;
1024 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1025 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1026 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1027 auto OverlapCurrentSegmentPosition =
1028 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1029 if (LRPosInfo[OverlapCheckCurrentSegment].
End >= CurrentIndex) {
1031 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1033 InstructionIndex] = 1;
1035 ++OverlapCheckCurrentSegment;
1038 if (CurrentIndex >= LastIndex) {
1045 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1052 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1053 LRPosInfo[CurrentSegmentIndex].
End) {
1054 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1056 ++CurrentSegmentIndex;
1061 const size_t CurrentInstructionIndex,
1062 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1066 const int MBBMappingIndex) {
1067 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1068 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1070 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1073 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1078#ifdef LLVM_HAVE_TFLITE
1081 return new DevelopmentModeEvictionAdvisorAnalysis();
1084int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1086 unsigned OrderLimit, uint8_t CostPerUseLimit,
1089 if (isa<ModelUnderTrainingRunner>(getRunner())) {
1090 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1091 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1093 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1094 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1106 if (TrainingLog.empty())
1111 if (Log->hasObservationInProgress())
1112 Log->logReward<
float>(0.0);
1114 Log->startObservation();
1115 size_t CurrentFeature = 0;
1117 ? FeatureIDs::FeaturesWithDevelopmentCount
1118 : FeatureIDs::FeatureCount;
1119 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1120 Log->logTensorValue(CurrentFeature,
1121 reinterpret_cast<const char *
>(
1122 getRunner().getTensorUntyped(CurrentFeature)));
1124 if (
auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(&getRunner()))
1125 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().size();
1126 ++
I, ++CurrentFeature)
1127 Log->logTensorValue(
1129 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1131 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1132 Log->endObservation();
1137 std::optional<float> CachedReward;
1138 auto GetReward = [&]() {
1140 CachedReward =
static_cast<float>(
1143 return *CachedReward;
1146 getAnalysis<RegAllocEvictionAdvisorAnalysis>().logRewardIfNeeded(MF,
1148 getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
1155 return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
1157 ?
new ReleaseModeEvictionAdvisorAnalysis()
1162#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.
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.