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 indices 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")
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)
INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME, false, false) char RISCVCoalesceVSETVLI const LiveIntervals * LIS
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)
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.
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.