9
9
#ifndef LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
10
10
#define LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
11
11
12
+ #include " llvm/ADT/Any.h"
12
13
#include " llvm/ADT/ArrayRef.h"
13
14
#include " llvm/ADT/SmallSet.h"
14
15
#include " llvm/ADT/StringRef.h"
16
+ #include " llvm/CodeGen/MachineBlockFrequencyInfo.h"
17
+ #include " llvm/CodeGen/MachineLoopInfo.h"
15
18
#include " llvm/CodeGen/Register.h"
16
19
#include " llvm/Config/llvm-config.h"
20
+ #include " llvm/IR/PassManager.h"
17
21
#include " llvm/MC/MCRegister.h"
18
22
#include " llvm/Pass.h"
23
+ #include " llvm/Support/Compiler.h"
19
24
20
25
namespace llvm {
21
26
class AllocationOrder ;
@@ -149,6 +154,35 @@ class RegAllocEvictionAdvisor {
149
154
const bool EnableLocalReassign;
150
155
};
151
156
157
+ // / Common provider for legacy and new pass managers.
158
+ // / This keeps the state for logging, and sets up and holds the provider.
159
+ // / The legacy pass itself used to keep the logging state and provider,
160
+ // / so this extraction helps the NPM analysis to reuse the logic.
161
+ // / TODO: Coalesce this with the NPM analysis when legacy PM is removed.
162
+ class RegAllocEvictionAdvisorProvider {
163
+ public:
164
+ enum class AdvisorMode : int { Default, Release, Development };
165
+ RegAllocEvictionAdvisorProvider (AdvisorMode Mode, LLVMContext &Ctx)
166
+ : Ctx(Ctx), Mode(Mode) {}
167
+
168
+ virtual ~RegAllocEvictionAdvisorProvider () = default ;
169
+
170
+ virtual void logRewardIfNeeded (const MachineFunction &MF,
171
+ llvm::function_ref<float ()> GetReward) {}
172
+
173
+ virtual std::unique_ptr<RegAllocEvictionAdvisor>
174
+ getAdvisor (const MachineFunction &MF, const RAGreedy &RA,
175
+ MachineBlockFrequencyInfo *MBFI, MachineLoopInfo *Loops) = 0 ;
176
+
177
+ AdvisorMode getAdvisorMode () const { return Mode; }
178
+
179
+ protected:
180
+ LLVMContext &Ctx;
181
+
182
+ private:
183
+ const AdvisorMode Mode;
184
+ };
185
+
152
186
// / ImmutableAnalysis abstraction for fetching the Eviction Advisor. We model it
153
187
// / as an analysis to decouple the user from the implementation insofar as
154
188
// / dependencies on other analyses goes. The motivation for it being an
@@ -164,40 +198,86 @@ class RegAllocEvictionAdvisor {
164
198
// /
165
199
// / Because we need to offer additional services in 'development' mode, the
166
200
// / implementations of this analysis need to implement RTTI support.
167
- class RegAllocEvictionAdvisorAnalysis : public ImmutablePass {
201
+ class RegAllocEvictionAdvisorAnalysisLegacy : public ImmutablePass {
168
202
public:
169
203
enum class AdvisorMode : int { Default, Release, Development };
170
204
171
- RegAllocEvictionAdvisorAnalysis (AdvisorMode Mode)
172
- : ImmutablePass(ID), Mode(Mode){};
205
+ RegAllocEvictionAdvisorAnalysisLegacy (AdvisorMode Mode)
206
+ : ImmutablePass(ID), Mode(Mode) {};
173
207
static char ID;
174
208
175
209
// / Get an advisor for the given context (i.e. machine function, etc)
176
- virtual std::unique_ptr<RegAllocEvictionAdvisor>
177
- getAdvisor ( const MachineFunction &MF, const RAGreedy &RA) = 0 ;
210
+ RegAllocEvictionAdvisorProvider & getProvider () { return *Provider; }
211
+
178
212
AdvisorMode getAdvisorMode () const { return Mode; }
179
213
virtual void logRewardIfNeeded (const MachineFunction &MF,
180
- llvm:: function_ref<float ()> GetReward){};
214
+ function_ref<float ()> GetReward) {};
181
215
182
216
protected:
183
217
// This analysis preserves everything, and subclasses may have additional
184
218
// requirements.
185
219
void getAnalysisUsage (AnalysisUsage &AU) const override {
186
220
AU.setPreservesAll ();
187
221
}
222
+ std::unique_ptr<RegAllocEvictionAdvisorProvider> Provider;
188
223
189
224
private:
190
225
StringRef getPassName () const override ;
191
226
const AdvisorMode Mode;
192
227
};
193
228
229
+ // / A MachineFunction analysis for fetching the Eviction Advisor.
230
+ // / This sets up the Provider lazily and caches it.
231
+ // / - in the ML implementation case, the evaluator is stateless but (especially
232
+ // / in the development mode) expensive to set up. With a Module Analysis, we
233
+ // / `require` it and set it up once.
234
+ // / - in the 'development' mode ML case, we want to capture the training log
235
+ // / during allocation (this is a log of features encountered and decisions
236
+ // / made), and then measure a score, potentially a few steps after allocation
237
+ // / completes. So we need a Module analysis to keep the logger state around
238
+ // / until we can make that measurement.
239
+ class RegAllocEvictionAdvisorAnalysis
240
+ : public AnalysisInfoMixin<RegAllocEvictionAdvisorAnalysis> {
241
+ static AnalysisKey Key;
242
+ friend AnalysisInfoMixin<RegAllocEvictionAdvisorAnalysis>;
243
+
244
+ public:
245
+ struct Result {
246
+ // owned by this analysis
247
+ RegAllocEvictionAdvisorProvider *Provider;
248
+
249
+ bool invalidate (MachineFunction &MF, const PreservedAnalyses &PA,
250
+ MachineFunctionAnalysisManager::Invalidator &Inv) {
251
+ // Provider is stateless and constructed only once. Do not get
252
+ // invalidated.
253
+ return false ;
254
+ }
255
+ };
256
+
257
+ Result run (MachineFunction &MF, MachineFunctionAnalysisManager &MAM);
258
+
259
+ private:
260
+ void
261
+ initializeProvider (RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode Mode,
262
+ LLVMContext &Ctx);
263
+
264
+ std::unique_ptr<RegAllocEvictionAdvisorProvider> Provider;
265
+ };
266
+
194
267
// / Specialization for the API used by the analysis infrastructure to create
195
268
// / an instance of the eviction advisor.
196
- template <> Pass *callDefaultCtor<RegAllocEvictionAdvisorAnalysis>();
269
+ template <> Pass *callDefaultCtor<RegAllocEvictionAdvisorAnalysisLegacy>();
270
+
271
+ RegAllocEvictionAdvisorAnalysisLegacy *createReleaseModeAdvisorAnalysisLegacy ();
272
+
273
+ RegAllocEvictionAdvisorAnalysisLegacy *
274
+ createDevelopmentModeAdvisorAnalysisLegacy ();
197
275
198
- RegAllocEvictionAdvisorAnalysis *createReleaseModeAdvisor ();
276
+ LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider *
277
+ createReleaseModeAdvisorProvider (LLVMContext &Ctx);
199
278
200
- RegAllocEvictionAdvisorAnalysis *createDevelopmentModeAdvisor ();
279
+ RegAllocEvictionAdvisorProvider *
280
+ createDevelopmentModeAdvisorProvider (LLVMContext &Ctx);
201
281
202
282
// TODO: move to RegAllocEvictionAdvisor.cpp when we move implementation
203
283
// out of RegAllocGreedy.cpp
0 commit comments