//===- RegAllocPriorityAdvisor.cpp - live ranges priority advisor ---------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Implementation of the default priority advisor and of the Analysis pass. // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/RegAllocPriorityAdvisor.h" #include "RegAllocGreedy.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/VirtRegMap.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" using namespace llvm; static cl::opt Mode( "regalloc-enable-priority-advisor", cl::Hidden, cl::init(RegAllocPriorityAdvisorProvider::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values( clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Development, "development", "for training"), clEnumValN( RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy, "dummy", "prioritize low virtual register numbers for test and debug"))); char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0; INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority", "Regalloc priority policy", false, true) namespace { class DefaultPriorityAdvisorProvider final : public RegAllocPriorityAdvisorProvider { public: DefaultPriorityAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx) : RegAllocPriorityAdvisorProvider(AdvisorMode::Default) { if (NotAsRequested) Ctx.emitError("Requested regalloc priority advisor analysis " "could be created. Using default"); } // support for isa<> and dyn_cast. static bool classof(const RegAllocPriorityAdvisorProvider *R) { return R->getAdvisorMode() == AdvisorMode::Default; } std::unique_ptr getAdvisor(const MachineFunction &MF, const RAGreedy &RA, SlotIndexes &SI) override { return std::make_unique(MF, RA, &SI); } }; class DummyPriorityAdvisorProvider final : public RegAllocPriorityAdvisorProvider { public: DummyPriorityAdvisorProvider() : RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {} static bool classof(const RegAllocPriorityAdvisorProvider *R) { return R->getAdvisorMode() == AdvisorMode::Dummy; } std::unique_ptr getAdvisor(const MachineFunction &MF, const RAGreedy &RA, SlotIndexes &SI) override { return std::make_unique(MF, RA, &SI); } }; class DefaultPriorityAdvisorAnalysisLegacy final : public RegAllocPriorityAdvisorAnalysisLegacy { public: DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested) : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default), NotAsRequested(NotAsRequested) {} // support for isa<> and dyn_cast. static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) { return R->getAdvisorMode() == AdvisorMode::Default; } private: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); } bool doInitialization(Module &M) override { Provider.reset( new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext())); return false; } const bool NotAsRequested; }; class DummyPriorityAdvisorAnalysis final : public RegAllocPriorityAdvisorAnalysisLegacy { public: using RegAllocPriorityAdvisorAnalysisLegacy::AdvisorMode; DummyPriorityAdvisorAnalysis() : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {} // support for isa<> and dyn_cast. static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) { return R->getAdvisorMode() == AdvisorMode::Dummy; } private: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); } bool doInitialization(Module &M) override { Provider.reset(new DummyPriorityAdvisorProvider()); return false; } }; } // namespace void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) { if (Provider) return; switch (Mode) { case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: Provider.reset(new DummyPriorityAdvisorProvider()); return; case RegAllocPriorityAdvisorProvider::AdvisorMode::Default: Provider.reset( new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/false, Ctx)); return; case RegAllocPriorityAdvisorProvider::AdvisorMode::Development: #if defined(LLVM_HAVE_TFLITE) Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx)); #else Provider.reset( new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx)); #endif return; case RegAllocPriorityAdvisorProvider::AdvisorMode::Release: Provider.reset(createReleaseModePriorityAdvisorProvider()); return; } } AnalysisKey RegAllocPriorityAdvisorAnalysis::Key; RegAllocPriorityAdvisorAnalysis::Result RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { // Lazily initialize the provider. initializeProvider(MF.getFunction().getContext()); // The requiring analysis will construct the advisor. return Result{Provider.get()}; } template <> Pass *llvm::callDefaultCtor() { Pass *Ret = nullptr; switch (Mode) { case RegAllocPriorityAdvisorProvider::AdvisorMode::Default: Ret = new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ false); break; case RegAllocPriorityAdvisorProvider::AdvisorMode::Development: #if defined(LLVM_HAVE_TFLITE) Ret = createDevelopmentModePriorityAdvisorAnalysis(); #endif break; case RegAllocPriorityAdvisorProvider::AdvisorMode::Release: Ret = createReleaseModePriorityAdvisorAnalysis(); break; case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: Ret = new DummyPriorityAdvisorAnalysis(); break; } if (Ret) return Ret; return new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ true); } StringRef RegAllocPriorityAdvisorAnalysisLegacy::getPassName() const { switch (getAdvisorMode()) { case AdvisorMode::Default: return "Default Regalloc Priority Advisor"; case AdvisorMode::Release: return "Release mode Regalloc Priority Advisor"; case AdvisorMode::Development: return "Development mode Regalloc Priority Advisor"; case AdvisorMode::Dummy: return "Dummy Regalloc Priority Advisor"; } llvm_unreachable("Unknown advisor kind"); } RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, SlotIndexes *const Indexes) : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()), MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes), RegClassPriorityTrumpsGlobalness( RA.getRegClassPriorityTrumpsGlobalness()), ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}