LLVM: lib/CodeGen/RegAllocEvictionAdvisor.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
27
28using namespace llvm;
29
31 "regalloc-enable-advisor", cl::Hidden,
33 cl::desc("Enable regalloc advisor mode"),
36 "default", "Default"),
38 "release", "precompiled"),
41 "development", "for training")));
42
45 cl::desc("Local reassignment can yield better allocation decisions, but "
46 "may be compile time intensive"),
48
49namespace llvm {
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."),
57}
58
59#define DEBUG_TYPE "regalloc"
60#ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL
61#define LLVM_HAVE_TF_AOT
62#endif
63
66 "Regalloc eviction policy", false, true)
67
68namespace {
69class DefaultEvictionAdvisorProvider final
71public:
72 DefaultEvictionAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx)
74 if (NotAsRequested)
75 Ctx.emitError("Requested regalloc eviction advisor analysis "
76 "could not be created. Using default");
77 }
78
79
81 return R->getAdvisorMode() == AdvisorMode::Default;
82 }
83
84 std::unique_ptr
87 return std::make_unique(MF, RA);
88 }
89};
90
91class DefaultEvictionAdvisorAnalysisLegacy final
93public:
94 DefaultEvictionAdvisorAnalysisLegacy(bool NotAsRequested)
96 NotAsRequested(NotAsRequested) {}
97
99 Provider.reset(
100 new DefaultEvictionAdvisorProvider(NotAsRequested, M.getContext()));
101 return false;
102 }
103
104
106 return R->getAdvisorMode() == AdvisorMode::Default;
107 }
108
109private:
110 const bool NotAsRequested;
111};
112}
113
114AnalysisKey RegAllocEvictionAdvisorAnalysis::Key;
115
116void RegAllocEvictionAdvisorAnalysis::initializeProvider(
118 if (Provider)
119 return;
120 switch (Mode) {
122 Provider.reset(
123 new DefaultEvictionAdvisorProvider(false, Ctx));
124 return;
126#if defined(LLVM_HAVE_TFLITE)
128#else
129 Provider.reset(
130 new DefaultEvictionAdvisorProvider(true, Ctx));
131#endif
132 return;
135 return;
136 }
137}
138
142
144 return Result{Provider.get()};
145}
146
147template <>
149 switch (Mode) {
151 return new DefaultEvictionAdvisorAnalysisLegacy(false);
154
155 if (Ret)
156 return Ret;
157 return new DefaultEvictionAdvisorAnalysisLegacy(true);
158 }
160#if defined(LLVM_HAVE_TFLITE)
162#else
163 return new DefaultEvictionAdvisorAnalysisLegacy(true);
164#endif
165 }
167}
168
172 return "Default Regalloc Eviction Advisor";
174 return "Release mode Regalloc Eviction Advisor";
176 return "Development mode Regalloc Eviction Advisor";
177 }
179}
180
184 LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
185 MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
188 MF.getSubtarget().enableRALocalReassignment(
189 MF.getTarget().getOptLevel())) {}
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval &A, bool IsHint,
206 bool BreaksHint) const {
207 bool CanSplit = RA.getExtraInfo().getStage(B) < RS_Spill;
208
209
210
211 if (CanSplit && IsHint && !BreaksHint)
212 return true;
213
214 if (A.weight() > B.weight()) {
216 return true;
217 }
218 return false;
219}
220
221
222
223bool DefaultEvictionAdvisor::canEvictHintInterference(
226 EvictionCost MaxCost;
228 return canEvictInterferenceBasedOnCost(VirtReg, PhysReg, true, MaxCost,
229 FixedRegisters);
230}
231
232
233
234
235
236
237
238
239
240
241bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
244
246 return false;
247
248 bool IsLocal = VirtReg.empty() || LIS->intervalIsInOneMBB(VirtReg);
249
250
251
252
253
254
255
256
257 unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());
258
259 EvictionCost Cost;
260 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
261 LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
262
265 return false;
266
267
268 for (const LiveInterval *Intf : reverse(Interferences)) {
269 assert(Intf->reg().isVirtual() &&
270 "Only expecting virtual register interference from query");
271
272
273
274
275 if (FixedRegisters.count(Intf->reg()))
276 return false;
277
278
279 if (RA.getExtraInfo().getStage(*Intf) == RS_Done)
280 return false;
281
282
283
284
285
286
287 bool Urgent =
289 (Intf->isSpillable() ||
290 RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
292 MRI->getRegClass(Intf->reg())));
293
294 unsigned IntfCascade = RA.getExtraInfo().getCascade(Intf->reg());
295 if (Cascade == IntfCascade)
296 return false;
297
298 if (Cascade < IntfCascade) {
299 if (!Urgent)
300 return false;
301
302
303 Cost.BrokenHints += 10 * MRI->getRegClass(Intf->reg())->getCopyCost();
304 }
305
306 bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
307
308 if (BreaksHint)
309 Cost.BrokenHints += MRI->getRegClass(Intf->reg())->getCopyCost();
310
311 Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
312
313 if (Cost >= MaxCost)
314 return false;
315 if (Urgent)
316 continue;
317
318 if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))
319 return false;
320
321
322
323 if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
325 return false;
326 }
327 }
328 }
329 MaxCost = Cost;
330 return true;
331}
332
333MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate(
335 uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const {
336
337 EvictionCost BestCost;
339 MCRegister BestPhys;
340 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);
341 if (!MaybeOrderLimit)
343 unsigned OrderLimit = *MaybeOrderLimit;
344
345
346
347 if (CostPerUseLimit < uint8_t(~0u)) {
350 }
351
353 ++I) {
354 MCRegister PhysReg = *I;
357 !canEvictInterferenceBasedOnCost(VirtReg, PhysReg, false, BestCost,
358 FixedRegisters))
359 continue;
360
361
362 BestPhys = PhysReg;
363
364
365 if (I.isHint())
366 break;
367 }
368 return BestPhys;
369}
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)
Definition RegAllocEvictionAdvisor.cpp:140
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 ...
Definition RegAllocEvictionAdvisor.cpp:148
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.
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)