1 //==- RegAllocGreedy.h ------- greedy register allocator ----------*-C++-*-==//
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 //===----------------------------------------------------------------------===//
8 // This file defines the RAGreedy function pass for register allocation in
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_CODEGEN_REGALLOCGREEDY_H_
13 #define LLVM_CODEGEN_REGALLOCGREEDY_H_
15 #include "AllocationOrder.h"
16 #include "InterferenceCache.h"
17 #include "LiveDebugVariables.h"
18 #include "RegAllocBase.h"
19 #include "RegAllocEvictionAdvisor.h"
20 #include "SpillPlacement.h"
22 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/BitVector.h"
24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/IndexedMap.h"
26 #include "llvm/ADT/MapVector.h"
27 #include "llvm/ADT/SetVector.h"
28 #include "llvm/ADT/SmallPtrSet.h"
29 #include "llvm/ADT/SmallSet.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/Analysis/AliasAnalysis.h"
33 #include "llvm/CodeGen/CalcSpillWeights.h"
34 #include "llvm/CodeGen/EdgeBundles.h"
35 #include "llvm/CodeGen/LiveInterval.h"
36 #include "llvm/CodeGen/LiveIntervalUnion.h"
37 #include "llvm/CodeGen/LiveIntervals.h"
38 #include "llvm/CodeGen/LiveRangeEdit.h"
39 #include "llvm/CodeGen/LiveRegMatrix.h"
40 #include "llvm/CodeGen/LiveStacks.h"
41 #include "llvm/CodeGen/MachineBasicBlock.h"
42 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
43 #include "llvm/CodeGen/MachineDominators.h"
44 #include "llvm/CodeGen/MachineFrameInfo.h"
45 #include "llvm/CodeGen/MachineFunction.h"
46 #include "llvm/CodeGen/MachineFunctionPass.h"
47 #include "llvm/CodeGen/MachineLoopInfo.h"
48 #include "llvm/CodeGen/MachineRegisterInfo.h"
49 #include "llvm/CodeGen/RegisterClassInfo.h"
50 #include "llvm/CodeGen/SlotIndexes.h"
51 #include "llvm/CodeGen/Spiller.h"
52 #include "llvm/CodeGen/TargetInstrInfo.h"
53 #include "llvm/CodeGen/TargetRegisterInfo.h"
54 #include "llvm/CodeGen/TargetSubtargetInfo.h"
55 #include "llvm/CodeGen/VirtRegMap.h"
56 #include "llvm/IR/DebugInfoMetadata.h"
57 #include "llvm/IR/Function.h"
58 #include "llvm/IR/LLVMContext.h"
59 #include "llvm/MC/MCRegisterInfo.h"
60 #include "llvm/Pass.h"
61 #include "llvm/Support/BranchProbability.h"
62 #include "llvm/Target/TargetMachine.h"
72 class LLVM_LIBRARY_VISIBILITY RAGreedy
: public MachineFunctionPass
,
74 private LiveRangeEdit::Delegate
{
75 // Interface to eviction advisers
77 /// Track allocation stage and eviction loop prevention during allocation.
78 class ExtraRegInfo final
{
79 // RegInfo - Keep additional information about each live range.
81 LiveRangeStage Stage
= RS_New
;
83 // Cascade - Eviction loop prevention. See
84 // canEvictInterferenceBasedOnCost().
90 IndexedMap
<RegInfo
, VirtReg2IndexFunctor
> Info
;
91 unsigned NextCascade
= 1;
94 ExtraRegInfo() = default;
95 ExtraRegInfo(const ExtraRegInfo
&) = delete;
97 LiveRangeStage
getStage(Register Reg
) const { return Info
[Reg
].Stage
; }
99 LiveRangeStage
getStage(const LiveInterval
&VirtReg
) const {
100 return getStage(VirtReg
.reg());
103 void setStage(Register Reg
, LiveRangeStage Stage
) {
105 Info
[Reg
].Stage
= Stage
;
108 void setStage(const LiveInterval
&VirtReg
, LiveRangeStage Stage
) {
109 setStage(VirtReg
.reg(), Stage
);
112 /// Return the current stage of the register, if present, otherwise
113 /// initialize it and return that.
114 LiveRangeStage
getOrInitStage(Register Reg
) {
116 return getStage(Reg
);
119 unsigned getCascade(Register Reg
) const { return Info
[Reg
].Cascade
; }
121 void setCascade(Register Reg
, unsigned Cascade
) {
123 Info
[Reg
].Cascade
= Cascade
;
126 unsigned getOrAssignNewCascade(Register Reg
) {
127 unsigned Cascade
= getCascade(Reg
);
129 Cascade
= NextCascade
++;
130 setCascade(Reg
, Cascade
);
135 unsigned getCascadeOrCurrentNext(Register Reg
) const {
136 unsigned Cascade
= getCascade(Reg
);
138 Cascade
= NextCascade
;
142 template <typename Iterator
>
143 void setStage(Iterator Begin
, Iterator End
, LiveRangeStage NewStage
) {
144 for (; Begin
!= End
; ++Begin
) {
145 Register Reg
= *Begin
;
147 if (Info
[Reg
].Stage
== RS_New
)
148 Info
[Reg
].Stage
= NewStage
;
151 void LRE_DidCloneVirtReg(Register New
, Register Old
);
154 LiveRegMatrix
*getInterferenceMatrix() const { return Matrix
; }
155 LiveIntervals
*getLiveIntervals() const { return LIS
; }
156 VirtRegMap
*getVirtRegMap() const { return VRM
; }
157 const RegisterClassInfo
&getRegClassInfo() const { return RegClassInfo
; }
158 const ExtraRegInfo
&getExtraInfo() const { return *ExtraInfo
; }
159 // end (interface to eviction advisers)
162 // Convenient shortcuts.
163 using PQueue
= std::priority_queue
<std::pair
<unsigned, unsigned>>;
164 using SmallLISet
= SmallPtrSet
<LiveInterval
*, 4>;
169 // Shortcuts to some useful interface.
170 const TargetInstrInfo
*TII
;
171 const TargetRegisterInfo
*TRI
;
172 RegisterClassInfo RCI
;
175 SlotIndexes
*Indexes
;
176 MachineBlockFrequencyInfo
*MBFI
;
177 MachineDominatorTree
*DomTree
;
178 MachineLoopInfo
*Loops
;
179 MachineOptimizationRemarkEmitter
*ORE
;
180 EdgeBundles
*Bundles
;
181 SpillPlacement
*SpillPlacer
;
182 LiveDebugVariables
*DebugVars
;
186 std::unique_ptr
<Spiller
> SpillerInstance
;
188 std::unique_ptr
<VirtRegAuxInfo
> VRAI
;
189 Optional
<ExtraRegInfo
> ExtraInfo
;
190 std::unique_ptr
<RegAllocEvictionAdvisor
> EvictAdvisor
;
192 // Enum CutOffStage to keep a track whether the register allocation failed
193 // because of the cutoffs encountered in last chance recoloring.
194 // Note: This is used as bitmask. New value should be next power of 2.
196 // No cutoffs encountered
199 // lcr-max-depth cutoff encountered
202 // lcr-max-interf cutoff encountered
209 static const char *const StageName
[];
212 /// EvictionTrack - Keeps track of past evictions in order to optimize region
214 class EvictionTrack
{
218 std::pair
<Register
/* evictor */, MCRegister
/* physreg */>;
219 using EvicteeInfo
= llvm::DenseMap
<Register
/* evictee */, EvictorInfo
>;
222 /// Each Vreg that has been evicted in the last stage of selectOrSplit will
223 /// be mapped to the evictor Vreg and the PhysReg it was evicted from.
224 EvicteeInfo Evictees
;
227 /// Clear all eviction information.
228 void clear() { Evictees
.clear(); }
230 /// Clear eviction information for the given evictee Vreg.
231 /// E.g. when Vreg get's a new allocation, the old eviction info is no
233 /// \param Evictee The evictee Vreg for whom we want to clear collected
235 void clearEvicteeInfo(Register Evictee
) { Evictees
.erase(Evictee
); }
237 /// Track new eviction.
238 /// The Evictor vreg has evicted the Evictee vreg from Physreg.
239 /// \param PhysReg The physical register Evictee was evicted from.
240 /// \param Evictor The evictor Vreg that evicted Evictee.
241 /// \param Evictee The evictee Vreg.
242 void addEviction(MCRegister PhysReg
, Register Evictor
, Register Evictee
) {
243 Evictees
[Evictee
].first
= Evictor
;
244 Evictees
[Evictee
].second
= PhysReg
;
247 /// Return the Evictor Vreg which evicted Evictee Vreg from PhysReg.
248 /// \param Evictee The evictee vreg.
249 /// \return The Evictor vreg which evicted Evictee vreg from PhysReg. 0 if
250 /// nobody has evicted Evictee from PhysReg.
251 EvictorInfo
getEvictor(Register Evictee
) {
252 if (Evictees
.count(Evictee
)) {
253 return Evictees
[Evictee
];
256 return EvictorInfo(0, 0);
260 // Keeps track of past evictions in order to optimize region split decision.
261 EvictionTrack LastEvicted
;
264 std::unique_ptr
<SplitAnalysis
> SA
;
265 std::unique_ptr
<SplitEditor
> SE
;
267 /// Cached per-block interference maps
268 InterferenceCache IntfCache
;
270 /// All basic blocks where the current register has uses.
271 SmallVector
<SpillPlacement::BlockConstraint
, 8> SplitConstraints
;
273 /// Global live range splitting candidate info.
274 struct GlobalSplitCandidate
{
275 // Register intended for assignment, or 0.
278 // SplitKit interval index for this candidate.
281 // Interference for PhysReg.
282 InterferenceCache::Cursor Intf
;
284 // Bundles where this candidate should be live.
285 BitVector LiveBundles
;
286 SmallVector
<unsigned, 8> ActiveBlocks
;
288 void reset(InterferenceCache
&Cache
, MCRegister Reg
) {
291 Intf
.setPhysReg(Cache
, Reg
);
293 ActiveBlocks
.clear();
296 // Set B[I] = C for every live bundle where B[I] was NoCand.
297 unsigned getBundles(SmallVectorImpl
<unsigned> &B
, unsigned C
) {
299 for (unsigned I
: LiveBundles
.set_bits())
300 if (B
[I
] == NoCand
) {
308 /// Candidate info for each PhysReg in AllocationOrder.
309 /// This vector never shrinks, but grows to the size of the largest register
311 SmallVector
<GlobalSplitCandidate
, 32> GlobalCand
;
313 enum : unsigned { NoCand
= ~0u };
315 /// Candidate map. Each edge bundle is assigned to a GlobalCand entry, or to
316 /// NoCand which indicates the stack interval.
317 SmallVector
<unsigned, 32> BundleCand
;
319 /// Callee-save register cost, calculated once per machine function.
320 BlockFrequency CSRCost
;
322 /// Enable or not the consideration of the cost of local intervals created
323 /// by a split candidate when choosing the best split candidate.
324 bool EnableAdvancedRASplitCost
;
326 /// Set of broken hints that may be reconciled later because of eviction.
327 SmallSetVector
<LiveInterval
*, 8> SetOfBrokenHints
;
329 /// The register cost values. This list will be recreated for each Machine
331 ArrayRef
<uint8_t> RegCosts
;
334 RAGreedy(const RegClassFilterFunc F
= allocateAllRegClasses
);
336 /// Return the pass name.
337 StringRef
getPassName() const override
{ return "Greedy Register Allocator"; }
339 /// RAGreedy analysis usage.
340 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
341 void releaseMemory() override
;
342 Spiller
&spiller() override
{ return *SpillerInstance
; }
343 void enqueueImpl(LiveInterval
*LI
) override
;
344 LiveInterval
*dequeue() override
;
345 MCRegister
selectOrSplit(LiveInterval
&,
346 SmallVectorImpl
<Register
> &) override
;
347 void aboutToRemoveInterval(LiveInterval
&) override
;
349 /// Perform register allocation.
350 bool runOnMachineFunction(MachineFunction
&mf
) override
;
352 MachineFunctionProperties
getRequiredProperties() const override
{
353 return MachineFunctionProperties().set(
354 MachineFunctionProperties::Property::NoPHIs
);
357 MachineFunctionProperties
getClearedProperties() const override
{
358 return MachineFunctionProperties().set(
359 MachineFunctionProperties::Property::IsSSA
);
365 MCRegister
selectOrSplitImpl(LiveInterval
&, SmallVectorImpl
<Register
> &,
366 SmallVirtRegSet
&, unsigned = 0);
368 bool LRE_CanEraseVirtReg(Register
) override
;
369 void LRE_WillShrinkVirtReg(Register
) override
;
370 void LRE_DidCloneVirtReg(Register
, Register
) override
;
371 void enqueue(PQueue
&CurQueue
, LiveInterval
*LI
);
372 LiveInterval
*dequeue(PQueue
&CurQueue
);
374 BlockFrequency
calcSpillCost();
375 bool addSplitConstraints(InterferenceCache::Cursor
, BlockFrequency
&);
376 bool addThroughConstraints(InterferenceCache::Cursor
, ArrayRef
<unsigned>);
377 bool growRegion(GlobalSplitCandidate
&Cand
);
378 bool splitCanCauseEvictionChain(Register Evictee
, GlobalSplitCandidate
&Cand
,
380 const AllocationOrder
&Order
);
381 bool splitCanCauseLocalSpill(unsigned VirtRegToSplit
,
382 GlobalSplitCandidate
&Cand
, unsigned BBNumber
,
383 const AllocationOrder
&Order
);
384 BlockFrequency
calcGlobalSplitCost(GlobalSplitCandidate
&,
385 const AllocationOrder
&Order
,
386 bool *CanCauseEvictionChain
);
387 bool calcCompactRegion(GlobalSplitCandidate
&);
388 void splitAroundRegion(LiveRangeEdit
&, ArrayRef
<unsigned>);
389 void calcGapWeights(MCRegister
, SmallVectorImpl
<float> &);
390 bool canEvictInterferenceInRange(const LiveInterval
&VirtReg
,
391 MCRegister PhysReg
, SlotIndex Start
,
392 SlotIndex End
, EvictionCost
&MaxCost
) const;
393 MCRegister
getCheapestEvicteeWeight(const AllocationOrder
&Order
,
394 const LiveInterval
&VirtReg
,
395 SlotIndex Start
, SlotIndex End
,
396 float *BestEvictWeight
) const;
397 void evictInterference(LiveInterval
&, MCRegister
,
398 SmallVectorImpl
<Register
> &);
399 bool mayRecolorAllInterferences(MCRegister PhysReg
, LiveInterval
&VirtReg
,
400 SmallLISet
&RecoloringCandidates
,
401 const SmallVirtRegSet
&FixedRegisters
);
403 MCRegister
tryAssign(LiveInterval
&, AllocationOrder
&,
404 SmallVectorImpl
<Register
> &, const SmallVirtRegSet
&);
405 MCRegister
tryEvict(LiveInterval
&, AllocationOrder
&,
406 SmallVectorImpl
<Register
> &, uint8_t,
407 const SmallVirtRegSet
&);
408 MCRegister
tryRegionSplit(LiveInterval
&, AllocationOrder
&,
409 SmallVectorImpl
<Register
> &);
410 /// Calculate cost of region splitting.
411 unsigned calculateRegionSplitCost(LiveInterval
&VirtReg
,
412 AllocationOrder
&Order
,
413 BlockFrequency
&BestCost
,
414 unsigned &NumCands
, bool IgnoreCSR
,
415 bool *CanCauseEvictionChain
= nullptr);
416 /// Perform region splitting.
417 unsigned doRegionSplit(LiveInterval
&VirtReg
, unsigned BestCand
,
418 bool HasCompact
, SmallVectorImpl
<Register
> &NewVRegs
);
419 /// Check other options before using a callee-saved register for the first
421 MCRegister
tryAssignCSRFirstTime(LiveInterval
&VirtReg
,
422 AllocationOrder
&Order
, MCRegister PhysReg
,
423 uint8_t &CostPerUseLimit
,
424 SmallVectorImpl
<Register
> &NewVRegs
);
425 void initializeCSRCost();
426 unsigned tryBlockSplit(LiveInterval
&, AllocationOrder
&,
427 SmallVectorImpl
<Register
> &);
428 unsigned tryInstructionSplit(LiveInterval
&, AllocationOrder
&,
429 SmallVectorImpl
<Register
> &);
430 unsigned tryLocalSplit(LiveInterval
&, AllocationOrder
&,
431 SmallVectorImpl
<Register
> &);
432 unsigned trySplit(LiveInterval
&, AllocationOrder
&,
433 SmallVectorImpl
<Register
> &, const SmallVirtRegSet
&);
434 unsigned tryLastChanceRecoloring(LiveInterval
&, AllocationOrder
&,
435 SmallVectorImpl
<Register
> &,
436 SmallVirtRegSet
&, unsigned);
437 bool tryRecoloringCandidates(PQueue
&, SmallVectorImpl
<Register
> &,
438 SmallVirtRegSet
&, unsigned);
439 void tryHintRecoloring(LiveInterval
&);
440 void tryHintsRecoloring();
442 /// Model the information carried by one end of a copy.
444 /// The frequency of the copy.
446 /// The virtual register or physical register.
448 /// Its currently assigned register.
449 /// In case of a physical register Reg == PhysReg.
452 HintInfo(BlockFrequency Freq
, Register Reg
, MCRegister PhysReg
)
453 : Freq(Freq
), Reg(Reg
), PhysReg(PhysReg
) {}
455 using HintsInfo
= SmallVector
<HintInfo
, 4>;
457 BlockFrequency
getBrokenHintFreq(const HintsInfo
&, MCRegister
);
458 void collectHintInfo(Register
, HintsInfo
&);
460 /// Greedy RA statistic to remark.
461 struct RAGreedyStats
{
462 unsigned Reloads
= 0;
463 unsigned FoldedReloads
= 0;
464 unsigned ZeroCostFoldedReloads
= 0;
466 unsigned FoldedSpills
= 0;
468 float ReloadsCost
= 0.0f
;
469 float FoldedReloadsCost
= 0.0f
;
470 float SpillsCost
= 0.0f
;
471 float FoldedSpillsCost
= 0.0f
;
472 float CopiesCost
= 0.0f
;
475 return !(Reloads
|| FoldedReloads
|| Spills
|| FoldedSpills
||
476 ZeroCostFoldedReloads
|| Copies
);
479 void add(RAGreedyStats other
) {
480 Reloads
+= other
.Reloads
;
481 FoldedReloads
+= other
.FoldedReloads
;
482 ZeroCostFoldedReloads
+= other
.ZeroCostFoldedReloads
;
483 Spills
+= other
.Spills
;
484 FoldedSpills
+= other
.FoldedSpills
;
485 Copies
+= other
.Copies
;
486 ReloadsCost
+= other
.ReloadsCost
;
487 FoldedReloadsCost
+= other
.FoldedReloadsCost
;
488 SpillsCost
+= other
.SpillsCost
;
489 FoldedSpillsCost
+= other
.FoldedSpillsCost
;
490 CopiesCost
+= other
.CopiesCost
;
493 void report(MachineOptimizationRemarkMissed
&R
);
496 /// Compute statistic for a basic block.
497 RAGreedyStats
computeStats(MachineBasicBlock
&MBB
);
499 /// Compute and report statistic through a remark.
500 RAGreedyStats
reportStats(MachineLoop
*L
);
502 /// Report the statistic for each loop.
506 #endif // #ifndef LLVM_CODEGEN_REGALLOCGREEDY_H_