18#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#include "llvm/CodeGen/RegAllocEvictModels.h"
62#define MLGO_MODEL(CLASS_NAME, CLI_FLAG) CLASS_NAME,
63#include "llvm/CodeGen/RegAllocEvictModels.def"
67 "regalloc-mlgo-model",
68 llvm::cl::desc(
"Select the MLGO model to execute for register allocation:"),
71 "Use standard heuristic")
73 ,
clEnumValN(MLGORegAllocModelChoice::CLASS_NAME, CLI_FLAG, \
74 "Use the " CLI_FLAG
" MLGO model")
75#include
"llvm/CodeGen/RegAllocEvictModels.def"
78static std::unique_ptr<MLModelRunner>
84#define MLGO_MODEL(CLASS_NAME, CLI_FLAG) \
85 case MLGORegAllocModelChoice::CLASS_NAME: \
86 return std::make_unique<EmitCModelRunner<CLASS_NAME>>(Ctx, InputFeatures);
87#include "llvm/CodeGen/RegAllocEvictModels.def"
93 "regalloc-evict-interactive-channel-base",
cl::Hidden,
95 "Base file path for the interactive mode. The incoming filename should "
96 "have the name <regalloc-evict-interactive-channel-base>.in, while the "
97 "outgoing name should be "
98 "<regalloc-evict-interactive-channel-base>.out"));
102 cl::desc(
"The maximum number of times a live range can be "
103 "evicted before preventing it from being evicted"),
107 "mlregalloc-num-allocatable-regs",
cl::Hidden,
108 cl::desc(
"The number of eviction candidates the model sees. The model has "
109 "one more column, for the live range seeking allocation"),
113#ifdef LLVM_HAVE_TFLITE
119 cl::desc(
"Training log for the register allocator eviction model"));
123 cl::desc(
"The model being trained for register allocation eviction"));
139 RegAllocScoring() : MachineFunctionPass(ID) {}
141 ~RegAllocScoring()
override =
default;
143 StringRef getPassName()
const override {
144 return "Register Allocation Pass Scoring";
148 void getAnalysisUsage(AnalysisUsage &AU)
const override {
150 AU.
addRequired<RegAllocEvictionAdvisorAnalysisLegacy>();
151 AU.
addRequired<RegAllocPriorityAdvisorAnalysisLegacy>();
152 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
161char RegAllocScoring::ID = 0;
163 return new RegAllocScoring();
167 "Register Allocation Scoring Pass",
false,
false)
191#define RA_EVICT_FEATURES_LIST(M) \
192 M(int64_t, mask, PerLiveRangeShape, \
193 "boolean values, 0 for unavailable candidates (i.e. if a position is 0, " \
195 "can't be evicted)") \
196 M(int64_t, is_free, PerLiveRangeShape, \
197 "boolean values, 1 if this phys reg is actually free (no interferences)") \
198 M(float, nr_urgent, PerLiveRangeShape, \
199 "number of 'urgent' intervals, normalized. Urgent are those that are OK " \
200 "to break cascades") \
201 M(float, nr_broken_hints, PerLiveRangeShape, \
202 "if this position were evicted, how many broken hints would there be") \
203 M(int64_t, is_hint, PerLiveRangeShape, \
204 "is this a preferred phys reg for the candidate") \
205 M(int64_t, is_local, PerLiveRangeShape, \
206 "is this live range local to a basic block") \
207 M(float, nr_rematerializable, PerLiveRangeShape, \
208 "nr rematerializable ranges") \
209 M(float, nr_defs_and_uses, PerLiveRangeShape, \
210 "bb freq - weighed nr defs and uses") \
211 M(float, weighed_reads_by_max, PerLiveRangeShape, \
212 "bb freq - weighed nr of reads, normalized") \
213 M(float, weighed_writes_by_max, PerLiveRangeShape, \
214 "bb feq - weighed nr of writes, normalized") \
215 M(float, weighed_read_writes_by_max, PerLiveRangeShape, \
216 "bb freq - weighed nr of uses that are both read and writes, normalized") \
217 M(float, weighed_indvars_by_max, PerLiveRangeShape, \
218 "bb freq - weighed nr of uses that are indvars, normalized") \
219 M(float, hint_weights_by_max, PerLiveRangeShape, \
220 "bb freq - weighed nr of uses that are hints, normalized") \
221 M(float, start_bb_freq_by_max, PerLiveRangeShape, \
222 "the freq in the start block, normalized") \
223 M(float, end_bb_freq_by_max, PerLiveRangeShape, \
224 "freq of end block, normalized") \
225 M(float, hottest_bb_freq_by_max, PerLiveRangeShape, \
226 "hottest BB freq, normalized") \
227 M(float, liverange_size, PerLiveRangeShape, \
228 "size (instr index diff) of the LR") \
229 M(float, use_def_density, PerLiveRangeShape, \
230 "the max weight, as computed by the manual heuristic") \
231 M(int64_t, max_stage, PerLiveRangeShape, \
232 "largest stage of an interval in this LR") \
233 M(int64_t, min_stage, PerLiveRangeShape, \
234 "lowest stage of an interval in this LR") \
235 M(float, progress, {1}, "ratio of current queue size to initial size")
241#define DecisionName "index_to_evict"
247#define _FEATURE_IDX_SIMPLE(_, name, __, ___) name
248#define _FEATURE_IDX(A, B, C, D) _FEATURE_IDX_SIMPLE(A, B, C, D),
251#undef _FEATURE_IDX_SIMPLE
265struct LIFeatureComponents {
269 double IndVarUpdates = 0;
270 double HintWeights = 0.0;
271 int64_t NumDefsAndUses = 0;
272 float HottestBlockFreq = 0.0;
273 bool IsRemat =
false;
277static constexpr unsigned MaxColumnsCapacityHint = 40;
279using CandidateRegList =
281using FeaturesListNormalizer =
299 const size_t NumColumns;
300 const size_t CandidateVirtRegPos = NumColumns - 1;
311 tryFindEvictionCandidatePosition(
const LiveInterval &VirtReg,
313 unsigned OrderLimit,
uint8_t CostPerUseLimit,
334 int64_t IsHint, int64_t LocalIntfsCount,
float NumUrgent,
342 return getDefaultAdvisor().canEvictHintInterference(VirtReg, PhysReg,
346 const LIFeatureComponents &
360 std::bitset<FeatureIDs::FeatureCount> DoNotNormalize;
361 const float InitialQSize;
368 void onEviction(
Register RegBeingEvicted)
const {
372 ++VirtRegEvictionCounts[RegBeingEvicted.
id()];
376 auto EvictionCountIt = VirtRegEvictionCounts.
find(
Reg.id());
377 if (EvictionCountIt != VirtRegEvictionCounts.
end())
378 return EvictionCountIt->second;
383#define _DECL_FEATURES(type, name, shape, _) \
384 TensorSpec::createSpec<type>(#name, shape),
390class ReleaseModeEvictionAdvisorProvider final
393 ReleaseModeEvictionAdvisorProvider(
LLVMContext &Ctx)
403 return R->getAdvisorMode() == AdvisorMode::Release;
406 std::unique_ptr<RegAllocEvictionAdvisor>
410 "Invalid provider state: must have analysis available");
412 return std::make_unique<DefaultEvictionAdvisor>(MF,
RA);
413 return std::make_unique<MLEvictAdvisor>(MF,
RA, Runner.get(),
InputFeatures,
419 std::unique_ptr<MLModelRunner> Runner;
422class ReleaseModeEvictionAdvisorAnalysisLegacy final
425 ReleaseModeEvictionAdvisorAnalysisLegacy()
435 std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
440 return R->getAdvisorMode() == AdvisorMode::Release;
454#ifdef LLVM_HAVE_TFLITE
461#define _DECL_TRAIN_FEATURES(type, name, shape, _) \
462 TensorSpec::createSpec<type>(std::string("action_") + #name, shape),
464class DevelopmentModeEvictAdvisor :
public MLEvictAdvisor {
474 int64_t tryFindEvictionCandidatePosition(
476 unsigned OrderLimit,
uint8_t CostPerUseLimit,
482class DevelopmentModeEvictionAdvisorProvider final
485 DevelopmentModeEvictionAdvisorProvider(
LLVMContext &Ctx)
490 TrainingInputFeatures = {
495 if (ModelUnderTraining.empty() && TrainingLog.empty()) {
496 Ctx.emitError(
"Regalloc development mode should be requested with at "
497 "least logging enabled and/or a training model");
500 if (ModelUnderTraining.empty())
501 Runner = std::make_unique<NoInferenceModelRunner>(Ctx,
InputFeatures);
503 Runner = ModelUnderTrainingRunner::createAndEnsureValid(
504 Ctx, ModelUnderTraining,
DecisionName, TrainingInputFeatures);
506 Ctx.emitError(
"Regalloc: could not set up the model runner");
509 if (TrainingLog.empty())
512 auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
514 Ctx.emitError(EC.message() +
":" + TrainingLog);
525 Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
532 return R->getAdvisorMode() == AdvisorMode::Development;
539 std::string Ctx = getContextName(MF);
540 if (!Log->hasAnyObservationForContext(Ctx))
546 if (Log->currentContext() != Ctx) {
548 "The training log context shouldn't have had changed.");
550 if (Log->hasObservationInProgress())
551 Log->logReward<
float>(GetReward());
554 std::unique_ptr<RegAllocEvictionAdvisor>
561 Log->switchContext(getContextName(MF));
564 "Invalid provider state: must have analysis available");
565 return std::make_unique<DevelopmentModeEvictAdvisor>(
571 std::vector<TensorSpec> TrainingInputFeatures;
573 std::unique_ptr<MLModelRunner> Runner;
574 std::unique_ptr<Logger> Log;
575 std::optional<unsigned> LastFunctionNumber;
582class DevelopmentModeEvictionAdvisorAnalysisLegacy final
585 DevelopmentModeEvictionAdvisorAnalysisLegacy()
589 Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
596 Provider->logRewardIfNeeded(MF, GetReward);
601 return R->getAdvisorMode() == AdvisorMode::Development;
615 unsigned NumUsedRegs = 0;
616 for (
unsigned I = 0,
E = MRI.getNumVirtRegs();
I !=
E; ++
I) {
618 if (!MRI.reg_nodbg_empty(
Reg))
621 return static_cast<float>(NumUsedRegs);
632 InitialQSize(MLEvictAdvisor::getInitialQueueSize(MF)) {
635 DoNotNormalize.set(FeatureIDs::mask);
636 DoNotNormalize.set(FeatureIDs::is_free);
637 DoNotNormalize.set(FeatureIDs::is_hint);
638 DoNotNormalize.set(FeatureIDs::is_local);
639 DoNotNormalize.set(FeatureIDs::min_stage);
640 DoNotNormalize.set(FeatureIDs::max_stage);
641 DoNotNormalize.set(FeatureIDs::progress);
644int64_t MLEvictAdvisor::tryFindEvictionCandidatePosition(
647 int64_t Ret = Runner->
evaluate<int64_t>();
649 assert(
static_cast<size_t>(Ret) <= CandidateVirtRegPos);
653bool MLEvictAdvisor::loadInterferenceFeatures(
664 const bool IsLocal = LIS->intervalIsInOneMBB(VirtReg);
665 int64_t LocalIntfs = 0;
666 float NumUrgent = 0.0f;
669 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
672 InterferingIntervals;
673 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
678 if (IFIntervals.empty() && InterferingIntervals.
empty())
682 InterferingIntervals.
append(IFIntervals.begin(), IFIntervals.end());
684 assert(Intf->reg().isVirtual() &&
685 "Only expecting virtual register interference from query");
692 if (FixedRegisters.
count(Intf->reg()))
694 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
698 (Intf->isSpillable() ||
699 RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.
reg())) <
700 RegClassInfo.getNumAllocatableRegs(
701 MRI->getRegClass(Intf->reg())));
703 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
716 if (Cascade <= IntfCascade) {
722 LocalIntfs += (IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
723 (!EnableLocalReassign || !canReassign(*Intf, PhysReg)));
728 extractFeatures(InterferingIntervals, Largest, Pos, IsHint, LocalIntfs,
729 NumUrgent, LRPosInfo);
733MCRegister MLEvictAdvisor::tryFindEvictionCandidate(
736 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
737 if (!MaybeOrderLimit)
739 unsigned OrderLimit = *MaybeOrderLimit;
747 const bool MustFindEviction =
758 CandidateRegList Regs(NumColumns, {0,
false});
775 if (Pos == CandidateVirtRegPos)
777 "-mlregalloc-num-allocatable-regs=" +
780 assert(!Regs[Pos].second);
782 if (!canAllocatePhysReg(CostPerUseLimit, PhysReg)) {
785 if (loadInterferenceFeatures(VirtReg, PhysReg,
I.isHint(), FixedRegisters,
786 Largest, Pos, LRPosInfo)) {
788 Regs[Pos] = std::make_pair(PhysReg,
true);
793 assert(!MustFindEviction);
796 const size_t ValidPosLimit = Pos;
799 Regs[CandidateVirtRegPos].second = !MustFindEviction;
800 if (!MustFindEviction)
802 CandidateVirtRegPos, 0,
805 assert(InitialQSize > 0.0 &&
"We couldn't have gotten here if we had "
806 "nothing to allocate initially.");
808 for (
auto &V : Largest)
814 for (
size_t Pos = 0; Pos < NumColumns; ++Pos) {
819 *Runner->
getTensor<
float>(FeatureIDs::progress) =
820 static_cast<float>(
RA.getQueueSize()) / InitialQSize;
823 size_t CandidatePos = tryFindEvictionCandidatePosition(
824 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
827 assert(Regs[CandidatePos].second);
828 if (CandidatePos == CandidateVirtRegPos) {
829 onEviction(VirtReg.
reg());
830 assert(!MustFindEviction);
833 assert(CandidatePos < ValidPosLimit);
839 for (MCRegUnit Unit :
TRI->regunits(Regs[CandidatePos].first)) {
843 onEviction(Intf->reg());
847 return Regs[CandidatePos].first;
850const LIFeatureComponents &
851MLEvictAdvisor::getLIFeatureComponents(
const LiveInterval &LI)
const {
852 RegID ID = LI.
reg().
id();
853 LIFeatureComponents
Empty;
854 auto I = CachedFeatures.insert(std::make_pair(ID,
Empty));
855 LIFeatureComponents &Ret =
I.first->getSecond();
863 I = MRI->reg_instr_nodbg_begin(LI.
reg()),
864 E = MRI->reg_instr_nodbg_end();
868 ++Ret.NumDefsAndUses;
872 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
876 std::tie(Reads, Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
879 Ret.HottestBlockFreq = std::max(Freq, Ret.HottestBlockFreq);
881 Ret.R += (Reads && !Writes) * Freq;
882 Ret.W += (!Reads && Writes) * Freq;
883 Ret.RW += (Reads && Writes) * Freq;
885 auto *
MBB =
MI->getParent();
889 if (Writes && IsExiting && LIS->isLiveOutOfMBB(LI,
MBB))
890 Ret.IndVarUpdates += Freq;
893 Ret.HintWeights += Freq;
902void MLEvictAdvisor::extractFeatures(
905 int64_t LocalIntfsCount,
float NumUrgent,
907 int64_t NumDefsAndUses = 0;
908 int64_t NumBrokenHints = 0;
912 double IndVarUpdates = 0.0;
913 double HintWeights = 0.0;
914 float StartBBFreq = 0.0;
915 float EndBBFreq = 0.0;
916 float HottestBlockFreq = 0.0;
917 int32_t NumRematerializable = 0;
918 float TotalWeight = 0.0;
920 SlotIndex EndSI = LIS->getSlotIndexes()->getZeroIndex();
921 SlotIndex StartSI = LIS->getSlotIndexes()->getLastIndex();
922 int64_t MaxStage = 0;
924 Intervals.
empty() ? 0 : std::numeric_limits<int64_t>::max();
926 for (
const auto *L : Intervals) {
928 MaxStage = std::max<int64_t>(
929 MaxStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
930 MinStage = std::min<int64_t>(
931 MinStage,
static_cast<int64_t
>(
RA.getExtraInfo().getStage(LI)));
933 TotalWeight = std::max(TotalWeight, LI.
weight());
940 const LIFeatureComponents &LIFC = getLIFeatureComponents(LI);
941 NumBrokenHints += VRM->hasPreferredPhys(LI.
reg());
943 NumDefsAndUses += LIFC.NumDefsAndUses;
944 HottestBlockFreq = std::max(HottestBlockFreq, LIFC.HottestBlockFreq);
949 IndVarUpdates += LIFC.IndVarUpdates;
951 HintWeights += LIFC.HintWeights;
952 NumRematerializable += LIFC.IsRemat;
955 if (!Intervals.empty()) {
958 if (EndSI >= LIS->getSlotIndexes()->getLastIndex())
959 EndSI = LIS->getSlotIndexes()->getLastIndex().
getPrevIndex();
965#define SET(ID, TYPE, VAL) \
967 Runner->getTensor<TYPE>(FeatureIDs::ID)[Pos] = static_cast<TYPE>(VAL); \
968 float F = static_cast<float>(VAL); \
969 if (!DoNotNormalize.test(FeatureIDs::ID) && !std::isinf(F)) \
970 Largest[FeatureIDs::ID] = std::max(Largest[FeatureIDs::ID], F); \
973 SET(is_free, int64_t, Intervals.empty());
974 SET(nr_urgent,
float, NumUrgent);
975 SET(nr_broken_hints,
float, NumBrokenHints);
976 SET(is_hint, int64_t, IsHint);
977 SET(is_local, int64_t, LocalIntfsCount);
978 SET(nr_rematerializable,
float, NumRematerializable);
979 SET(nr_defs_and_uses,
float, NumDefsAndUses);
980 SET(weighed_reads_by_max,
float, R);
981 SET(weighed_writes_by_max,
float, W);
982 SET(weighed_read_writes_by_max,
float, RW);
983 SET(weighed_indvars_by_max,
float, IndVarUpdates);
984 SET(hint_weights_by_max,
float, HintWeights);
985 SET(start_bb_freq_by_max,
float, StartBBFreq);
986 SET(end_bb_freq_by_max,
float, EndBBFreq);
987 SET(hottest_bb_freq_by_max,
float, HottestBlockFreq);
988 SET(liverange_size,
float,
Size);
989 SET(use_def_density,
float, TotalWeight);
990 SET(max_stage, int64_t, MaxStage);
991 SET(min_stage, int64_t, MinStage);
996#ifdef LLVM_HAVE_TFLITE
1000 return new DevelopmentModeEvictionAdvisorAnalysisLegacy();
1003int64_t DevelopmentModeEvictAdvisor::tryFindEvictionCandidatePosition(
1005 unsigned OrderLimit,
uint8_t CostPerUseLimit,
1009 Ret = MLEvictAdvisor::tryFindEvictionCandidatePosition(
1010 VirtReg, Order, OrderLimit, CostPerUseLimit, FixedRegisters);
1012 MCRegister PhysReg = getDefaultAdvisor().tryFindEvictionCandidate(
1013 VirtReg, Order, CostPerUseLimit, FixedRegisters);
1018 Ret = CandidateVirtRegPos;
1025 if (TrainingLog.empty())
1030 if (
Log->hasObservationInProgress())
1031 Log->logReward<
float>(0.0);
1033 Log->startObservation();
1034 size_t CurrentFeature = 0;
1036 for (; CurrentFeature <
FeatureCount; ++CurrentFeature) {
1037 Log->logTensorValue(CurrentFeature,
1038 reinterpret_cast<const char *
>(
1039 getRunner().getTensorUntyped(CurrentFeature)));
1042 for (
size_t I = 0;
I < MUTR->extraOutputsForLoggingSpecs().
size();
1043 ++
I, ++CurrentFeature)
1044 Log->logTensorValue(
1046 reinterpret_cast<const char *
>(MUTR->getUntypedExtraOutputValue(
I)));
1048 Log->logTensorValue(CurrentFeature,
reinterpret_cast<const char *
>(&Ret));
1049 Log->endObservation();
1054 std::optional<float> CachedReward;
1055 auto GetReward = [&]() {
1057 CachedReward =
static_cast<float>(
1059 MF, getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI())
1061 return *CachedReward;
1064 getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().logRewardIfNeeded(
1066 getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().logRewardIfNeeded(
1072RegAllocEvictionAdvisorProvider *
1076 ?
new ReleaseModeEvictionAdvisorProvider(Ctx)
1082#if defined(LLVM_HAVE_TFLITE)
1083 return new DevelopmentModeEvictionAdvisorProvider(Ctx);
1092 ?
new ReleaseModeEvictionAdvisorAnalysisLegacy()
1097#if !defined(LLVM_HAVE_TFLITE)
1098bool RegAllocScoring::runOnMachineFunction(
MachineFunction &) {
return false; }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr unsigned long long mask(BlockVerifier::State S)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file implements a model runner wrapping an EmitC compiled ML model.
@ Available
We know the block is fully available. This is a fixpoint.
Module.h This file contains the declarations for the Module class.
This file provides helper functions for creating MLModelRunners and checking model validity in releas...
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 llvm::cl::opt< MLGORegAllocModelChoice > SelectedMLGORegAllocModel("regalloc-mlgo-model", llvm::cl::desc("Select the MLGO model to execute for register allocation:"), llvm::cl::init(MLGORegAllocModelChoice::Default), llvm::cl::values(clEnumValN(MLGORegAllocModelChoice::Default, "default", "Use standard heuristic") #define MLGO_MODEL(CLASS_NAME, CLI_FLAG) \ \))
static std::unique_ptr< MLModelRunner > createMLGORegAllocModelRunner(LLVMContext &Ctx, const std::vector< TensorSpec > &InputFeatures)
#define MLGO_MODEL(CLASS_NAME, CLI_FLAG)
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)
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"))
static cl::opt< unsigned > NumAllocatableRegs("mlregalloc-num-allocatable-regs", cl::Hidden, cl::desc("The number of eviction candidates the model sees. The model has " "one more column, for the live range seeking allocation"), cl::init(32))
#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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator find(const_arg_type_t< KeyT > Val)
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)
void * getTensorUntyped(size_t Index)
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.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
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.
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.
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)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI 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 LLVM_ABI 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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()
LLVM_ABI RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)
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.
bool isReleaseModelValid(StringRef InteractiveChannelBaseName, const cl::opt< EnumType, ExternalStorage, ParserClass > &SelectedModel, EnumType DefaultModelVal=EnumType::Default)
Helper to check if a release-mode ML advisor has a valid model to execute.
LLVM_ABI RegAllocEvictionAdvisorAnalysisLegacy * createDevelopmentModeAdvisorAnalysisLegacy()
auto reverse(ContainerTy &&C)
std::unique_ptr< MLModelRunner > createReleaseModeModelRunner(LLVMContext &Ctx, const std::vector< TensorSpec > &InputFeatures, StringRef DecisionName, const std::string &InteractiveChannelBaseName, const TensorSpec &InteractiveDecisionSpec, CreateEmitCFunc &&CreateEmitCModelRunner, const EmbeddedModelRunnerOptions &Options={})
Helper to construct the appropriate MLModelRunner in release mode:
static const std::vector< TensorSpec > InputFeatures
@ RS_Done
There is nothing more we can do to this live range.
std::string getLoggerContextName(StringRef Name, unsigned Number)
Context name for Name.
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_ABI RegAllocEvictionAdvisorProvider * createReleaseModeAdvisorProvider(LLVMContext &Ctx)
static const std::vector< int64_t > PerLiveRangeShape
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.