1 //===- RegAllocPriorityAdvisor.h - live ranges priority advisor -*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H 10 #define LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H 11 12 #include "llvm/CodeGen/MachineBasicBlock.h" 13 #include "llvm/CodeGen/RegAllocEvictionAdvisor.h" 14 #include "llvm/CodeGen/SlotIndexes.h" 15 #include "llvm/IR/PassManager.h" 16 #include "llvm/Pass.h" 17 18 namespace llvm { 19 20 class MachineFunction; 21 class VirtRegMap; 22 class RAGreedy; 23 24 /// Interface to the priority advisor, which is responsible for prioritizing 25 /// live ranges. 26 class RegAllocPriorityAdvisor { 27 public: 28 RegAllocPriorityAdvisor(const RegAllocPriorityAdvisor &) = delete; 29 RegAllocPriorityAdvisor(RegAllocPriorityAdvisor &&) = delete; 30 virtual ~RegAllocPriorityAdvisor() = default; 31 32 /// Find the priority value for a live range. A float value is used since ML 33 /// prefers it. 34 virtual unsigned getPriority(const LiveInterval &LI) const = 0; 35 36 RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, 37 SlotIndexes *const Indexes); 38 39 protected: 40 const RAGreedy &RA; 41 LiveIntervals *const LIS; 42 VirtRegMap *const VRM; 43 MachineRegisterInfo *const MRI; 44 const TargetRegisterInfo *const TRI; 45 const RegisterClassInfo &RegClassInfo; 46 SlotIndexes *const Indexes; 47 const bool RegClassPriorityTrumpsGlobalness; 48 const bool ReverseLocalAssignment; 49 }; 50 51 class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor { 52 public: DefaultPriorityAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes * const Indexes)53 DefaultPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, 54 SlotIndexes *const Indexes) 55 : RegAllocPriorityAdvisor(MF, RA, Indexes) {} 56 57 private: 58 unsigned getPriority(const LiveInterval &LI) const override; 59 }; 60 61 /// Stupid priority advisor which just enqueues in virtual register number 62 /// order, for debug purposes only. 63 class DummyPriorityAdvisor : public RegAllocPriorityAdvisor { 64 public: DummyPriorityAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes * const Indexes)65 DummyPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, 66 SlotIndexes *const Indexes) 67 : RegAllocPriorityAdvisor(MF, RA, Indexes) {} 68 69 private: 70 unsigned getPriority(const LiveInterval &LI) const override; 71 }; 72 73 /// Common provider for getting the priority advisor and logging rewards. 74 /// Legacy analysis forwards all calls to this provider. 75 /// New analysis serves the provider as the analysis result. 76 /// Expensive setup is done in the constructor, so that the advisor can be 77 /// created quickly for every machine function. 78 /// TODO: Remove once legacy PM support is dropped. 79 class RegAllocPriorityAdvisorProvider { 80 public: 81 enum class AdvisorMode : int { Default, Release, Development, Dummy }; 82 RegAllocPriorityAdvisorProvider(AdvisorMode Mode)83 RegAllocPriorityAdvisorProvider(AdvisorMode Mode) : Mode(Mode) {} 84 85 virtual ~RegAllocPriorityAdvisorProvider() = default; 86 logRewardIfNeeded(const MachineFunction & MF,function_ref<float ()> GetReward)87 virtual void logRewardIfNeeded(const MachineFunction &MF, 88 function_ref<float()> GetReward) {}; 89 90 virtual std::unique_ptr<RegAllocPriorityAdvisor> 91 getAdvisor(const MachineFunction &MF, const RAGreedy &RA, 92 SlotIndexes &SI) = 0; 93 getAdvisorMode()94 AdvisorMode getAdvisorMode() const { return Mode; } 95 96 private: 97 const AdvisorMode Mode; 98 }; 99 100 class RegAllocPriorityAdvisorAnalysis 101 : public AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis> { 102 static AnalysisKey Key; 103 friend AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis>; 104 105 public: 106 struct Result { 107 // Owned by this analysis. 108 RegAllocPriorityAdvisorProvider *Provider; 109 invalidateResult110 bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, 111 MachineFunctionAnalysisManager::Invalidator &Inv) { 112 auto PAC = PA.getChecker<RegAllocPriorityAdvisorAnalysis>(); 113 return !PAC.preservedWhenStateless() || 114 Inv.invalidate<SlotIndexesAnalysis>(MF, PA); 115 } 116 }; 117 118 Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM); 119 120 private: 121 void initializeProvider(LLVMContext &Ctx); 122 void initializeMLProvider(RegAllocPriorityAdvisorProvider::AdvisorMode Mode, 123 LLVMContext &Ctx); 124 std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider; 125 }; 126 127 class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass { 128 public: 129 using AdvisorMode = RegAllocPriorityAdvisorProvider::AdvisorMode; RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode)130 RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode) 131 : ImmutablePass(ID), Mode(Mode) {}; 132 static char ID; 133 134 /// Get an advisor for the given context (i.e. machine function, etc) getProvider()135 RegAllocPriorityAdvisorProvider &getProvider() { return *Provider; } getAdvisorMode()136 AdvisorMode getAdvisorMode() const { return Mode; } logRewardIfNeeded(const MachineFunction & MF,llvm::function_ref<float ()> GetReward)137 virtual void logRewardIfNeeded(const MachineFunction &MF, 138 llvm::function_ref<float()> GetReward) {}; 139 140 protected: 141 // This analysis preserves everything, and subclasses may have additional 142 // requirements. getAnalysisUsage(AnalysisUsage & AU)143 void getAnalysisUsage(AnalysisUsage &AU) const override { 144 AU.setPreservesAll(); 145 } 146 147 std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider; 148 149 private: 150 StringRef getPassName() const override; 151 const AdvisorMode Mode; 152 }; 153 154 /// Specialization for the API used by the analysis infrastructure to create 155 /// an instance of the priority advisor. 156 template <> Pass *callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>(); 157 158 RegAllocPriorityAdvisorAnalysisLegacy * 159 createReleaseModePriorityAdvisorAnalysis(); 160 161 RegAllocPriorityAdvisorAnalysisLegacy * 162 createDevelopmentModePriorityAdvisorAnalysis(); 163 164 LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider * 165 createReleaseModePriorityAdvisorProvider(); 166 167 LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider * 168 createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx); 169 170 } // namespace llvm 171 172 #endif // LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H 173