1 //===- RegAllocPriorityAdvisor.cpp - live ranges priority 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 priority advisor and of the Analysis pass.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
14 #include "RegAllocGreedy.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/VirtRegMap.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/Pass.h"
20
21 using namespace llvm;
22
23 static cl::opt<RegAllocPriorityAdvisorProvider::AdvisorMode> Mode(
24 "regalloc-enable-priority-advisor", cl::Hidden,
25 cl::init(RegAllocPriorityAdvisorProvider::AdvisorMode::Default),
26 cl::desc("Enable regalloc advisor mode"),
27 cl::values(
28 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Default,
29 "default", "Default"),
30 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Release,
31 "release", "precompiled"),
32 clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Development,
33 "development", "for training"),
34 clEnumValN(
35 RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy, "dummy",
36 "prioritize low virtual register numbers for test and debug")));
37
38 char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0;
39 INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority",
40 "Regalloc priority policy", false, true)
41
42 namespace {
43
44 class DefaultPriorityAdvisorProvider final
45 : public RegAllocPriorityAdvisorProvider {
46 public:
DefaultPriorityAdvisorProvider(bool NotAsRequested,LLVMContext & Ctx)47 DefaultPriorityAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx)
48 : RegAllocPriorityAdvisorProvider(AdvisorMode::Default) {
49 if (NotAsRequested)
50 Ctx.emitError("Requested regalloc priority advisor analysis "
51 "could be created. Using default");
52 }
53
54 // support for isa<> and dyn_cast.
classof(const RegAllocPriorityAdvisorProvider * R)55 static bool classof(const RegAllocPriorityAdvisorProvider *R) {
56 return R->getAdvisorMode() == AdvisorMode::Default;
57 }
58
59 std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes & SI)60 getAdvisor(const MachineFunction &MF, const RAGreedy &RA,
61 SlotIndexes &SI) override {
62 return std::make_unique<DefaultPriorityAdvisor>(MF, RA, &SI);
63 }
64 };
65
66 class DummyPriorityAdvisorProvider final
67 : public RegAllocPriorityAdvisorProvider {
68 public:
DummyPriorityAdvisorProvider()69 DummyPriorityAdvisorProvider()
70 : RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {}
71
classof(const RegAllocPriorityAdvisorProvider * R)72 static bool classof(const RegAllocPriorityAdvisorProvider *R) {
73 return R->getAdvisorMode() == AdvisorMode::Dummy;
74 }
75
76 std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes & SI)77 getAdvisor(const MachineFunction &MF, const RAGreedy &RA,
78 SlotIndexes &SI) override {
79 return std::make_unique<DummyPriorityAdvisor>(MF, RA, &SI);
80 }
81 };
82
83 class DefaultPriorityAdvisorAnalysisLegacy final
84 : public RegAllocPriorityAdvisorAnalysisLegacy {
85 public:
DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested)86 DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested)
87 : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default),
88 NotAsRequested(NotAsRequested) {}
89
90 // support for isa<> and dyn_cast.
classof(const RegAllocPriorityAdvisorAnalysisLegacy * R)91 static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
92 return R->getAdvisorMode() == AdvisorMode::Default;
93 }
94
95 private:
getAnalysisUsage(AnalysisUsage & AU) const96 void getAnalysisUsage(AnalysisUsage &AU) const override {
97 AU.addRequired<SlotIndexesWrapperPass>();
98 RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
99 }
100
doInitialization(Module & M)101 bool doInitialization(Module &M) override {
102 Provider.reset(
103 new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext()));
104 return false;
105 }
106
107 const bool NotAsRequested;
108 };
109
110 class DummyPriorityAdvisorAnalysis final
111 : public RegAllocPriorityAdvisorAnalysisLegacy {
112 public:
113 using RegAllocPriorityAdvisorAnalysisLegacy::AdvisorMode;
DummyPriorityAdvisorAnalysis()114 DummyPriorityAdvisorAnalysis()
115 : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {}
116
117 // support for isa<> and dyn_cast.
classof(const RegAllocPriorityAdvisorAnalysisLegacy * R)118 static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
119 return R->getAdvisorMode() == AdvisorMode::Dummy;
120 }
121
122 private:
getAnalysisUsage(AnalysisUsage & AU) const123 void getAnalysisUsage(AnalysisUsage &AU) const override {
124 AU.addRequired<SlotIndexesWrapperPass>();
125 RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
126 }
127
doInitialization(Module & M)128 bool doInitialization(Module &M) override {
129 Provider.reset(new DummyPriorityAdvisorProvider());
130 return false;
131 }
132 };
133
134 } // namespace
135
initializeProvider(LLVMContext & Ctx)136 void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) {
137 if (Provider)
138 return;
139 switch (Mode) {
140 case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy:
141 Provider.reset(new DummyPriorityAdvisorProvider());
142 return;
143 case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
144 Provider.reset(
145 new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/false, Ctx));
146 return;
147 case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
148 #if defined(LLVM_HAVE_TFLITE)
149 Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx));
150 #else
151 Provider.reset(
152 new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx));
153 #endif
154 return;
155 case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
156 Provider.reset(createReleaseModePriorityAdvisorProvider());
157 return;
158 }
159 }
160
161 AnalysisKey RegAllocPriorityAdvisorAnalysis::Key;
162
163 RegAllocPriorityAdvisorAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)164 RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF,
165 MachineFunctionAnalysisManager &MFAM) {
166 // Lazily initialize the provider.
167 initializeProvider(MF.getFunction().getContext());
168 // The requiring analysis will construct the advisor.
169 return Result{Provider.get()};
170 }
171
172 template <>
callDefaultCtor()173 Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>() {
174 Pass *Ret = nullptr;
175 switch (Mode) {
176 case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
177 Ret = new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ false);
178 break;
179 case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
180 #if defined(LLVM_HAVE_TFLITE)
181 Ret = createDevelopmentModePriorityAdvisorAnalysis();
182 #endif
183 break;
184 case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
185 Ret = createReleaseModePriorityAdvisorAnalysis();
186 break;
187 case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy:
188 Ret = new DummyPriorityAdvisorAnalysis();
189 break;
190 }
191 if (Ret)
192 return Ret;
193 return new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ true);
194 }
195
getPassName() const196 StringRef RegAllocPriorityAdvisorAnalysisLegacy::getPassName() const {
197 switch (getAdvisorMode()) {
198 case AdvisorMode::Default:
199 return "Default Regalloc Priority Advisor";
200 case AdvisorMode::Release:
201 return "Release mode Regalloc Priority Advisor";
202 case AdvisorMode::Development:
203 return "Development mode Regalloc Priority Advisor";
204 case AdvisorMode::Dummy:
205 return "Dummy Regalloc Priority Advisor";
206 }
207 llvm_unreachable("Unknown advisor kind");
208 }
209
RegAllocPriorityAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes * const Indexes)210 RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
211 const RAGreedy &RA,
212 SlotIndexes *const Indexes)
213 : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
214 MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
215 RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes),
216 RegClassPriorityTrumpsGlobalness(
217 RA.getRegClassPriorityTrumpsGlobalness()),
218 ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
219