10eae32dcSDimitry Andric //===- RegAllocEvictionAdvisor.cpp - eviction advisor ---------------------===// 20eae32dcSDimitry Andric // 30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60eae32dcSDimitry Andric // 70eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 80eae32dcSDimitry Andric // 90eae32dcSDimitry Andric // Implementation of the default eviction advisor and of the Analysis pass. 100eae32dcSDimitry Andric // 110eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 120eae32dcSDimitry Andric 130eae32dcSDimitry Andric #include "RegAllocEvictionAdvisor.h" 14*04eeddc0SDimitry Andric #include "RegAllocGreedy.h" 150eae32dcSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 160eae32dcSDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h" 170eae32dcSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h" 180eae32dcSDimitry Andric #include "llvm/InitializePasses.h" 190eae32dcSDimitry Andric #include "llvm/Pass.h" 200eae32dcSDimitry Andric #include "llvm/PassRegistry.h" 210eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 220eae32dcSDimitry Andric #include "llvm/Support/ErrorHandling.h" 230eae32dcSDimitry Andric #include "llvm/Target/TargetMachine.h" 240eae32dcSDimitry Andric 250eae32dcSDimitry Andric using namespace llvm; 260eae32dcSDimitry Andric 270eae32dcSDimitry Andric static cl::opt<RegAllocEvictionAdvisorAnalysis::AdvisorMode> Mode( 280eae32dcSDimitry Andric "regalloc-enable-advisor", cl::Hidden, 290eae32dcSDimitry Andric cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), 300eae32dcSDimitry Andric cl::desc("Enable regalloc advisor mode"), 310eae32dcSDimitry Andric cl::values( 320eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, 330eae32dcSDimitry Andric "default", "Default"), 340eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, 350eae32dcSDimitry Andric "release", "precompiled"), 360eae32dcSDimitry Andric clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, 370eae32dcSDimitry Andric "development", "for training"))); 380eae32dcSDimitry Andric 390eae32dcSDimitry Andric static cl::opt<bool> EnableLocalReassignment( 400eae32dcSDimitry Andric "enable-local-reassign", cl::Hidden, 410eae32dcSDimitry Andric cl::desc("Local reassignment can yield better allocation decisions, but " 420eae32dcSDimitry Andric "may be compile time intensive"), 430eae32dcSDimitry Andric cl::init(false)); 440eae32dcSDimitry Andric 450eae32dcSDimitry Andric #define DEBUG_TYPE "regalloc" 46*04eeddc0SDimitry Andric #ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL 47*04eeddc0SDimitry Andric #define LLVM_HAVE_TF_AOT 48*04eeddc0SDimitry Andric #endif 490eae32dcSDimitry Andric 500eae32dcSDimitry Andric char RegAllocEvictionAdvisorAnalysis::ID = 0; 510eae32dcSDimitry Andric INITIALIZE_PASS(RegAllocEvictionAdvisorAnalysis, "regalloc-evict", 520eae32dcSDimitry Andric "Regalloc eviction policy", false, true) 530eae32dcSDimitry Andric 540eae32dcSDimitry Andric namespace { 550eae32dcSDimitry Andric class DefaultEvictionAdvisorAnalysis final 560eae32dcSDimitry Andric : public RegAllocEvictionAdvisorAnalysis { 570eae32dcSDimitry Andric public: 580eae32dcSDimitry Andric DefaultEvictionAdvisorAnalysis(bool NotAsRequested) 590eae32dcSDimitry Andric : RegAllocEvictionAdvisorAnalysis(AdvisorMode::Default), 600eae32dcSDimitry Andric NotAsRequested(NotAsRequested) {} 610eae32dcSDimitry Andric 620eae32dcSDimitry Andric // support for isa<> and dyn_cast. 630eae32dcSDimitry Andric static bool classof(const RegAllocEvictionAdvisorAnalysis *R) { 640eae32dcSDimitry Andric return R->getAdvisorMode() == AdvisorMode::Default; 650eae32dcSDimitry Andric } 660eae32dcSDimitry Andric 670eae32dcSDimitry Andric private: 680eae32dcSDimitry Andric std::unique_ptr<RegAllocEvictionAdvisor> 69*04eeddc0SDimitry Andric getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { 70*04eeddc0SDimitry Andric return std::make_unique<DefaultEvictionAdvisor>(MF, RA); 710eae32dcSDimitry Andric } 720eae32dcSDimitry Andric bool doInitialization(Module &M) override { 730eae32dcSDimitry Andric if (NotAsRequested) 740eae32dcSDimitry Andric M.getContext().emitError("Requested regalloc eviction advisor analysis " 750eae32dcSDimitry Andric "could be created. Using default"); 760eae32dcSDimitry Andric return RegAllocEvictionAdvisorAnalysis::doInitialization(M); 770eae32dcSDimitry Andric } 780eae32dcSDimitry Andric const bool NotAsRequested; 790eae32dcSDimitry Andric }; 800eae32dcSDimitry Andric } // namespace 810eae32dcSDimitry Andric 820eae32dcSDimitry Andric template <> Pass *llvm::callDefaultCtor<RegAllocEvictionAdvisorAnalysis>() { 830eae32dcSDimitry Andric Pass *Ret = nullptr; 840eae32dcSDimitry Andric switch (Mode) { 850eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default: 860eae32dcSDimitry Andric Ret = new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ false); 870eae32dcSDimitry Andric break; 880eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development: 89*04eeddc0SDimitry Andric #if defined(LLVM_HAVE_TF_API) 90*04eeddc0SDimitry Andric Ret = createDevelopmentModeAdvisor(); 91*04eeddc0SDimitry Andric #endif 920eae32dcSDimitry Andric break; 930eae32dcSDimitry Andric case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release: 94*04eeddc0SDimitry Andric #if defined(LLVM_HAVE_TF_AOT) 95*04eeddc0SDimitry Andric Ret = createReleaseModeAdvisor(); 96*04eeddc0SDimitry Andric #endif 970eae32dcSDimitry Andric break; 980eae32dcSDimitry Andric } 990eae32dcSDimitry Andric if (Ret) 1000eae32dcSDimitry Andric return Ret; 1010eae32dcSDimitry Andric return new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ true); 1020eae32dcSDimitry Andric } 1030eae32dcSDimitry Andric 1040eae32dcSDimitry Andric StringRef RegAllocEvictionAdvisorAnalysis::getPassName() const { 1050eae32dcSDimitry Andric switch (getAdvisorMode()) { 1060eae32dcSDimitry Andric case AdvisorMode::Default: 1070eae32dcSDimitry Andric return "Default Regalloc Eviction Advisor"; 1080eae32dcSDimitry Andric case AdvisorMode::Release: 1090eae32dcSDimitry Andric return "Release mode Regalloc Eviction Advisor"; 1100eae32dcSDimitry Andric case AdvisorMode::Development: 1110eae32dcSDimitry Andric return "Development mode Regalloc Eviction Advisor"; 1120eae32dcSDimitry Andric } 1130eae32dcSDimitry Andric llvm_unreachable("Unknown advisor kind"); 1140eae32dcSDimitry Andric } 1150eae32dcSDimitry Andric 116*04eeddc0SDimitry Andric RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction &MF, 117*04eeddc0SDimitry Andric const RAGreedy &RA) 118*04eeddc0SDimitry Andric : MF(MF), RA(RA), Matrix(RA.getInterferenceMatrix()), 119*04eeddc0SDimitry Andric LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()), 120*04eeddc0SDimitry Andric MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()), 121*04eeddc0SDimitry Andric RegClassInfo(RA.getRegClassInfo()), RegCosts(TRI->getRegisterCosts(MF)), 1220eae32dcSDimitry Andric EnableLocalReassign(EnableLocalReassignment || 1230eae32dcSDimitry Andric MF.getSubtarget().enableRALocalReassignment( 1240eae32dcSDimitry Andric MF.getTarget().getOptLevel())) {} 125