xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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:
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.
55   static bool classof(const RegAllocPriorityAdvisorProvider *R) {
56     return R->getAdvisorMode() == AdvisorMode::Default;
57   }
58 
59   std::unique_ptr<RegAllocPriorityAdvisor>
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:
69   DummyPriorityAdvisorProvider()
70       : RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {}
71 
72   static bool classof(const RegAllocPriorityAdvisorProvider *R) {
73     return R->getAdvisorMode() == AdvisorMode::Dummy;
74   }
75 
76   std::unique_ptr<RegAllocPriorityAdvisor>
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:
86   DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested)
87       : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default),
88         NotAsRequested(NotAsRequested) {}
89 
90   // support for isa<> and dyn_cast.
91   static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
92     return R->getAdvisorMode() == AdvisorMode::Default;
93   }
94 
95 private:
96   void getAnalysisUsage(AnalysisUsage &AU) const override {
97     AU.addRequired<SlotIndexesWrapperPass>();
98     RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
99   }
100 
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;
114   DummyPriorityAdvisorAnalysis()
115       : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {}
116 
117   // support for isa<> and dyn_cast.
118   static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
119     return R->getAdvisorMode() == AdvisorMode::Dummy;
120   }
121 
122 private:
123   void getAnalysisUsage(AnalysisUsage &AU) const override {
124     AU.addRequired<SlotIndexesWrapperPass>();
125     RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
126   }
127 
128   bool doInitialization(Module &M) override {
129     Provider.reset(new DummyPriorityAdvisorProvider());
130     return false;
131   }
132 };
133 
134 } // namespace
135 
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
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 <>
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 
196 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 
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