219 lines · cpp
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-exception6//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 21using namespace llvm;22 23static 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 38char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0;39INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority",40 "Regalloc priority policy", false, true)41 42namespace {43 44class DefaultPriorityAdvisorProvider final45 : public RegAllocPriorityAdvisorProvider {46public: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 66class DummyPriorityAdvisorProvider final67 : public RegAllocPriorityAdvisorProvider {68public: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 83class DefaultPriorityAdvisorAnalysisLegacy final84 : public RegAllocPriorityAdvisorAnalysisLegacy {85public: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 95private: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 110class DummyPriorityAdvisorAnalysis final111 : public RegAllocPriorityAdvisorAnalysisLegacy {112public: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 122private: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} // namespace135 136void 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#else151 Provider.reset(152 new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx));153#endif154 return;155 case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:156 Provider.reset(createReleaseModePriorityAdvisorProvider());157 return;158 }159}160 161AnalysisKey RegAllocPriorityAdvisorAnalysis::Key;162 163RegAllocPriorityAdvisorAnalysis::Result164RegAllocPriorityAdvisorAnalysis::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 172template <>173Pass *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#endif183 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 196StringRef 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 210RegAllocPriorityAdvisor::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