1*0eae32dcSDimitry Andric //===- RegAllocEvictionAdvisor.cpp - eviction advisor ---------------------===// 2*0eae32dcSDimitry Andric // 3*0eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0eae32dcSDimitry Andric // 7*0eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 8*0eae32dcSDimitry Andric // 9*0eae32dcSDimitry Andric // Implementation of the default eviction advisor and of the Analysis pass. 10*0eae32dcSDimitry Andric // 11*0eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 12*0eae32dcSDimitry Andric 13*0eae32dcSDimitry Andric #include "RegAllocEvictionAdvisor.h" 14*0eae32dcSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 15*0eae32dcSDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h" 16*0eae32dcSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h" 17*0eae32dcSDimitry Andric #include "llvm/InitializePasses.h" 18*0eae32dcSDimitry Andric #include "llvm/Pass.h" 19*0eae32dcSDimitry Andric #include "llvm/PassRegistry.h" 20*0eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 21*0eae32dcSDimitry Andric #include "llvm/Support/ErrorHandling.h" 22*0eae32dcSDimitry Andric #include "llvm/Target/TargetMachine.h" 23*0eae32dcSDimitry Andric 24*0eae32dcSDimitry Andric using namespace llvm; 25*0eae32dcSDimitry Andric 26*0eae32dcSDimitry Andric static cl::opt<RegAllocEvictionAdvisorAnalysis::AdvisorMode> Mode( 27*0eae32dcSDimitry Andric "regalloc-enable-advisor", cl::Hidden, 28*0eae32dcSDimitry Andric cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), 29*0eae32dcSDimitry Andric cl::desc("Enable regalloc advisor mode"), 30*0eae32dcSDimitry Andric cl::values( 31*0eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, 32*0eae32dcSDimitry Andric "default", "Default"), 33*0eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, 34*0eae32dcSDimitry Andric "release", "precompiled"), 35*0eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, 36*0eae32dcSDimitry Andric "development", "for training"))); 37*0eae32dcSDimitry Andric 38*0eae32dcSDimitry Andric static cl::opt<bool> EnableLocalReassignment( 39*0eae32dcSDimitry Andric "enable-local-reassign", cl::Hidden, 40*0eae32dcSDimitry Andric cl::desc("Local reassignment can yield better allocation decisions, but " 41*0eae32dcSDimitry Andric "may be compile time intensive"), 42*0eae32dcSDimitry Andric cl::init(false)); 43*0eae32dcSDimitry Andric 44*0eae32dcSDimitry Andric #define DEBUG_TYPE "regalloc" 45*0eae32dcSDimitry Andric 46*0eae32dcSDimitry Andric char RegAllocEvictionAdvisorAnalysis::ID = 0; 47*0eae32dcSDimitry Andric INITIALIZE_PASS(RegAllocEvictionAdvisorAnalysis, "regalloc-evict", 48*0eae32dcSDimitry Andric "Regalloc eviction policy", false, true) 49*0eae32dcSDimitry Andric 50*0eae32dcSDimitry Andric namespace { 51*0eae32dcSDimitry Andric class DefaultEvictionAdvisorAnalysis final 52*0eae32dcSDimitry Andric : public RegAllocEvictionAdvisorAnalysis { 53*0eae32dcSDimitry Andric public: 54*0eae32dcSDimitry Andric DefaultEvictionAdvisorAnalysis(bool NotAsRequested) 55*0eae32dcSDimitry Andric : RegAllocEvictionAdvisorAnalysis(AdvisorMode::Default), 56*0eae32dcSDimitry Andric NotAsRequested(NotAsRequested) {} 57*0eae32dcSDimitry Andric 58*0eae32dcSDimitry Andric // support for isa<> and dyn_cast. 59*0eae32dcSDimitry Andric static bool classof(const RegAllocEvictionAdvisorAnalysis *R) { 60*0eae32dcSDimitry Andric return R->getAdvisorMode() == AdvisorMode::Default; 61*0eae32dcSDimitry Andric } 62*0eae32dcSDimitry Andric 63*0eae32dcSDimitry Andric private: 64*0eae32dcSDimitry Andric std::unique_ptr<RegAllocEvictionAdvisor> 65*0eae32dcSDimitry Andric getAdvisor(const MachineFunction &MF, LiveRegMatrix *Matrix, 66*0eae32dcSDimitry Andric LiveIntervals *LIS, VirtRegMap *VRM, 67*0eae32dcSDimitry Andric const RegisterClassInfo &RegClassInfo, 68*0eae32dcSDimitry Andric ExtraRegInfo *ExtraInfo) override { 69*0eae32dcSDimitry Andric return std::make_unique<DefaultEvictionAdvisor>(MF, Matrix, LIS, VRM, 70*0eae32dcSDimitry Andric RegClassInfo, ExtraInfo); 71*0eae32dcSDimitry Andric } 72*0eae32dcSDimitry Andric bool doInitialization(Module &M) override { 73*0eae32dcSDimitry Andric if (NotAsRequested) 74*0eae32dcSDimitry Andric M.getContext().emitError("Requested regalloc eviction advisor analysis " 75*0eae32dcSDimitry Andric "could be created. Using default"); 76*0eae32dcSDimitry Andric return RegAllocEvictionAdvisorAnalysis::doInitialization(M); 77*0eae32dcSDimitry Andric } 78*0eae32dcSDimitry Andric const bool NotAsRequested; 79*0eae32dcSDimitry Andric }; 80*0eae32dcSDimitry Andric } // namespace 81*0eae32dcSDimitry Andric 82*0eae32dcSDimitry Andric template <> Pass *llvm::callDefaultCtor<RegAllocEvictionAdvisorAnalysis>() { 83*0eae32dcSDimitry Andric Pass *Ret = nullptr; 84*0eae32dcSDimitry Andric switch (Mode) { 85*0eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default: 86*0eae32dcSDimitry Andric Ret = new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ false); 87*0eae32dcSDimitry Andric break; 88*0eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development: 89*0eae32dcSDimitry Andric // TODO(mtrofin): add implementation 90*0eae32dcSDimitry Andric break; 91*0eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release: 92*0eae32dcSDimitry Andric // TODO(mtrofin): add implementation 93*0eae32dcSDimitry Andric break; 94*0eae32dcSDimitry Andric } 95*0eae32dcSDimitry Andric if (Ret) 96*0eae32dcSDimitry Andric return Ret; 97*0eae32dcSDimitry Andric return new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ true); 98*0eae32dcSDimitry Andric } 99*0eae32dcSDimitry Andric 100*0eae32dcSDimitry Andric StringRef RegAllocEvictionAdvisorAnalysis::getPassName() const { 101*0eae32dcSDimitry Andric switch (getAdvisorMode()) { 102*0eae32dcSDimitry Andric case AdvisorMode::Default: 103*0eae32dcSDimitry Andric return "Default Regalloc Eviction Advisor"; 104*0eae32dcSDimitry Andric case AdvisorMode::Release: 105*0eae32dcSDimitry Andric return "Release mode Regalloc Eviction Advisor"; 106*0eae32dcSDimitry Andric case AdvisorMode::Development: 107*0eae32dcSDimitry Andric return "Development mode Regalloc Eviction Advisor"; 108*0eae32dcSDimitry Andric } 109*0eae32dcSDimitry Andric llvm_unreachable("Unknown advisor kind"); 110*0eae32dcSDimitry Andric } 111*0eae32dcSDimitry Andric 112*0eae32dcSDimitry Andric RegAllocEvictionAdvisor::RegAllocEvictionAdvisor( 113*0eae32dcSDimitry Andric const MachineFunction &MF, LiveRegMatrix *Matrix, LiveIntervals *LIS, 114*0eae32dcSDimitry Andric VirtRegMap *VRM, const RegisterClassInfo &RegClassInfo, 115*0eae32dcSDimitry Andric ExtraRegInfo *ExtraInfo) 116*0eae32dcSDimitry Andric : MF(MF), Matrix(Matrix), LIS(LIS), VRM(VRM), MRI(&VRM->getRegInfo()), 117*0eae32dcSDimitry Andric TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RegClassInfo), 118*0eae32dcSDimitry Andric RegCosts(TRI->getRegisterCosts(MF)), ExtraInfo(ExtraInfo), 119*0eae32dcSDimitry Andric EnableLocalReassign(EnableLocalReassignment || 120*0eae32dcSDimitry Andric MF.getSubtarget().enableRALocalReassignment( 121*0eae32dcSDimitry Andric MF.getTarget().getOptLevel())) {} 122