Skip to content

Commit 519b53e

Browse files
authored
[CodeGen][NewPM] Port RegAllocEvictionAdvisor analysis to NPM (#117309)
Legacy pass used to provide the advisor, so this extracts that logic into a provider class used by both analysis passes. All three (Default, Release, Development) legacy passes `*AdvisorAnalysis` are basically renamed to `*AdvisorProvider`, so the actual legacy wrapper passes are `*AdvisorAnalysisLegacy`. There is only one NPM analysis `RegAllocEvictionAnalysis` that switches between the three providers in the `::run` method, to be cached by the NPM. Also adds `RequireAnalysis<RegAllocEvictionAnalysis>` to the optimized target reg alloc codegen builder.
1 parent 719c46b commit 519b53e

10 files changed

+330
-129
lines changed

llvm/lib/CodeGen/RegAllocEvictionAdvisor.h renamed to llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
#ifndef LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
1010
#define LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
1111

12+
#include "llvm/ADT/Any.h"
1213
#include "llvm/ADT/ArrayRef.h"
1314
#include "llvm/ADT/SmallSet.h"
1415
#include "llvm/ADT/StringRef.h"
16+
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
17+
#include "llvm/CodeGen/MachineLoopInfo.h"
1518
#include "llvm/CodeGen/Register.h"
1619
#include "llvm/Config/llvm-config.h"
20+
#include "llvm/IR/PassManager.h"
1721
#include "llvm/MC/MCRegister.h"
1822
#include "llvm/Pass.h"
23+
#include "llvm/Support/Compiler.h"
1924

2025
namespace llvm {
2126
class AllocationOrder;
@@ -149,6 +154,35 @@ class RegAllocEvictionAdvisor {
149154
const bool EnableLocalReassign;
150155
};
151156

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+
152186
/// ImmutableAnalysis abstraction for fetching the Eviction Advisor. We model it
153187
/// as an analysis to decouple the user from the implementation insofar as
154188
/// dependencies on other analyses goes. The motivation for it being an
@@ -164,40 +198,86 @@ class RegAllocEvictionAdvisor {
164198
///
165199
/// Because we need to offer additional services in 'development' mode, the
166200
/// implementations of this analysis need to implement RTTI support.
167-
class RegAllocEvictionAdvisorAnalysis : public ImmutablePass {
201+
class RegAllocEvictionAdvisorAnalysisLegacy : public ImmutablePass {
168202
public:
169203
enum class AdvisorMode : int { Default, Release, Development };
170204

171-
RegAllocEvictionAdvisorAnalysis(AdvisorMode Mode)
172-
: ImmutablePass(ID), Mode(Mode){};
205+
RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode Mode)
206+
: ImmutablePass(ID), Mode(Mode) {};
173207
static char ID;
174208

175209
/// 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+
178212
AdvisorMode getAdvisorMode() const { return Mode; }
179213
virtual void logRewardIfNeeded(const MachineFunction &MF,
180-
llvm::function_ref<float()> GetReward){};
214+
function_ref<float()> GetReward) {};
181215

182216
protected:
183217
// This analysis preserves everything, and subclasses may have additional
184218
// requirements.
185219
void getAnalysisUsage(AnalysisUsage &AU) const override {
186220
AU.setPreservesAll();
187221
}
222+
std::unique_ptr<RegAllocEvictionAdvisorProvider> Provider;
188223

189224
private:
190225
StringRef getPassName() const override;
191226
const AdvisorMode Mode;
192227
};
193228

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+
194267
/// Specialization for the API used by the analysis infrastructure to create
195268
/// 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();
197275

198-
RegAllocEvictionAdvisorAnalysis *createReleaseModeAdvisor();
276+
LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider *
277+
createReleaseModeAdvisorProvider(LLVMContext &Ctx);
199278

200-
RegAllocEvictionAdvisorAnalysis *createDevelopmentModeAdvisor();
279+
RegAllocEvictionAdvisorProvider *
280+
createDevelopmentModeAdvisorProvider(LLVMContext &Ctx);
201281

202282
// TODO: move to RegAllocEvictionAdvisor.cpp when we move implementation
203283
// out of RegAllocGreedy.cpp

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void initializePseudoProbeInserterPass(PassRegistry &);
251251
void initializeRAGreedyPass(PassRegistry &);
252252
void initializeReachingDefAnalysisPass(PassRegistry &);
253253
void initializeReassociateLegacyPassPass(PassRegistry &);
254-
void initializeRegAllocEvictionAdvisorAnalysisPass(PassRegistry &);
254+
void initializeRegAllocEvictionAdvisorAnalysisLegacyPass(PassRegistry &);
255255
void initializeRegAllocFastPass(PassRegistry &);
256256
void initializeRegAllocPriorityAdvisorAnalysisPass(PassRegistry &);
257257
void initializeRegAllocScoringPass(PassRegistry &);

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "llvm/CodeGen/PeepholeOptimizer.h"
5858
#include "llvm/CodeGen/PostRASchedulerList.h"
5959
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
60+
#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
6061
#include "llvm/CodeGen/RegAllocFast.h"
6162
#include "llvm/CodeGen/RegUsageInfoCollector.h"
6263
#include "llvm/CodeGen/RegUsageInfoPropagate.h"

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
114114
MachinePostDominatorTreeAnalysis())
115115
MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
116116
MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
117+
MACHINE_FUNCTION_ANALYSIS("regalloc-evict", RegAllocEvictionAdvisorAnalysis())
117118
MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
118119
MACHINE_FUNCTION_ANALYSIS("spill-code-placement", SpillPlacementAnalysis())
119120
MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())

0 commit comments

Comments
 (0)