33 cl::desc(
"Enable regalloc advisor mode"),
36 "default",
"Default"),
38 "release",
"precompiled"),
41 "development",
"for training")));
45 cl::desc(
"Local reassignment can yield better allocation decisions, but "
46 "may be compile time intensive"),
51 "regalloc-eviction-max-interference-cutoff",
cl::Hidden,
52 cl::desc(
"Number of interferences after which we declare "
53 "an interference unevictable and bail out. This "
54 "is a compilation cost-saving consideration. To "
55 "disable, pass a very large number."),
59#define DEBUG_TYPE "regalloc"
60#ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL
61#define LLVM_HAVE_TF_AOT
66 "Regalloc eviction policy",
false,
true)
69class DefaultEvictionAdvisorProvider final
72 DefaultEvictionAdvisorProvider(
bool NotAsRequested,
LLVMContext &Ctx)
75 Ctx.emitError(
"Requested regalloc eviction advisor analysis "
76 "could not be created. Using default");
81 return R->getAdvisorMode() == AdvisorMode::Default;
84 std::unique_ptr<RegAllocEvictionAdvisor>
87 return std::make_unique<DefaultEvictionAdvisor>(MF,
RA);
91class DefaultEvictionAdvisorAnalysisLegacy final
94 DefaultEvictionAdvisorAnalysisLegacy(
bool NotAsRequested)
96 NotAsRequested(NotAsRequested) {}
100 new DefaultEvictionAdvisorProvider(NotAsRequested, M.getContext()));
106 return R->getAdvisorMode() == AdvisorMode::Default;
110 const bool NotAsRequested;
116void RegAllocEvictionAdvisorAnalysis::initializeProvider(
123 new DefaultEvictionAdvisorProvider(
false, Ctx));
126#if defined(LLVM_HAVE_TFLITE)
130 new DefaultEvictionAdvisorProvider(
true, Ctx));
144 return Result{Provider.get()};
151 return new DefaultEvictionAdvisorAnalysisLegacy(
false);
157 return new DefaultEvictionAdvisorAnalysisLegacy(
true);
160#if defined(LLVM_HAVE_TFLITE)
163 return new DefaultEvictionAdvisorAnalysisLegacy(
true);
172 return "Default Regalloc Eviction Advisor";
174 return "Release mode Regalloc Eviction Advisor";
176 return "Development mode Regalloc Eviction Advisor";
184 LIS(
RA.getLiveIntervals()),
VRM(
RA.getVirtRegMap()),
185 MRI(&
VRM->getRegInfo()),
TRI(
MF.getSubtarget().getRegisterInfo()),
188 MF.getSubtarget().enableRALocalReassignment(
189 MF.getTarget().getOptLevel())) {}
204bool DefaultEvictionAdvisor::shouldEvict(
const LiveInterval &
A,
bool IsHint,
206 bool BreaksHint)
const {
207 bool CanSplit =
RA.getExtraInfo().getStage(
B) <
RS_Spill;
211 if (CanSplit && IsHint && !BreaksHint)
214 if (
A.weight() >
B.weight()) {
223bool DefaultEvictionAdvisor::canEvictHintInterference(
226 EvictionCost MaxCost;
228 return canEvictInterferenceBasedOnCost(VirtReg, PhysReg,
true, MaxCost,
241bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
248 bool IsLocal = VirtReg.
empty() ||
LIS->intervalIsInOneMBB(VirtReg);
257 unsigned Cascade =
RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.
reg());
261 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
268 for (
const LiveInterval *Intf :
reverse(Interferences)) {
269 assert(Intf->reg().isVirtual() &&
270 "Only expecting virtual register interference from query");
275 if (FixedRegisters.
count(Intf->reg()))
279 if (
RA.getExtraInfo().getStage(*Intf) ==
RS_Done)
289 (Intf->isSpillable() ||
292 MRI->getRegClass(Intf->reg())));
294 unsigned IntfCascade =
RA.getExtraInfo().getCascade(Intf->reg());
295 if (Cascade == IntfCascade)
298 if (Cascade < IntfCascade) {
303 Cost.BrokenHints += 10;
306 bool BreaksHint =
VRM->hasPreferredPhys(Intf->reg());
308 Cost.BrokenHints += BreaksHint;
309 Cost.MaxWeight = std::max(
Cost.MaxWeight, Intf->weight());
311 if (!(
Cost < MaxCost))
316 if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))
321 if (!MaxCost.
isMax() && IsLocal &&
LIS->intervalIsInOneMBB(*Intf) &&
331MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate(
333 uint8_t CostPerUseLimit,
const SmallVirtRegSet &FixedRegisters)
const {
335 EvictionCost BestCost;
338 auto MaybeOrderLimit =
getOrderLimit(VirtReg, Order, CostPerUseLimit);
339 if (!MaybeOrderLimit)
341 unsigned OrderLimit = *MaybeOrderLimit;
345 if (CostPerUseLimit < uint8_t(~0u)) {
352 MCRegister PhysReg = *
I;
355 !canEvictInterferenceBasedOnCost(VirtReg, PhysReg,
false, BestCost,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static cl::opt< bool > EnableLocalReassignment("enable-local-reassign", cl::Hidden, cl::desc("Local reassignment can yield better allocation decisions, but " "may be compile time intensive"), cl::init(false))
SI optimize exec mask operations pre RA
Iterator getOrderLimitEnd(unsigned OrderLimit) const
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.
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?
@ IK_VirtReg
Virtual register interference.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
Function & getFunction()
Return the LLVM function that this machine code represents.
A Module instance is used to store all the information related to an LLVM module.
Pass interface - Implemented by all 'passes'.
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
ImmutableAnalysis abstraction for fetching the Eviction Advisor.
RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode Mode)
AdvisorMode getAdvisorMode() const
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM)
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
RegAllocEvictionAdvisorProvider(AdvisorMode Mode, LLVMContext &Ctx)
const TargetRegisterInfo *const TRI
std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const
const ArrayRef< uint8_t > RegCosts
MachineRegisterInfo *const MRI
const RegisterClassInfo & RegClassInfo
const MachineFunction & MF
RegAllocEvictionAdvisor(const RegAllocEvictionAdvisor &)=delete
bool canReassign(const LiveInterval &VirtReg, MCRegister FromReg) const
const bool EnableLocalReassign
Run or not the local reassignment heuristic.
bool canAllocatePhysReg(unsigned CostPerUseLimit, MCRegister PhysReg) const
LiveRegMatrix *const Matrix
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
#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.
SmallSet< Register, 16 > SmallVirtRegSet
RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()
RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
auto reverse(ContainerTy &&C)
Pass * callDefaultCtor< RegAllocEvictionAdvisorAnalysisLegacy >()
Specialization for the API used by the analysis infrastructure to create an instance of the eviction ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ RS_Spill
Live range will be spilled. No more splitting will be attempted.
@ RS_Done
There is nothing more we can do to this live range.
unsigned MCRegUnit
Register units are used to compute register aliasing.
cl::opt< unsigned > EvictInterferenceCutoff
LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider * createReleaseModeAdvisorProvider(LLVMContext &Ctx)
RegAllocEvictionAdvisorAnalysisLegacy * createDevelopmentModeAdvisorAnalysisLegacy()
A special type used by analysis passes to provide an address that identifies that particular analysis...
Cost of evicting interference - used by default advisor, and the eviction chain heuristic in RegAlloc...
unsigned BrokenHints
Total number of broken hints.
float MaxWeight
Maximum spill weight evicted.
void setBrokenHints(unsigned NHints)