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