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 "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<RegAllocPriorityAdvisorAnalysis::AdvisorMode> Mode( 24 "regalloc-enable-priority-advisor", cl::Hidden, 25 cl::init(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default), 26 cl::desc("Enable regalloc advisor mode"), 27 cl::values( 28 clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default, 29 "default", "Default"), 30 clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release, 31 "release", "precompiled"), 32 clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development, 33 "development", "for training"), 34 clEnumValN( 35 RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy, "dummy", 36 "prioritize low virtual register numbers for test and debug"))); 37 38 char RegAllocPriorityAdvisorAnalysis::ID = 0; 39 INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority", 40 "Regalloc priority policy", false, true) 41 42 namespace { 43 class DefaultPriorityAdvisorAnalysis final 44 : public RegAllocPriorityAdvisorAnalysis { 45 public: 46 DefaultPriorityAdvisorAnalysis(bool NotAsRequested) 47 : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default), 48 NotAsRequested(NotAsRequested) {} 49 50 // support for isa<> and dyn_cast. 51 static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { 52 return R->getAdvisorMode() == AdvisorMode::Default; 53 } 54 55 private: 56 void getAnalysisUsage(AnalysisUsage &AU) const override { 57 AU.addRequired<SlotIndexesWrapperPass>(); 58 RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); 59 } 60 std::unique_ptr<RegAllocPriorityAdvisor> 61 getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { 62 return std::make_unique<DefaultPriorityAdvisor>( 63 MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI()); 64 } 65 bool doInitialization(Module &M) override { 66 if (NotAsRequested) 67 M.getContext().emitError("Requested regalloc priority advisor analysis " 68 "could be created. Using default"); 69 return RegAllocPriorityAdvisorAnalysis::doInitialization(M); 70 } 71 const bool NotAsRequested; 72 }; 73 74 class DummyPriorityAdvisorAnalysis final 75 : public RegAllocPriorityAdvisorAnalysis { 76 public: 77 DummyPriorityAdvisorAnalysis() 78 : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Dummy) {} 79 80 // support for isa<> and dyn_cast. 81 static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { 82 return R->getAdvisorMode() == AdvisorMode::Dummy; 83 } 84 85 private: 86 void getAnalysisUsage(AnalysisUsage &AU) const override { 87 AU.addRequired<SlotIndexesWrapperPass>(); 88 RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); 89 } 90 91 std::unique_ptr<RegAllocPriorityAdvisor> 92 getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { 93 return std::make_unique<DummyPriorityAdvisor>( 94 MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI()); 95 } 96 }; 97 98 } // namespace 99 100 template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() { 101 Pass *Ret = nullptr; 102 switch (Mode) { 103 case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default: 104 Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false); 105 break; 106 case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy: 107 Ret = new DummyPriorityAdvisorAnalysis(); 108 break; 109 case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development: 110 #if defined(LLVM_HAVE_TFLITE) 111 Ret = createDevelopmentModePriorityAdvisor(); 112 #endif 113 break; 114 case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release: 115 Ret = createReleaseModePriorityAdvisor(); 116 break; 117 } 118 if (Ret) 119 return Ret; 120 return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true); 121 } 122 123 StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const { 124 switch (getAdvisorMode()) { 125 case AdvisorMode::Default: 126 return "Default Regalloc Priority Advisor"; 127 case AdvisorMode::Release: 128 return "Release mode Regalloc Priority Advisor"; 129 case AdvisorMode::Development: 130 return "Development mode Regalloc Priority Advisor"; 131 case AdvisorMode::Dummy: 132 return "Dummy Regalloc Priority Advisor"; 133 } 134 llvm_unreachable("Unknown advisor kind"); 135 } 136 137 RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF, 138 const RAGreedy &RA, 139 SlotIndexes *const Indexes) 140 : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()), 141 MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()), 142 RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes), 143 RegClassPriorityTrumpsGlobalness( 144 RA.getRegClassPriorityTrumpsGlobalness()), 145 ReverseLocalAssignment(RA.getReverseLocalAssignment()) {} 146