xref: /llvm-project/llvm/lib/CodeGen/RegAllocGreedy.h (revision d9b4bdbff597d0ed98dd82674e456ac4c751a6a0)
1c4161077SMircea Trofin //==- RegAllocGreedy.h ------- greedy register allocator  ----------*-C++-*-==//
2c4161077SMircea Trofin //
3c4161077SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c4161077SMircea Trofin // See https://llvm.org/LICENSE.txt for license information.
5c4161077SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c4161077SMircea Trofin //
7c4161077SMircea Trofin //===----------------------------------------------------------------------===//
8c4161077SMircea Trofin // This file defines the RAGreedy function pass for register allocation in
9c4161077SMircea Trofin // optimized builds.
10c4161077SMircea Trofin //===----------------------------------------------------------------------===//
11c4161077SMircea Trofin 
12c4161077SMircea Trofin #ifndef LLVM_CODEGEN_REGALLOCGREEDY_H_
13c4161077SMircea Trofin #define LLVM_CODEGEN_REGALLOCGREEDY_H_
14c4161077SMircea Trofin 
15c4161077SMircea Trofin #include "InterferenceCache.h"
16c4161077SMircea Trofin #include "RegAllocBase.h"
17c4161077SMircea Trofin #include "RegAllocEvictionAdvisor.h"
18ad8eb855SEric Wang #include "RegAllocPriorityAdvisor.h"
19c4161077SMircea Trofin #include "SplitKit.h"
20c4161077SMircea Trofin #include "llvm/ADT/ArrayRef.h"
21c4161077SMircea Trofin #include "llvm/ADT/BitVector.h"
22c4161077SMircea Trofin #include "llvm/ADT/IndexedMap.h"
23c4161077SMircea Trofin #include "llvm/ADT/SetVector.h"
24c4161077SMircea Trofin #include "llvm/ADT/SmallVector.h"
25c4161077SMircea Trofin #include "llvm/ADT/StringRef.h"
26c4161077SMircea Trofin #include "llvm/CodeGen/CalcSpillWeights.h"
27*d9b4bdbfSAkshat Oke #include "llvm/CodeGen/LiveDebugVariables.h"
28c4161077SMircea Trofin #include "llvm/CodeGen/LiveInterval.h"
29c4161077SMircea Trofin #include "llvm/CodeGen/LiveRangeEdit.h"
30c4161077SMircea Trofin #include "llvm/CodeGen/MachineFunction.h"
31c4161077SMircea Trofin #include "llvm/CodeGen/MachineFunctionPass.h"
32c4161077SMircea Trofin #include "llvm/CodeGen/RegisterClassInfo.h"
33b68340c8SAkshat Oke #include "llvm/CodeGen/SpillPlacement.h"
34c4161077SMircea Trofin #include "llvm/CodeGen/Spiller.h"
35c4161077SMircea Trofin #include "llvm/CodeGen/TargetRegisterInfo.h"
36c4161077SMircea Trofin #include <algorithm>
37c4161077SMircea Trofin #include <cstdint>
38c4161077SMircea Trofin #include <memory>
39c4161077SMircea Trofin #include <queue>
40c4161077SMircea Trofin #include <utility>
41c4161077SMircea Trofin 
42c4161077SMircea Trofin namespace llvm {
43989f1c72Sserge-sans-paille class AllocationOrder;
44989f1c72Sserge-sans-paille class AnalysisUsage;
45989f1c72Sserge-sans-paille class EdgeBundles;
46*d9b4bdbfSAkshat Oke class LiveDebugVariablesWrapperLegacy;
47989f1c72Sserge-sans-paille class LiveIntervals;
48989f1c72Sserge-sans-paille class LiveRegMatrix;
49989f1c72Sserge-sans-paille class MachineBasicBlock;
50989f1c72Sserge-sans-paille class MachineBlockFrequencyInfo;
51989f1c72Sserge-sans-paille class MachineDominatorTree;
52989f1c72Sserge-sans-paille class MachineLoop;
53989f1c72Sserge-sans-paille class MachineLoopInfo;
54989f1c72Sserge-sans-paille class MachineOptimizationRemarkEmitter;
55989f1c72Sserge-sans-paille class MachineOptimizationRemarkMissed;
56989f1c72Sserge-sans-paille class SlotIndexes;
57989f1c72Sserge-sans-paille class TargetInstrInfo;
58989f1c72Sserge-sans-paille class VirtRegMap;
59989f1c72Sserge-sans-paille 
6056ec762aSMichael Liao class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass,
61c4161077SMircea Trofin                                          public RegAllocBase,
62c4161077SMircea Trofin                                          private LiveRangeEdit::Delegate {
63e1212691SMircea Trofin   // Interface to eviction advisers
64e1212691SMircea Trofin public:
65e1212691SMircea Trofin   /// Track allocation stage and eviction loop prevention during allocation.
66e1212691SMircea Trofin   class ExtraRegInfo final {
67e1212691SMircea Trofin     // RegInfo - Keep additional information about each live range.
68e1212691SMircea Trofin     struct RegInfo {
69e1212691SMircea Trofin       LiveRangeStage Stage = RS_New;
70e1212691SMircea Trofin 
71e1212691SMircea Trofin       // Cascade - Eviction loop prevention. See
72e1212691SMircea Trofin       // canEvictInterferenceBasedOnCost().
73e1212691SMircea Trofin       unsigned Cascade = 0;
74e1212691SMircea Trofin 
75e1212691SMircea Trofin       RegInfo() = default;
76e1212691SMircea Trofin     };
77e1212691SMircea Trofin 
78e1212691SMircea Trofin     IndexedMap<RegInfo, VirtReg2IndexFunctor> Info;
79e1212691SMircea Trofin     unsigned NextCascade = 1;
80e1212691SMircea Trofin 
81e1212691SMircea Trofin   public:
822916b991SBenjamin Kramer     ExtraRegInfo() {}
83e1212691SMircea Trofin     ExtraRegInfo(const ExtraRegInfo &) = delete;
84e1212691SMircea Trofin 
85e1212691SMircea Trofin     LiveRangeStage getStage(Register Reg) const { return Info[Reg].Stage; }
86e1212691SMircea Trofin 
87e1212691SMircea Trofin     LiveRangeStage getStage(const LiveInterval &VirtReg) const {
88e1212691SMircea Trofin       return getStage(VirtReg.reg());
89e1212691SMircea Trofin     }
90e1212691SMircea Trofin 
91e1212691SMircea Trofin     void setStage(Register Reg, LiveRangeStage Stage) {
92e1212691SMircea Trofin       Info.grow(Reg.id());
93e1212691SMircea Trofin       Info[Reg].Stage = Stage;
94e1212691SMircea Trofin     }
95e1212691SMircea Trofin 
96e1212691SMircea Trofin     void setStage(const LiveInterval &VirtReg, LiveRangeStage Stage) {
97e1212691SMircea Trofin       setStage(VirtReg.reg(), Stage);
98e1212691SMircea Trofin     }
99e1212691SMircea Trofin 
100e1212691SMircea Trofin     /// Return the current stage of the register, if present, otherwise
101e1212691SMircea Trofin     /// initialize it and return that.
102e1212691SMircea Trofin     LiveRangeStage getOrInitStage(Register Reg) {
103e1212691SMircea Trofin       Info.grow(Reg.id());
104e1212691SMircea Trofin       return getStage(Reg);
105e1212691SMircea Trofin     }
106e1212691SMircea Trofin 
107e1212691SMircea Trofin     unsigned getCascade(Register Reg) const { return Info[Reg].Cascade; }
108e1212691SMircea Trofin 
109e1212691SMircea Trofin     void setCascade(Register Reg, unsigned Cascade) {
110e1212691SMircea Trofin       Info.grow(Reg.id());
111e1212691SMircea Trofin       Info[Reg].Cascade = Cascade;
112e1212691SMircea Trofin     }
113e1212691SMircea Trofin 
114e1212691SMircea Trofin     unsigned getOrAssignNewCascade(Register Reg) {
115e1212691SMircea Trofin       unsigned Cascade = getCascade(Reg);
116e1212691SMircea Trofin       if (!Cascade) {
117e1212691SMircea Trofin         Cascade = NextCascade++;
118e1212691SMircea Trofin         setCascade(Reg, Cascade);
119e1212691SMircea Trofin       }
120e1212691SMircea Trofin       return Cascade;
121e1212691SMircea Trofin     }
122e1212691SMircea Trofin 
123e1212691SMircea Trofin     unsigned getCascadeOrCurrentNext(Register Reg) const {
124e1212691SMircea Trofin       unsigned Cascade = getCascade(Reg);
125e1212691SMircea Trofin       if (!Cascade)
126e1212691SMircea Trofin         Cascade = NextCascade;
127e1212691SMircea Trofin       return Cascade;
128e1212691SMircea Trofin     }
129e1212691SMircea Trofin 
130e1212691SMircea Trofin     template <typename Iterator>
131e1212691SMircea Trofin     void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
132e1212691SMircea Trofin       for (; Begin != End; ++Begin) {
133e1212691SMircea Trofin         Register Reg = *Begin;
134e1212691SMircea Trofin         Info.grow(Reg.id());
135e1212691SMircea Trofin         if (Info[Reg].Stage == RS_New)
136e1212691SMircea Trofin           Info[Reg].Stage = NewStage;
137e1212691SMircea Trofin       }
138e1212691SMircea Trofin     }
139e1212691SMircea Trofin     void LRE_DidCloneVirtReg(Register New, Register Old);
140e1212691SMircea Trofin   };
141e1212691SMircea Trofin 
142e1212691SMircea Trofin   LiveRegMatrix *getInterferenceMatrix() const { return Matrix; }
143e1212691SMircea Trofin   LiveIntervals *getLiveIntervals() const { return LIS; }
144e1212691SMircea Trofin   VirtRegMap *getVirtRegMap() const { return VRM; }
145e1212691SMircea Trofin   const RegisterClassInfo &getRegClassInfo() const { return RegClassInfo; }
146e1212691SMircea Trofin   const ExtraRegInfo &getExtraInfo() const { return *ExtraInfo; }
147e67430ccSMircea Trofin   size_t getQueueSize() const { return Queue.size(); }
148e1212691SMircea Trofin   // end (interface to eviction advisers)
149e1212691SMircea Trofin 
150ad8eb855SEric Wang   // Interface to priority advisers
151ad8eb855SEric Wang   bool getRegClassPriorityTrumpsGlobalness() const {
152ad8eb855SEric Wang     return RegClassPriorityTrumpsGlobalness;
153ad8eb855SEric Wang   }
154ad8eb855SEric Wang   bool getReverseLocalAssignment() const { return ReverseLocalAssignment; }
155ad8eb855SEric Wang   // end (interface to priority advisers)
156ad8eb855SEric Wang 
157e1212691SMircea Trofin private:
158c4161077SMircea Trofin   // Convenient shortcuts.
159c4161077SMircea Trofin   using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
160bfdca153SMatt Arsenault   using SmallLISet = SmallSetVector<const LiveInterval *, 4>;
161c4161077SMircea Trofin 
162eefed1dbSMatt Arsenault   // We need to track all tentative recolorings so we can roll back any
163eefed1dbSMatt Arsenault   // successful and unsuccessful recoloring attempts.
164eefed1dbSMatt Arsenault   using RecoloringStack =
165eefed1dbSMatt Arsenault       SmallVector<std::pair<const LiveInterval *, MCRegister>, 8>;
166eefed1dbSMatt Arsenault 
167c4161077SMircea Trofin   // context
1688bf7f86dSAkshay Khadse   MachineFunction *MF = nullptr;
169c4161077SMircea Trofin 
170c4161077SMircea Trofin   // Shortcuts to some useful interface.
1718bf7f86dSAkshay Khadse   const TargetInstrInfo *TII = nullptr;
172c4161077SMircea Trofin 
173c4161077SMircea Trofin   // analyses
1748bf7f86dSAkshay Khadse   SlotIndexes *Indexes = nullptr;
1758bf7f86dSAkshay Khadse   MachineBlockFrequencyInfo *MBFI = nullptr;
1768bf7f86dSAkshay Khadse   MachineDominatorTree *DomTree = nullptr;
1778bf7f86dSAkshay Khadse   MachineLoopInfo *Loops = nullptr;
1788bf7f86dSAkshay Khadse   MachineOptimizationRemarkEmitter *ORE = nullptr;
1798bf7f86dSAkshay Khadse   EdgeBundles *Bundles = nullptr;
1808bf7f86dSAkshay Khadse   SpillPlacement *SpillPlacer = nullptr;
1818bf7f86dSAkshay Khadse   LiveDebugVariables *DebugVars = nullptr;
182c4161077SMircea Trofin 
183c4161077SMircea Trofin   // state
184c4161077SMircea Trofin   std::unique_ptr<Spiller> SpillerInstance;
185c4161077SMircea Trofin   PQueue Queue;
186c4161077SMircea Trofin   std::unique_ptr<VirtRegAuxInfo> VRAI;
18777c90c8cSKazu Hirata   std::optional<ExtraRegInfo> ExtraInfo;
188c4161077SMircea Trofin   std::unique_ptr<RegAllocEvictionAdvisor> EvictAdvisor;
189c4161077SMircea Trofin 
190ad8eb855SEric Wang   std::unique_ptr<RegAllocPriorityAdvisor> PriorityAdvisor;
191ad8eb855SEric Wang 
192c4161077SMircea Trofin   // Enum CutOffStage to keep a track whether the register allocation failed
193c4161077SMircea Trofin   // because of the cutoffs encountered in last chance recoloring.
194c4161077SMircea Trofin   // Note: This is used as bitmask. New value should be next power of 2.
195c4161077SMircea Trofin   enum CutOffStage {
196c4161077SMircea Trofin     // No cutoffs encountered
197c4161077SMircea Trofin     CO_None = 0,
198c4161077SMircea Trofin 
199c4161077SMircea Trofin     // lcr-max-depth cutoff encountered
200c4161077SMircea Trofin     CO_Depth = 1,
201c4161077SMircea Trofin 
202c4161077SMircea Trofin     // lcr-max-interf cutoff encountered
203c4161077SMircea Trofin     CO_Interf = 2
204c4161077SMircea Trofin   };
205c4161077SMircea Trofin 
20643b38696SAkshay Khadse   uint8_t CutOffInfo = CutOffStage::CO_None;
207c4161077SMircea Trofin 
208c4161077SMircea Trofin #ifndef NDEBUG
209c4161077SMircea Trofin   static const char *const StageName[];
210c4161077SMircea Trofin #endif
211c4161077SMircea Trofin 
212c4161077SMircea Trofin   // splitting state.
213c4161077SMircea Trofin   std::unique_ptr<SplitAnalysis> SA;
214c4161077SMircea Trofin   std::unique_ptr<SplitEditor> SE;
215c4161077SMircea Trofin 
216c4161077SMircea Trofin   /// Cached per-block interference maps
217c4161077SMircea Trofin   InterferenceCache IntfCache;
218c4161077SMircea Trofin 
219c4161077SMircea Trofin   /// All basic blocks where the current register has uses.
220c4161077SMircea Trofin   SmallVector<SpillPlacement::BlockConstraint, 8> SplitConstraints;
221c4161077SMircea Trofin 
222c4161077SMircea Trofin   /// Global live range splitting candidate info.
223c4161077SMircea Trofin   struct GlobalSplitCandidate {
224c4161077SMircea Trofin     // Register intended for assignment, or 0.
225c4161077SMircea Trofin     MCRegister PhysReg;
226c4161077SMircea Trofin 
227c4161077SMircea Trofin     // SplitKit interval index for this candidate.
228c4161077SMircea Trofin     unsigned IntvIdx;
229c4161077SMircea Trofin 
230c4161077SMircea Trofin     // Interference for PhysReg.
231c4161077SMircea Trofin     InterferenceCache::Cursor Intf;
232c4161077SMircea Trofin 
233c4161077SMircea Trofin     // Bundles where this candidate should be live.
234c4161077SMircea Trofin     BitVector LiveBundles;
235c4161077SMircea Trofin     SmallVector<unsigned, 8> ActiveBlocks;
236c4161077SMircea Trofin 
237c4161077SMircea Trofin     void reset(InterferenceCache &Cache, MCRegister Reg) {
238c4161077SMircea Trofin       PhysReg = Reg;
239c4161077SMircea Trofin       IntvIdx = 0;
240c4161077SMircea Trofin       Intf.setPhysReg(Cache, Reg);
241c4161077SMircea Trofin       LiveBundles.clear();
242c4161077SMircea Trofin       ActiveBlocks.clear();
243c4161077SMircea Trofin     }
244c4161077SMircea Trofin 
245c4161077SMircea Trofin     // Set B[I] = C for every live bundle where B[I] was NoCand.
246c4161077SMircea Trofin     unsigned getBundles(SmallVectorImpl<unsigned> &B, unsigned C) {
247c4161077SMircea Trofin       unsigned Count = 0;
248c4161077SMircea Trofin       for (unsigned I : LiveBundles.set_bits())
249c4161077SMircea Trofin         if (B[I] == NoCand) {
250c4161077SMircea Trofin           B[I] = C;
251c4161077SMircea Trofin           Count++;
252c4161077SMircea Trofin         }
253c4161077SMircea Trofin       return Count;
254c4161077SMircea Trofin     }
255c4161077SMircea Trofin   };
256c4161077SMircea Trofin 
257c4161077SMircea Trofin   /// Candidate info for each PhysReg in AllocationOrder.
258c4161077SMircea Trofin   /// This vector never shrinks, but grows to the size of the largest register
259c4161077SMircea Trofin   /// class.
260c4161077SMircea Trofin   SmallVector<GlobalSplitCandidate, 32> GlobalCand;
261c4161077SMircea Trofin 
262c4161077SMircea Trofin   enum : unsigned { NoCand = ~0u };
263c4161077SMircea Trofin 
264c4161077SMircea Trofin   /// Candidate map. Each edge bundle is assigned to a GlobalCand entry, or to
265c4161077SMircea Trofin   /// NoCand which indicates the stack interval.
266c4161077SMircea Trofin   SmallVector<unsigned, 32> BundleCand;
267c4161077SMircea Trofin 
268c4161077SMircea Trofin   /// Callee-save register cost, calculated once per machine function.
269c4161077SMircea Trofin   BlockFrequency CSRCost;
270c4161077SMircea Trofin 
271c4161077SMircea Trofin   /// Set of broken hints that may be reconciled later because of eviction.
272592f52deSMircea Trofin   SmallSetVector<const LiveInterval *, 8> SetOfBrokenHints;
273c4161077SMircea Trofin 
274c4161077SMircea Trofin   /// The register cost values. This list will be recreated for each Machine
275c4161077SMircea Trofin   /// Function
276c4161077SMircea Trofin   ArrayRef<uint8_t> RegCosts;
277c4161077SMircea Trofin 
27877480556SJay Foad   /// Flags for the live range priority calculation, determined once per
27977480556SJay Foad   /// machine function.
28043b38696SAkshay Khadse   bool RegClassPriorityTrumpsGlobalness = false;
28177480556SJay Foad 
28243b38696SAkshay Khadse   bool ReverseLocalAssignment = false;
28362531518SMatt Arsenault 
284c4161077SMircea Trofin public:
28515b41d20SChristudasan Devadasan   RAGreedy(const RegAllocFilterFunc F = nullptr);
286c4161077SMircea Trofin 
287c4161077SMircea Trofin   /// Return the pass name.
288c4161077SMircea Trofin   StringRef getPassName() const override { return "Greedy Register Allocator"; }
289c4161077SMircea Trofin 
290c4161077SMircea Trofin   /// RAGreedy analysis usage.
291c4161077SMircea Trofin   void getAnalysisUsage(AnalysisUsage &AU) const override;
292c4161077SMircea Trofin   void releaseMemory() override;
293c4161077SMircea Trofin   Spiller &spiller() override { return *SpillerInstance; }
294592f52deSMircea Trofin   void enqueueImpl(const LiveInterval *LI) override;
295592f52deSMircea Trofin   const LiveInterval *dequeue() override;
296592f52deSMircea Trofin   MCRegister selectOrSplit(const LiveInterval &,
297c4161077SMircea Trofin                            SmallVectorImpl<Register> &) override;
298592f52deSMircea Trofin   void aboutToRemoveInterval(const LiveInterval &) override;
299c4161077SMircea Trofin 
300c4161077SMircea Trofin   /// Perform register allocation.
301c4161077SMircea Trofin   bool runOnMachineFunction(MachineFunction &mf) override;
302c4161077SMircea Trofin 
303c4161077SMircea Trofin   MachineFunctionProperties getRequiredProperties() const override {
304c4161077SMircea Trofin     return MachineFunctionProperties().set(
305c4161077SMircea Trofin         MachineFunctionProperties::Property::NoPHIs);
306c4161077SMircea Trofin   }
307c4161077SMircea Trofin 
308c4161077SMircea Trofin   MachineFunctionProperties getClearedProperties() const override {
309c4161077SMircea Trofin     return MachineFunctionProperties().set(
310c4161077SMircea Trofin         MachineFunctionProperties::Property::IsSSA);
311c4161077SMircea Trofin   }
312c4161077SMircea Trofin 
313c4161077SMircea Trofin   static char ID;
314c4161077SMircea Trofin 
315c4161077SMircea Trofin private:
316592f52deSMircea Trofin   MCRegister selectOrSplitImpl(const LiveInterval &,
317592f52deSMircea Trofin                                SmallVectorImpl<Register> &, SmallVirtRegSet &,
318eefed1dbSMatt Arsenault                                RecoloringStack &, unsigned = 0);
319c4161077SMircea Trofin 
320c4161077SMircea Trofin   bool LRE_CanEraseVirtReg(Register) override;
321c4161077SMircea Trofin   void LRE_WillShrinkVirtReg(Register) override;
322c4161077SMircea Trofin   void LRE_DidCloneVirtReg(Register, Register) override;
323592f52deSMircea Trofin   void enqueue(PQueue &CurQueue, const LiveInterval *LI);
324592f52deSMircea Trofin   const LiveInterval *dequeue(PQueue &CurQueue);
325c4161077SMircea Trofin 
326fa8656d2SLuo, Yuanke   bool hasVirtRegAlloc();
327c4161077SMircea Trofin   BlockFrequency calcSpillCost();
328c4161077SMircea Trofin   bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency &);
329c4161077SMircea Trofin   bool addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>);
330c4161077SMircea Trofin   bool growRegion(GlobalSplitCandidate &Cand);
331c4161077SMircea Trofin   BlockFrequency calcGlobalSplitCost(GlobalSplitCandidate &,
332294eca35SMircea Trofin                                      const AllocationOrder &Order);
333c4161077SMircea Trofin   bool calcCompactRegion(GlobalSplitCandidate &);
334c4161077SMircea Trofin   void splitAroundRegion(LiveRangeEdit &, ArrayRef<unsigned>);
335c4161077SMircea Trofin   void calcGapWeights(MCRegister, SmallVectorImpl<float> &);
336592f52deSMircea Trofin   void evictInterference(const LiveInterval &, MCRegister,
337c4161077SMircea Trofin                          SmallVectorImpl<Register> &);
338592f52deSMircea Trofin   bool mayRecolorAllInterferences(MCRegister PhysReg,
339592f52deSMircea Trofin                                   const LiveInterval &VirtReg,
340c4161077SMircea Trofin                                   SmallLISet &RecoloringCandidates,
341c4161077SMircea Trofin                                   const SmallVirtRegSet &FixedRegisters);
342c4161077SMircea Trofin 
343592f52deSMircea Trofin   MCRegister tryAssign(const LiveInterval &, AllocationOrder &,
344c4161077SMircea Trofin                        SmallVectorImpl<Register> &, const SmallVirtRegSet &);
345592f52deSMircea Trofin   MCRegister tryEvict(const LiveInterval &, AllocationOrder &,
346c4161077SMircea Trofin                       SmallVectorImpl<Register> &, uint8_t,
347c4161077SMircea Trofin                       const SmallVirtRegSet &);
348592f52deSMircea Trofin   MCRegister tryRegionSplit(const LiveInterval &, AllocationOrder &,
349c4161077SMircea Trofin                             SmallVectorImpl<Register> &);
350cbdccb30SGuozhi Wei   /// Calculate cost of region splitting around the specified register.
351cbdccb30SGuozhi Wei   unsigned calculateRegionSplitCostAroundReg(MCPhysReg PhysReg,
352cbdccb30SGuozhi Wei                                              AllocationOrder &Order,
353cbdccb30SGuozhi Wei                                              BlockFrequency &BestCost,
354cbdccb30SGuozhi Wei                                              unsigned &NumCands,
355cbdccb30SGuozhi Wei                                              unsigned &BestCand);
356c4161077SMircea Trofin   /// Calculate cost of region splitting.
357592f52deSMircea Trofin   unsigned calculateRegionSplitCost(const LiveInterval &VirtReg,
358c4161077SMircea Trofin                                     AllocationOrder &Order,
359c4161077SMircea Trofin                                     BlockFrequency &BestCost,
360294eca35SMircea Trofin                                     unsigned &NumCands, bool IgnoreCSR);
361c4161077SMircea Trofin   /// Perform region splitting.
362592f52deSMircea Trofin   unsigned doRegionSplit(const LiveInterval &VirtReg, unsigned BestCand,
363c4161077SMircea Trofin                          bool HasCompact, SmallVectorImpl<Register> &NewVRegs);
364cbdccb30SGuozhi Wei   /// Try to split VirtReg around physical Hint register.
365cbdccb30SGuozhi Wei   bool trySplitAroundHintReg(MCPhysReg Hint, const LiveInterval &VirtReg,
366cbdccb30SGuozhi Wei                              SmallVectorImpl<Register> &NewVRegs,
367cbdccb30SGuozhi Wei                              AllocationOrder &Order);
368c4161077SMircea Trofin   /// Check other options before using a callee-saved register for the first
369c4161077SMircea Trofin   /// time.
370592f52deSMircea Trofin   MCRegister tryAssignCSRFirstTime(const LiveInterval &VirtReg,
371c4161077SMircea Trofin                                    AllocationOrder &Order, MCRegister PhysReg,
372c4161077SMircea Trofin                                    uint8_t &CostPerUseLimit,
373c4161077SMircea Trofin                                    SmallVectorImpl<Register> &NewVRegs);
374c4161077SMircea Trofin   void initializeCSRCost();
375592f52deSMircea Trofin   unsigned tryBlockSplit(const LiveInterval &, AllocationOrder &,
376c4161077SMircea Trofin                          SmallVectorImpl<Register> &);
377592f52deSMircea Trofin   unsigned tryInstructionSplit(const LiveInterval &, AllocationOrder &,
378c4161077SMircea Trofin                                SmallVectorImpl<Register> &);
379592f52deSMircea Trofin   unsigned tryLocalSplit(const LiveInterval &, AllocationOrder &,
380c4161077SMircea Trofin                          SmallVectorImpl<Register> &);
381592f52deSMircea Trofin   unsigned trySplit(const LiveInterval &, AllocationOrder &,
382c4161077SMircea Trofin                     SmallVectorImpl<Register> &, const SmallVirtRegSet &);
383592f52deSMircea Trofin   unsigned tryLastChanceRecoloring(const LiveInterval &, AllocationOrder &,
384c4161077SMircea Trofin                                    SmallVectorImpl<Register> &,
385eefed1dbSMatt Arsenault                                    SmallVirtRegSet &, RecoloringStack &,
386eefed1dbSMatt Arsenault                                    unsigned);
387c4161077SMircea Trofin   bool tryRecoloringCandidates(PQueue &, SmallVectorImpl<Register> &,
388eefed1dbSMatt Arsenault                                SmallVirtRegSet &, RecoloringStack &, unsigned);
389592f52deSMircea Trofin   void tryHintRecoloring(const LiveInterval &);
390c4161077SMircea Trofin   void tryHintsRecoloring();
391c4161077SMircea Trofin 
392c4161077SMircea Trofin   /// Model the information carried by one end of a copy.
393c4161077SMircea Trofin   struct HintInfo {
394c4161077SMircea Trofin     /// The frequency of the copy.
395c4161077SMircea Trofin     BlockFrequency Freq;
396c4161077SMircea Trofin     /// The virtual register or physical register.
397c4161077SMircea Trofin     Register Reg;
398c4161077SMircea Trofin     /// Its currently assigned register.
399c4161077SMircea Trofin     /// In case of a physical register Reg == PhysReg.
400c4161077SMircea Trofin     MCRegister PhysReg;
401c4161077SMircea Trofin 
402c4161077SMircea Trofin     HintInfo(BlockFrequency Freq, Register Reg, MCRegister PhysReg)
403c4161077SMircea Trofin         : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
404c4161077SMircea Trofin   };
405c4161077SMircea Trofin   using HintsInfo = SmallVector<HintInfo, 4>;
406c4161077SMircea Trofin 
407c4161077SMircea Trofin   BlockFrequency getBrokenHintFreq(const HintsInfo &, MCRegister);
408c4161077SMircea Trofin   void collectHintInfo(Register, HintsInfo &);
409c4161077SMircea Trofin 
410c4161077SMircea Trofin   /// Greedy RA statistic to remark.
411c4161077SMircea Trofin   struct RAGreedyStats {
412c4161077SMircea Trofin     unsigned Reloads = 0;
413c4161077SMircea Trofin     unsigned FoldedReloads = 0;
414c4161077SMircea Trofin     unsigned ZeroCostFoldedReloads = 0;
415c4161077SMircea Trofin     unsigned Spills = 0;
416c4161077SMircea Trofin     unsigned FoldedSpills = 0;
417c4161077SMircea Trofin     unsigned Copies = 0;
418c4161077SMircea Trofin     float ReloadsCost = 0.0f;
419c4161077SMircea Trofin     float FoldedReloadsCost = 0.0f;
420c4161077SMircea Trofin     float SpillsCost = 0.0f;
421c4161077SMircea Trofin     float FoldedSpillsCost = 0.0f;
422c4161077SMircea Trofin     float CopiesCost = 0.0f;
423c4161077SMircea Trofin 
424c4161077SMircea Trofin     bool isEmpty() {
425c4161077SMircea Trofin       return !(Reloads || FoldedReloads || Spills || FoldedSpills ||
426c4161077SMircea Trofin                ZeroCostFoldedReloads || Copies);
427c4161077SMircea Trofin     }
428c4161077SMircea Trofin 
42979ce70b8SBraden Helmer     void add(const RAGreedyStats &other) {
430c4161077SMircea Trofin       Reloads += other.Reloads;
431c4161077SMircea Trofin       FoldedReloads += other.FoldedReloads;
432c4161077SMircea Trofin       ZeroCostFoldedReloads += other.ZeroCostFoldedReloads;
433c4161077SMircea Trofin       Spills += other.Spills;
434c4161077SMircea Trofin       FoldedSpills += other.FoldedSpills;
435c4161077SMircea Trofin       Copies += other.Copies;
436c4161077SMircea Trofin       ReloadsCost += other.ReloadsCost;
437c4161077SMircea Trofin       FoldedReloadsCost += other.FoldedReloadsCost;
438c4161077SMircea Trofin       SpillsCost += other.SpillsCost;
439c4161077SMircea Trofin       FoldedSpillsCost += other.FoldedSpillsCost;
440c4161077SMircea Trofin       CopiesCost += other.CopiesCost;
441c4161077SMircea Trofin     }
442c4161077SMircea Trofin 
443c4161077SMircea Trofin     void report(MachineOptimizationRemarkMissed &R);
444c4161077SMircea Trofin   };
445c4161077SMircea Trofin 
446c4161077SMircea Trofin   /// Compute statistic for a basic block.
447c4161077SMircea Trofin   RAGreedyStats computeStats(MachineBasicBlock &MBB);
448c4161077SMircea Trofin 
449c4161077SMircea Trofin   /// Compute and report statistic through a remark.
450c4161077SMircea Trofin   RAGreedyStats reportStats(MachineLoop *L);
451c4161077SMircea Trofin 
452c4161077SMircea Trofin   /// Report the statistic for each loop.
453c4161077SMircea Trofin   void reportStats();
454c4161077SMircea Trofin };
455c4161077SMircea Trofin } // namespace llvm
456c4161077SMircea Trofin #endif // #ifndef LLVM_CODEGEN_REGALLOCGREEDY_H_
457