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