1 //===- RegAllocEvictionAdvisor.cpp - eviction advisor ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Implementation of the default eviction advisor and of the Analysis pass.
11 //===----------------------------------------------------------------------===//
13 #include "RegAllocEvictionAdvisor.h"
14 #include "AllocationOrder.h"
15 #include "RegAllocGreedy.h"
16 #include "llvm/CodeGen/LiveRegMatrix.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/RegisterClassInfo.h"
19 #include "llvm/CodeGen/VirtRegMap.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Target/TargetMachine.h"
29 static cl::opt
<RegAllocEvictionAdvisorAnalysis::AdvisorMode
> Mode(
30 "regalloc-enable-advisor", cl::Hidden
,
31 cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default
),
32 cl::desc("Enable regalloc advisor mode"),
34 clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default
,
35 "default", "Default"),
36 clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release
,
37 "release", "precompiled"),
38 clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development
,
39 "development", "for training")));
41 static cl::opt
<bool> EnableLocalReassignment(
42 "enable-local-reassign", cl::Hidden
,
43 cl::desc("Local reassignment can yield better allocation decisions, but "
44 "may be compile time intensive"),
48 cl::opt
<unsigned> EvictInterferenceCutoff(
49 "regalloc-eviction-max-interference-cutoff", cl::Hidden
,
50 cl::desc("Number of interferences after which we declare "
51 "an interference unevictable and bail out. This "
52 "is a compilation cost-saving consideration. To "
53 "disable, pass a very large number."),
57 #define DEBUG_TYPE "regalloc"
58 #ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL
59 #define LLVM_HAVE_TF_AOT
62 char RegAllocEvictionAdvisorAnalysis::ID
= 0;
63 INITIALIZE_PASS(RegAllocEvictionAdvisorAnalysis
, "regalloc-evict",
64 "Regalloc eviction policy", false, true)
67 class DefaultEvictionAdvisorAnalysis final
68 : public RegAllocEvictionAdvisorAnalysis
{
70 DefaultEvictionAdvisorAnalysis(bool NotAsRequested
)
71 : RegAllocEvictionAdvisorAnalysis(AdvisorMode::Default
),
72 NotAsRequested(NotAsRequested
) {}
74 // support for isa<> and dyn_cast.
75 static bool classof(const RegAllocEvictionAdvisorAnalysis
*R
) {
76 return R
->getAdvisorMode() == AdvisorMode::Default
;
80 std::unique_ptr
<RegAllocEvictionAdvisor
>
81 getAdvisor(const MachineFunction
&MF
, const RAGreedy
&RA
) override
{
82 return std::make_unique
<DefaultEvictionAdvisor
>(MF
, RA
);
84 bool doInitialization(Module
&M
) override
{
86 M
.getContext().emitError("Requested regalloc eviction advisor analysis "
87 "could not be created. Using default");
88 return RegAllocEvictionAdvisorAnalysis::doInitialization(M
);
90 const bool NotAsRequested
;
94 template <> Pass
*llvm::callDefaultCtor
<RegAllocEvictionAdvisorAnalysis
>() {
97 case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default
:
98 Ret
= new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ false);
100 case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development
:
101 #if defined(LLVM_HAVE_TFLITE)
102 Ret
= createDevelopmentModeAdvisor();
105 case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release
:
106 Ret
= createReleaseModeAdvisor();
111 return new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ true);
114 StringRef
RegAllocEvictionAdvisorAnalysis::getPassName() const {
115 switch (getAdvisorMode()) {
116 case AdvisorMode::Default
:
117 return "Default Regalloc Eviction Advisor";
118 case AdvisorMode::Release
:
119 return "Release mode Regalloc Eviction Advisor";
120 case AdvisorMode::Development
:
121 return "Development mode Regalloc Eviction Advisor";
123 llvm_unreachable("Unknown advisor kind");
126 RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction
&MF
,
128 : MF(MF
), RA(RA
), Matrix(RA
.getInterferenceMatrix()),
129 LIS(RA
.getLiveIntervals()), VRM(RA
.getVirtRegMap()),
130 MRI(&VRM
->getRegInfo()), TRI(MF
.getSubtarget().getRegisterInfo()),
131 RegClassInfo(RA
.getRegClassInfo()), RegCosts(TRI
->getRegisterCosts(MF
)),
132 EnableLocalReassign(EnableLocalReassignment
||
133 MF
.getSubtarget().enableRALocalReassignment(
134 MF
.getTarget().getOptLevel())) {}
136 /// shouldEvict - determine if A should evict the assigned live range B. The
137 /// eviction policy defined by this function together with the allocation order
138 /// defined by enqueue() decides which registers ultimately end up being split
141 /// Cascade numbers are used to prevent infinite loops if this function is a
144 /// @param A The live range to be assigned.
145 /// @param IsHint True when A is about to be assigned to its preferred
147 /// @param B The live range to be evicted.
148 /// @param BreaksHint True when B is already assigned to its preferred register.
149 bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval
&A
, bool IsHint
,
150 const LiveInterval
&B
,
151 bool BreaksHint
) const {
152 bool CanSplit
= RA
.getExtraInfo().getStage(B
) < RS_Spill
;
154 // Be fairly aggressive about following hints as long as the evictee can be
156 if (CanSplit
&& IsHint
&& !BreaksHint
)
159 if (A
.weight() > B
.weight()) {
160 LLVM_DEBUG(dbgs() << "should evict: " << B
<< " w= " << B
.weight() << '\n');
166 /// canEvictHintInterference - return true if the interference for VirtReg
167 /// on the PhysReg, which is VirtReg's hint, can be evicted in favor of VirtReg.
168 bool DefaultEvictionAdvisor::canEvictHintInterference(
169 const LiveInterval
&VirtReg
, MCRegister PhysReg
,
170 const SmallVirtRegSet
&FixedRegisters
) const {
171 EvictionCost MaxCost
;
172 MaxCost
.setBrokenHints(1);
173 return canEvictInterferenceBasedOnCost(VirtReg
, PhysReg
, true, MaxCost
,
177 /// canEvictInterferenceBasedOnCost - Return true if all interferences between
178 /// VirtReg and PhysReg can be evicted.
180 /// @param VirtReg Live range that is about to be assigned.
181 /// @param PhysReg Desired register for assignment.
182 /// @param IsHint True when PhysReg is VirtReg's preferred register.
183 /// @param MaxCost Only look for cheaper candidates and update with new cost
184 /// when returning true.
185 /// @returns True when interference can be evicted cheaper than MaxCost.
186 bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
187 const LiveInterval
&VirtReg
, MCRegister PhysReg
, bool IsHint
,
188 EvictionCost
&MaxCost
, const SmallVirtRegSet
&FixedRegisters
) const {
189 // It is only possible to evict virtual register interference.
190 if (Matrix
->checkInterference(VirtReg
, PhysReg
) > LiveRegMatrix::IK_VirtReg
)
193 bool IsLocal
= VirtReg
.empty() || LIS
->intervalIsInOneMBB(VirtReg
);
195 // Find VirtReg's cascade number. This will be unassigned if VirtReg was never
196 // involved in an eviction before. If a cascade number was assigned, deny
197 // evicting anything with the same or a newer cascade number. This prevents
198 // infinite eviction loops.
200 // This works out so a register without a cascade number is allowed to evict
201 // anything, and it can be evicted by anything.
202 unsigned Cascade
= RA
.getExtraInfo().getCascadeOrCurrentNext(VirtReg
.reg());
205 for (MCRegUnit Unit
: TRI
->regunits(PhysReg
)) {
206 LiveIntervalUnion::Query
&Q
= Matrix
->query(VirtReg
, Unit
);
207 // If there is 10 or more interferences, chances are one is heavier.
208 const auto &Interferences
= Q
.interferingVRegs(EvictInterferenceCutoff
);
209 if (Interferences
.size() >= EvictInterferenceCutoff
)
212 // Check if any interfering live range is heavier than MaxWeight.
213 for (const LiveInterval
*Intf
: reverse(Interferences
)) {
214 assert(Intf
->reg().isVirtual() &&
215 "Only expecting virtual register interference from query");
217 // Do not allow eviction of a virtual register if we are in the middle
218 // of last-chance recoloring and this virtual register is one that we
219 // have scavenged a physical register for.
220 if (FixedRegisters
.count(Intf
->reg()))
223 // Never evict spill products. They cannot split or spill.
224 if (RA
.getExtraInfo().getStage(*Intf
) == RS_Done
)
226 // Once a live range becomes small enough, it is urgent that we find a
227 // register for it. This is indicated by an infinite spill weight. These
228 // urgent live ranges get to evict almost anything.
230 // Also allow urgent evictions of unspillable ranges from a strictly
231 // larger allocation order.
233 !VirtReg
.isSpillable() &&
234 (Intf
->isSpillable() ||
235 RegClassInfo
.getNumAllocatableRegs(MRI
->getRegClass(VirtReg
.reg())) <
236 RegClassInfo
.getNumAllocatableRegs(
237 MRI
->getRegClass(Intf
->reg())));
238 // Only evict older cascades or live ranges without a cascade.
239 unsigned IntfCascade
= RA
.getExtraInfo().getCascade(Intf
->reg());
240 if (Cascade
== IntfCascade
)
243 if (Cascade
< IntfCascade
) {
246 // We permit breaking cascades for urgent evictions. It should be the
247 // last resort, though, so make it really expensive.
248 Cost
.BrokenHints
+= 10;
250 // Would this break a satisfied hint?
251 bool BreaksHint
= VRM
->hasPreferredPhys(Intf
->reg());
252 // Update eviction cost.
253 Cost
.BrokenHints
+= BreaksHint
;
254 Cost
.MaxWeight
= std::max(Cost
.MaxWeight
, Intf
->weight());
255 // Abort if this would be too expensive.
256 if (!(Cost
< MaxCost
))
260 // Apply the eviction policy for non-urgent evictions.
261 if (!shouldEvict(VirtReg
, IsHint
, *Intf
, BreaksHint
))
263 // If !MaxCost.isMax(), then we're just looking for a cheap register.
264 // Evicting another local live range in this case could lead to suboptimal
266 if (!MaxCost
.isMax() && IsLocal
&& LIS
->intervalIsInOneMBB(*Intf
) &&
267 (!EnableLocalReassign
|| !canReassign(*Intf
, PhysReg
))) {
276 MCRegister
DefaultEvictionAdvisor::tryFindEvictionCandidate(
277 const LiveInterval
&VirtReg
, const AllocationOrder
&Order
,
278 uint8_t CostPerUseLimit
, const SmallVirtRegSet
&FixedRegisters
) const {
279 // Keep track of the cheapest interference seen so far.
280 EvictionCost BestCost
;
283 auto MaybeOrderLimit
= getOrderLimit(VirtReg
, Order
, CostPerUseLimit
);
284 if (!MaybeOrderLimit
)
285 return MCRegister::NoRegister
;
286 unsigned OrderLimit
= *MaybeOrderLimit
;
288 // When we are just looking for a reduced cost per use, don't break any
289 // hints, and only evict smaller spill weights.
290 if (CostPerUseLimit
< uint8_t(~0u)) {
291 BestCost
.BrokenHints
= 0;
292 BestCost
.MaxWeight
= VirtReg
.weight();
295 for (auto I
= Order
.begin(), E
= Order
.getOrderLimitEnd(OrderLimit
); I
!= E
;
297 MCRegister PhysReg
= *I
;
299 if (!canAllocatePhysReg(CostPerUseLimit
, PhysReg
) ||
300 !canEvictInterferenceBasedOnCost(VirtReg
, PhysReg
, false, BestCost
,
307 // Stop if the hint can be used.