19#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL) || defined(LLVM_HAVE_TFLITE)
45#include <unordered_map>
49#define DEBUG_TYPE "ml-regalloc"
52#if defined(LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL)
53#include "RegAllocEvictModel.h"
60 "regalloc-evict-interactive-channel-base",
cl::Hidden,
62 "Base file path for the interactive mode. The incoming filename should "
63 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
64 "outgoing name should be "
65 "<regalloc-evict-interactive-channel-base>.out"));
69 cl::desc(
"The maximum number of times a live range can be "
70 "evicted before preventing it from being evicted"),
74#ifdef LLVM_HAVE_TFLITE
80 cl::desc(
"Training log for the register allocator eviction model"));
84 cl::desc(
"The model being trained for register allocation eviction"));
100 RegAllocScoring() : MachineFunctionPass(ID) {
104 ~RegAllocScoring()
override =
default;
106 StringRef getPassName()
const override {
107 return "Register Allocation Pass Scoring";
111 void getAnalysisUsage(AnalysisUsage &AU)
const override {
113 AU.
addRequired<RegAllocEvictionAdvisorAnalysisLegacy>();
114 AU.
addRequired<RegAllocPriorityAdvisorAnalysisLegacy>();
115 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
120 bool runOnMachineFunction(MachineFunction &)
override;
124char RegAllocScoring::ID = 0;
126 return new RegAllocScoring();
130 "Register Allocation Scoring Pass",
false,
false)
138static const int OpcodeValueCutoff = 17716;
162#define RA_EVICT_FEATURES_LIST(M) \
163 M(int64_t, mask, PerLiveRangeShape, \
164 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
166 "can't be evicted)") \
167 M(int64_t, is_free, PerLiveRangeShape, \
168 "boolean values, 1 if this phys reg is actually free (no interferences)") \
169 M(float, nr_urgent, PerLiveRangeShape, \
170 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
171 "to break cascades") \
172 M(float, nr_broken_hints, PerLiveRangeShape, \
173 "if this position were evicted, how many broken hints would there be") \
174 M(int64_t, is_hint, PerLiveRangeShape, \
175 "is this a preferred phys reg for the candidate") \
176 M(int64_t, is_local, PerLiveRangeShape, \
177 "is this live range local to a basic block") \
178 M(float, nr_rematerializable, PerLiveRangeShape, \
179 "nr rematerializable ranges") \
180 M(float, nr_defs_and_uses, PerLiveRangeShape, \
181 "bb freq - weighed nr defs and uses") \
182 M(float, weighed_reads_by_max, PerLiveRangeShape, \
183 "bb freq - weighed nr of reads, normalized") \
184 M(float, weighed_writes_by_max, PerLiveRangeShape, \
185 "bb feq - weighed nr of writes, normalized") \
186 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
187 "bb freq - weighed nr of uses that are both read and writes, normalized") \
188 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
189 "bb freq - weighed nr of uses that are indvars, normalized") \
190 M(float, hint_weights_by_max, PerLiveRangeShape, \
191 "bb freq - weighed nr of uses that are hints, normalized") \
192 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
193 "the freq in the start block, normalized") \
194 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
195 "freq of end block, normalized") \
196 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
197 "hottest BB freq, normalized") \
198 M(float, liverange_size, PerLiveRangeShape, \
199 "size (instr index diff) of the LR") \
200 M(float, use_def_density, PerLiveRangeShape, \
201 "the max weight, as computed by the manual heuristic") \
202 M(int64_t, max_stage, PerLiveRangeShape, \
203 "largest stage of an interval in this LR") \
204 M(int64_t, min_stage, PerLiveRangeShape, \
205 "lowest stage of an interval in this LR") \
206 M(float, progress, {1}, "ratio of current queue size to initial size")
212#define DecisionName "index_to_evict"
218#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
219#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
222#undef _FEATURE_IDX_SIMPLE
229template <
typename T>
size_t getTotalSize(
const std::vector<int64_t> &Shape) {
230 size_t Ret =
sizeof(
T);
231 for (
const auto V : Shape)
237#define _RESET(TYPE, NAME, SHAPE, __) \
238 std::memset(Runner.getTensorUntyped(FeatureIDs::NAME), 0, \
239 getTotalSize<TYPE>(SHAPE));
246struct LIFeatureComponents {
250 double IndVarUpdates = 0;
251 double HintWeights = 0.0;
252 int64_t NumDefsAndUses = 0;
253 float HottestBlockFreq = 0.0;
254 bool IsRemat =
false;
257using CandidateRegList =
259using FeaturesListNormalizer =
283 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
285 unsigned OrderLimit,
uint8_t CostPerUseLimit,
306 int64_t IsHint, int64_t LocalIntfsCount,
float NumUrgent,
314 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
318 const LIFeatureComponents &
332 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
333 const float InitialQSize;
338 mutable std::unordered_map<unsigned, unsigned> VirtRegEvictionCounts;
340 void onEviction(
Register RegBeingEvicted)
const {
344 ++VirtRegEvictionCounts[RegBeingEvicted.
id()];
348 auto EvictionCountIt = VirtRegEvictionCounts.find(
Reg.id());
349 if (EvictionCountIt != VirtRegEvictionCounts.end())
350 return EvictionCountIt->second;
355#define _DECL_FEATURES(type, name, shape, _) \
356 TensorSpec::createSpec<type>(#name, shape),
362class ReleaseModeEvictionAdvisorProvider final
365 ReleaseModeEvictionAdvisorProvider(
LLVMContext &Ctx)
371 return R->getAdvisorMode() == AdvisorMode::Release;
374 std::unique_ptr<RegAllocEvictionAdvisor>
379 Runner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
382 Runner = std::make_unique<InteractiveModelRunner>(
388 "Invalid provider state: must have analysis available");
389 return std::make_unique<MLEvictAdvisor>(MF,
RA, Runner.get(), *MBFI,
395 std::unique_ptr<MLModelRunner> Runner;
398class ReleaseModeEvictionAdvisorAnalysisLegacy final
401 ReleaseModeEvictionAdvisorAnalysisLegacy()
411 std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
416 return R->getAdvisorMode() == AdvisorMode::Release;
431#ifdef LLVM_HAVE_TFLITE
438#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
439 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
441class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
447 : MLEvictAdvisor(MF,
RA, Runner, MBFI,
Loops), Log(Log) {}
450 int64_t tryFindEvictionCandidatePosition(
452 unsigned OrderLimit,
uint8_t CostPerUseLimit,
458class DevelopmentModeEvictionAdvisorProvider final
461 DevelopmentModeEvictionAdvisorProvider(
LLVMContext &Ctx)
464 TrainingInputFeatures = {
469 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
470 Ctx.emitError(
"Regalloc development mode should be requested with at "
471 "least logging enabled and/or a training model");
474 if (ModelUnderTraining.empty())
475 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
477 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
478 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
480 Ctx.emitError(
"Regalloc: could not set up the model runner");
483 if (TrainingLog.empty())
486 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
488 Ctx.emitError(EC.message() +
":" + TrainingLog);
499 Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
506 return R->getAdvisorMode() == AdvisorMode::Development;
511 if (!Log || !Log->hasAnyObservationForContext(MF.
getName()))
517 if (Log->currentContext() != MF.
getName()) {
519 "The training log context shouldn't have had changed.");
521 if (Log->hasObservationInProgress())
522 Log->logReward<
float>(GetReward());
525 std::unique_ptr<RegAllocEvictionAdvisor>
531 Log->switchContext(MF.
getName());
533 "Invalid provider state: must have analysis available");
534 return std::make_unique<DevelopmentModeEvictAdvisor>(
535 MF,
RA, Runner.get(), *MBFI, *
Loops, Log.get());
540 std::vector<TensorSpec> TrainingInputFeatures;
542 std::unique_ptr<MLModelRunner> Runner;
543 std::unique_ptr<Logger> Log;
546class DevelopmentModeEvictionAdvisorAnalysisLegacy final
549 DevelopmentModeEvictionAdvisorAnalysisLegacy()
553 Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
560 Provider->logRewardIfNeeded(MF, GetReward);
565 return R->getAdvisorMode() == AdvisorMode::Development;
580 unsigned NumUsedRegs = 0;
581 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
583 if (!
MRI.reg_nodbg_empty(
Reg))
586 return static_cast<float>(NumUsedRegs);
595 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
598 DoNotNormalize.set(FeatureIDs::mask);
599 DoNotNormalize.set(FeatureIDs::is_free);
600 DoNotNormalize.set(FeatureIDs::is_hint);
601 DoNotNormalize.set(FeatureIDs::is_local);
602 DoNotNormalize.set(FeatureIDs::min_stage);
603 DoNotNormalize.set(FeatureIDs::max_stage);
604 DoNotNormalize.set(FeatureIDs::progress);
607int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
616bool MLEvictAdvisor::loadInterferenceFeatures(
627 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
628 int64_t LocalIntfs = 0;
629 float NumUrgent = 0.0f;
632 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
640 if (IFIntervals.empty() && InterferingIntervals.
empty())
644 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
646 assert(Intf->reg().isVirtual() &&
647 "Only expecting virtual register interference from query");
654 if (FixedRegisters.
count(Intf->reg()))
656 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
660 (Intf->isSpillable() ||
661 RegClassInfo.getNumAllocatableRegs(
MRI->getRegClass(VirtReg.
reg())) <
662 RegClassInfo.getNumAllocatableRegs(
663 MRI->getRegClass(Intf->reg())));
665 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
676 if (Cascade <= IntfCascade) {
682 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
683 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
688 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
689 NumUrgent, LRPosInfo);
693MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
696 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
697 if (!MaybeOrderLimit)
699 unsigned OrderLimit = *MaybeOrderLimit;
707 const bool MustFindEviction =
713 resetInputs(*Runner);
718 CandidateRegList Regs;
719 Regs.fill({0,
false});
737 assert(!Regs[Pos].second);
739 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
742 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
743 Largest, Pos, LRPosInfo)) {
745 Regs[Pos] = std::make_pair(PhysReg,
true);
750 assert(!MustFindEviction);
753 const size_t ValidPosLimit = Pos;
757 if (!MustFindEviction)
762 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
763 "nothing to allocate initially.");
765 for (
auto &V : Largest)
775 *Runner->
getTensor<
float>(FeatureIDs::progress) =
776 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
779 size_t CandidatePos = tryFindEvictionCandidatePosition(
780 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
783 assert(Regs[CandidatePos].second);
785 onEviction(VirtReg.
reg());
786 assert(!MustFindEviction);
789 assert(CandidatePos < ValidPosLimit);
795 for (
MCRegUnit Unit :
TRI->regunits(Regs[CandidatePos].first)) {
799 onEviction(Intf->reg());
803 return Regs[CandidatePos].first;
806const LIFeatureComponents &
807MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
809 LIFeatureComponents
Empty;
810 auto I = CachedFeatures.insert(std::make_pair(
ID,
Empty));
811 LIFeatureComponents &
Ret =
I.first->getSecond();
819 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
820 E =
MRI->reg_instr_nodbg_end();
824 ++
Ret.NumDefsAndUses;
828 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
832 std::tie(Reads, Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
835 Ret.HottestBlockFreq = std::max(Freq,
Ret.HottestBlockFreq);
837 Ret.R += (Reads && !Writes) * Freq;
838 Ret.W += (!Reads && Writes) * Freq;
839 Ret.RW += (Reads && Writes) * Freq;
841 auto *
MBB =
MI->getParent();
845 if (Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
846 Ret.IndVarUpdates += Freq;
849 Ret.HintWeights += Freq;
858void MLEvictAdvisor::extractFeatures(
861 int64_t LocalIntfsCount,
float NumUrgent,
863 int64_t NumDefsAndUses = 0;
864 int64_t NumBrokenHints = 0;
868 double IndVarUpdates = 0.0;
869 double HintWeights = 0.0;
870 float StartBBFreq = 0.0;
871 float EndBBFreq = 0.0;
872 float HottestBlockFreq = 0.0;
873 int32_t NumRematerializable = 0;
874 float TotalWeight = 0.0;
876 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
877 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
878 int64_t MaxStage = 0;
880 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
882 for (
const auto *L : Intervals) {
884 MaxStage = std::max<int64_t>(
885 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
886 MinStage = std::min<int64_t>(
887 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
889 TotalWeight = std::max(TotalWeight, LI.
weight());
896 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
897 NumBrokenHints += VRM->hasPreferredPhys(LI.
reg());
899 NumDefsAndUses += LIFC.NumDefsAndUses;
900 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
905 IndVarUpdates += LIFC.IndVarUpdates;
907 HintWeights += LIFC.HintWeights;
908 NumRematerializable += LIFC.IsRemat;
911 if (!Intervals.empty()) {
914 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
915 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
921#define SET(ID, TYPE, VAL) \
923 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
924 if (!DoNotNormalize.test(FeatureIDs::ID)) \
925 Largest[FeatureIDs::ID] = \
926 std::max(Largest[FeatureIDs::ID], static_cast<float>(VAL)); \
929 SET(is_free, int64_t, Intervals.empty());
930 SET(nr_urgent,
float, NumUrgent);
931 SET(nr_broken_hints,
float, NumBrokenHints);
932 SET(is_hint, int64_t, IsHint);
933 SET(is_local, int64_t, LocalIntfsCount);
934 SET(nr_rematerializable,
float, NumRematerializable);
935 SET(nr_defs_and_uses,
float, NumDefsAndUses);
936 SET(weighed_reads_by_max,
float, R);
937 SET(weighed_writes_by_max,
float, W);
938 SET(weighed_read_writes_by_max,
float, RW);
939 SET(weighed_indvars_by_max,
float, IndVarUpdates);
940 SET(hint_weights_by_max,
float, HintWeights);
941 SET(start_bb_freq_by_max,
float, StartBBFreq);
942 SET(end_bb_freq_by_max,
float, EndBBFreq);
943 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
944 SET(liverange_size,
float,
Size);
945 SET(use_def_density,
float, TotalWeight);
946 SET(max_stage, int64_t, MaxStage);
947 SET(min_stage, int64_t, MinStage);
956 const int InstructionsIndex,
const int InstructionsMappingIndex,
957 const int MBBFreqIndex,
const int MBBMappingIndex,
977 size_t InstructionIndex = 0;
978 size_t CurrentSegmentIndex = 0;
979 SlotIndex CurrentIndex = LRPosInfo[0].Begin;
980 std::map<MachineBasicBlock *, size_t> VisitedMBBs;
981 size_t CurrentMBBIndex = 0;
993 while (CurrentIndex <= LRPosInfo[CurrentSegmentIndex].End &&
995 int CurrentOpcode = GetOpcode(CurrentIndex);
997 if (CurrentOpcode == -1) {
1000 if (CurrentIndex >= LastIndex) {
1007 if (VisitedMBBs.count(CurrentMBBReference) == 0) {
1008 VisitedMBBs[CurrentMBBReference] = CurrentMBBIndex;
1012 GetMBBFreq, CurrentMBBReference, RegallocRunner,
1013 MBBFreqIndex, MBBMappingIndex);
1015 assert(LRPosInfo[CurrentSegmentIndex].Begin <= CurrentIndex);
1016 RegallocRunner->
getTensor<int64_t>(InstructionsIndex)[InstructionIndex] =
1017 CurrentOpcode < OpcodeValueCutoff ? CurrentOpcode : 0;
1019 auto CurrentSegmentPosition = LRPosInfo[CurrentSegmentIndex].Pos;
1021 InstructionsMappingIndex)[CurrentSegmentPosition *
1023 InstructionIndex] = 1;
1032 size_t OverlapCheckCurrentSegment = CurrentSegmentIndex + 1;
1033 while (OverlapCheckCurrentSegment < LRPosInfo.
size() &&
1034 LRPosInfo[OverlapCheckCurrentSegment].Begin <= CurrentIndex) {
1035 auto OverlapCurrentSegmentPosition =
1036 LRPosInfo[OverlapCheckCurrentSegment].Pos;
1037 if (LRPosInfo[OverlapCheckCurrentSegment].End >= CurrentIndex) {
1039 InstructionsMappingIndex)[OverlapCurrentSegmentPosition *
1041 InstructionIndex] = 1;
1043 ++OverlapCheckCurrentSegment;
1046 if (CurrentIndex >= LastIndex) {
1053 if (CurrentSegmentIndex == LRPosInfo.
size() - 1 ||
1060 if (LRPosInfo[CurrentSegmentIndex + 1].Begin >
1061 LRPosInfo[CurrentSegmentIndex].End) {
1062 CurrentIndex = LRPosInfo[CurrentSegmentIndex + 1].Begin;
1064 ++CurrentSegmentIndex;
1069 const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
1070 std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
1073 const int MBBFreqIndex,
const int MBBMappingIndex) {
1074 size_t CurrentMBBIndex = VisitedMBBs[CurrentMBBReference];
1075 float CurrentMBBFreq = GetMBBFreq(CurrentIndex);
1077 RegallocRunner->
getTensor<
float>(MBBFreqIndex)[CurrentMBBIndex] =
1080 MBBMappingIndex)[CurrentInstructionIndex] = CurrentMBBIndex;
1085#ifdef LLVM_HAVE_TFLITE
1089 return new DevelopmentModeEvictionAdvisorAnalysisLegacy();
1092int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1094 unsigned OrderLimit,
uint8_t CostPerUseLimit,
1098 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1099 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1101 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1102 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1114 if (TrainingLog.empty())
1119 if (Log->hasObservationInProgress())
1120 Log->logReward<
float>(0.0);
1122 Log->startObservation();
1123 size_t CurrentFeature = 0;
1125 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1126 Log->logTensorValue(CurrentFeature,
1127 reinterpret_cast<const char *
>(
1128 getRunner().getTensorUntyped(CurrentFeature)));
1131 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().
size();
1132 ++
I, ++CurrentFeature)
1133 Log->logTensorValue(
1135 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1137 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1138 Log->endObservation();
1143 std::optional<float> CachedReward;
1144 auto GetReward = [&]() {
1146 CachedReward =
static_cast<float>(
1148 MF, getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI())
1150 return *CachedReward;
1153 getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().logRewardIfNeeded(
1155 getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().logRewardIfNeeded(
1161RegAllocEvictionAdvisorProvider *
1163 return new ReleaseModeEvictionAdvisorProvider(Ctx);
1168#if defined(LLVM_HAVE_TFLITE)
1169 return new DevelopmentModeEvictionAdvisorProvider(Ctx);
1178 ?
new ReleaseModeEvictionAdvisorAnalysisLegacy()
1183#if !defined(LLVM_HAVE_TFLITE)
1184bool RegAllocScoring::runOnMachineFunction(
MachineFunction &) {
return false; }
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr unsigned long long mask(BlockVerifier::State S)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
@ Available
We know the block is fully available. This is a fixpoint.
Module.h This file contains the declarations for the Module class.
NoopSavedModelImpl CompiledModelType
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 cl::opt< unsigned > MaxEvictionCount("mlregalloc-max-eviction-count", cl::Hidden, cl::desc("The maximum number of times a live range can be " "evicted before preventing it from being evicted"), cl::init(100))
#define RA_EVICT_FEATURES_LIST(M)
#define SET(ID, TYPE, VAL)
#define _RESET(TYPE, NAME, SHAPE, __)
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, _)
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
SI optimize exec mask operations pre RA
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
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.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
Query interferences between a single live virtual register and a live interval union.
const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())
LiveInterval - This class represents the liveness of a register, or stack slot.
bool isSpillable() const
isSpillable - Can this interval be spilled?
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
SlotIndex endIndex() const
endNumber - return the maximum point of the range of the whole, exclusive.
@ IK_VirtReg
Virtual register interference.
Logging utility - given an ordered specification of features, and assuming a scalar reward,...
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
Represents a single loop in the control flow graph.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
MLModelRunner interface: abstraction of a mechanism for evaluating a ML model.
virtual void switchContext(StringRef Name)
T * getTensor(I FeatureID)
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_instr_iterator< true, true, true, true > reg_instr_nodbg_iterator
reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk all defs and uses of the sp...
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 LLVM_ABI 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.
virtual void logRewardIfNeeded(const MachineFunction &MF, function_ref< float()> GetReward)
RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode Mode)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Common provider for legacy and new pass managers.
virtual std::unique_ptr< RegAllocEvictionAdvisor > getAdvisor(const MachineFunction &MF, const RAGreedy &RA, MachineBlockFrequencyInfo *MBFI, MachineLoopInfo *Loops)=0
virtual void logRewardIfNeeded(const MachineFunction &MF, llvm::function_ref< float()> GetReward)
RegAllocEvictionAdvisorProvider(AdvisorMode Mode, LLVMContext &Ctx)
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.
LLVM_ABI_FOR_TEST double getScore() const
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.
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
static TensorSpec createSpec(const std::string &Name, const std::vector< int64_t > &Shape, int Port=0)
static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
Determine if all values in LI are rematerializable.
static Register copyHint(const MachineInstr *MI, Register Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)
Return the preferred allocation register for reg, given a COPY instruction.
An efficient, type-erasing, non-owning reference to a callable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool isEmbeddedModelEvaluatorValid()
static const int ModelMaxSupportedInstructionCount
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
SmallSet< Register, 16 > SmallVirtRegSet
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()
static const int64_t ModelMaxSupportedMBBCount
RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI_FOR_TEST void extractInstructionFeatures(llvm::SmallVectorImpl< LRStartEndInfo > &LRPosInfo, MLModelRunner *RegallocRunner, function_ref< int(SlotIndex)> GetOpcode, function_ref< float(SlotIndex)> GetMBBFreq, function_ref< MachineBasicBlock *(SlotIndex)> GetMBBReference, const int InstructionsIndex, const int InstructionsMappingIndex, const int MBBFreqIndex, const int MBBMappingIndex, const SlotIndex LastIndex)
static const TensorSpec DecisionSpec
RegAllocScore calculateRegAllocScore(const MachineFunction &MF, const MachineBlockFrequencyInfo &MBFI)
Calculate a score.
auto reverse(ContainerTy &&C)
LLVM_ABI void initializeRegAllocScoringPass(PassRegistry &)
static const std::vector< TensorSpec > InputFeatures
@ RS_Done
There is nothing more we can do to this live range.
unsigned MCRegUnit
Register units are used to compute register aliasing.
LLVM_ABI FunctionPass * createRegAllocScoringPass()
When learning an eviction policy, extract score(reward) information, otherwise this does nothing.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider * createReleaseModeAdvisorProvider(LLVMContext &Ctx)
LLVM_ABI_FOR_TEST void extractMBBFrequency(const SlotIndex CurrentIndex, const size_t CurrentInstructionIndex, std::map< MachineBasicBlock *, size_t > &VisitedMBBs, function_ref< float(SlotIndex)> GetMBBFreq, MachineBasicBlock *CurrentMBBReference, MLModelRunner *RegallocRunner, const int MBBFreqIndex, const int MBBMappingIndex)
static const int64_t NumberOfInterferences
static const std::vector< int64_t > PerLiveRangeShape
RegAllocEvictionAdvisorAnalysisLegacy * createDevelopmentModeAdvisorAnalysisLegacy()
static const int64_t CandidateVirtRegPos
Implement std::hash so that hash_code can be used in STL containers.