1 //===- RegAllocPriorityAdvisor.cpp - live ranges priority advisor ---------===// 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 // Implementation of the default priority advisor and of the Analysis pass. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/CodeGen/RegAllocPriorityAdvisor.h" 14 #include "RegAllocGreedy.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/VirtRegMap.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/InitializePasses.h" 19 #include "llvm/Pass.h" 20 21 using namespace llvm; 22 23 static cl::opt<RegAllocPriorityAdvisorProvider::AdvisorMode> Mode( 24 "regalloc-enable-priority-advisor", cl::Hidden, 25 cl::init(RegAllocPriorityAdvisorProvider::AdvisorMode::Default), 26 cl::desc("Enable regalloc advisor mode"), 27 cl::values( 28 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Default, 29 "default", "Default"), 30 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Release, 31 "release", "precompiled"), 32 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Development, 33 "development", "for training"), 34 clEnumValN( 35 RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy, "dummy", 36 "prioritize low virtual register numbers for test and debug"))); 37 38 char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0; 39 INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority", 40 "Regalloc priority policy", false, true) 41 42 namespace { 43 44 class DefaultPriorityAdvisorProvider final 45 : public RegAllocPriorityAdvisorProvider { 46 public: 47 DefaultPriorityAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx) 48 : RegAllocPriorityAdvisorProvider(AdvisorMode::Default) { 49 if (NotAsRequested) 50 Ctx.emitError("Requested regalloc priority advisor analysis " 51 "could be created. Using default"); 52 } 53 54 // support for isa<> and dyn_cast. 55 static bool classof(const RegAllocPriorityAdvisorProvider *R) { 56 return R->getAdvisorMode() == AdvisorMode::Default; 57 } 58 59 std::unique_ptr<RegAllocPriorityAdvisor> 60 getAdvisor(const MachineFunction &MF, const RAGreedy &RA, 61 SlotIndexes &SI) override { 62 return std::make_unique<DefaultPriorityAdvisor>(MF, RA, &SI); 63 } 64 }; 65 66 class DummyPriorityAdvisorProvider final 67 : public RegAllocPriorityAdvisorProvider { 68 public: 69 DummyPriorityAdvisorProvider() 70 : RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {} 71 72 static bool classof(const RegAllocPriorityAdvisorProvider *R) { 73 return R->getAdvisorMode() == AdvisorMode::Dummy; 74 } 75 76 std::unique_ptr<RegAllocPriorityAdvisor> 77 getAdvisor(const MachineFunction &MF, const RAGreedy &RA, 78 SlotIndexes &SI) override { 79 return std::make_unique<DummyPriorityAdvisor>(MF, RA, &SI); 80 } 81 }; 82 83 class DefaultPriorityAdvisorAnalysisLegacy final 84 : public RegAllocPriorityAdvisorAnalysisLegacy { 85 public: 86 DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested) 87 : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default), 88 NotAsRequested(NotAsRequested) {} 89 90 // support for isa<> and dyn_cast. 91 static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) { 92 return R->getAdvisorMode() == AdvisorMode::Default; 93 } 94 95 private: 96 void getAnalysisUsage(AnalysisUsage &AU) const override { 97 AU.addRequired<SlotIndexesWrapperPass>(); 98 RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); 99 } 100 101 bool doInitialization(Module &M) override { 102 Provider.reset( 103 new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext())); 104 return false; 105 } 106 107 const bool NotAsRequested; 108 }; 109 110 class DummyPriorityAdvisorAnalysis final 111 : public RegAllocPriorityAdvisorAnalysisLegacy { 112 public: 113 using RegAllocPriorityAdvisorAnalysisLegacy::AdvisorMode; 114 DummyPriorityAdvisorAnalysis() 115 : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {} 116 117 // support for isa<> and dyn_cast. 118 static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) { 119 return R->getAdvisorMode() == AdvisorMode::Dummy; 120 } 121 122 private: 123 void getAnalysisUsage(AnalysisUsage &AU) const override { 124 AU.addRequired<SlotIndexesWrapperPass>(); 125 RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); 126 } 127 128 bool doInitialization(Module &M) override { 129 Provider.reset(new DummyPriorityAdvisorProvider()); 130 return false; 131 } 132 }; 133 134 } // namespace 135 136 void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) { 137 if (Provider) 138 return; 139 switch (Mode) { 140 case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: 141 Provider.reset(new DummyPriorityAdvisorProvider()); 142 return; 143 case RegAllocPriorityAdvisorProvider::AdvisorMode::Default: 144 Provider.reset( 145 new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/false, Ctx)); 146 return; 147 case RegAllocPriorityAdvisorProvider::AdvisorMode::Development: 148 #if defined(LLVM_HAVE_TFLITE) 149 Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx)); 150 #else 151 Provider.reset( 152 new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx)); 153 #endif 154 return; 155 case RegAllocPriorityAdvisorProvider::AdvisorMode::Release: 156 Provider.reset(createReleaseModePriorityAdvisorProvider()); 157 return; 158 } 159 } 160 161 AnalysisKey RegAllocPriorityAdvisorAnalysis::Key; 162 163 RegAllocPriorityAdvisorAnalysis::Result 164 RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF, 165 MachineFunctionAnalysisManager &MFAM) { 166 // Lazily initialize the provider. 167 initializeProvider(MF.getFunction().getContext()); 168 // The requiring analysis will construct the advisor. 169 return Result{Provider.get()}; 170 } 171 172 template <> 173 Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>() { 174 Pass *Ret = nullptr; 175 switch (Mode) { 176 case RegAllocPriorityAdvisorProvider::AdvisorMode::Default: 177 Ret = new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ false); 178 break; 179 case RegAllocPriorityAdvisorProvider::AdvisorMode::Development: 180 #if defined(LLVM_HAVE_TFLITE) 181 Ret = createDevelopmentModePriorityAdvisorAnalysis(); 182 #endif 183 break; 184 case RegAllocPriorityAdvisorProvider::AdvisorMode::Release: 185 Ret = createReleaseModePriorityAdvisorAnalysis(); 186 break; 187 case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: 188 Ret = new DummyPriorityAdvisorAnalysis(); 189 break; 190 } 191 if (Ret) 192 return Ret; 193 return new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ true); 194 } 195 196 StringRef RegAllocPriorityAdvisorAnalysisLegacy::getPassName() const { 197 switch (getAdvisorMode()) { 198 case AdvisorMode::Default: 199 return "Default Regalloc Priority Advisor"; 200 case AdvisorMode::Release: 201 return "Release mode Regalloc Priority Advisor"; 202 case AdvisorMode::Development: 203 return "Development mode Regalloc Priority Advisor"; 204 case AdvisorMode::Dummy: 205 return "Dummy Regalloc Priority Advisor"; 206 } 207 llvm_unreachable("Unknown advisor kind"); 208 } 209 210 RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF, 211 const RAGreedy &RA, 212 SlotIndexes *const Indexes) 213 : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()), 214 MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()), 215 RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes), 216 RegClassPriorityTrumpsGlobalness( 217 RA.getRegClassPriorityTrumpsGlobalness()), 218 ReverseLocalAssignment(RA.getReverseLocalAssignment()) {} 219