xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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