Skip to content

Commit 7ef1c18

Browse files
committed
Remove Provider::doInit, change to MF analysis
init is in the constructor. The new MF analysis lazily intiailizes the provider. The (wrapped) provider is the analysis result.
1 parent 398e4f5 commit 7ef1c18

File tree

6 files changed

+143
-114
lines changed

6 files changed

+143
-114
lines changed

llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "llvm/ADT/ArrayRef.h"
1414
#include "llvm/ADT/SmallSet.h"
1515
#include "llvm/ADT/StringRef.h"
16+
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
17+
#include "llvm/CodeGen/MachineLoopInfo.h"
1618
#include "llvm/CodeGen/Register.h"
1719
#include "llvm/Config/llvm-config.h"
1820
#include "llvm/IR/PassManager.h"
@@ -200,33 +202,43 @@ class RegAllocEvictionAdvisorAnalysisLegacy : public ImmutablePass {
200202
class RegAllocEvictionAdvisorProvider {
201203
public:
202204
enum class AdvisorMode : int { Default, Release, Development };
203-
RegAllocEvictionAdvisorProvider(AdvisorMode Mode) : Mode(Mode) {}
205+
RegAllocEvictionAdvisorProvider(AdvisorMode Mode, LLVMContext &Ctx)
206+
: Ctx(Ctx), Mode(Mode) {}
204207

205208
virtual ~RegAllocEvictionAdvisorProvider() = default;
206209

207-
virtual bool doInitialization(Module &M) { return false; }
208-
209210
virtual void logRewardIfNeeded(const MachineFunction &MF,
210211
llvm::function_ref<float()> GetReward) {}
211212

212213
virtual std::unique_ptr<RegAllocEvictionAdvisor>
213214
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) = 0;
214215

215-
/// Set the analyses that the advisor needs to use as they might not be
216-
/// available before the advisor is created.
217-
virtual void setAnalyses(std::initializer_list<llvm::Any> AnalysisP) {}
216+
/// We create this provider in doInitialization which doesn't have these
217+
/// analyses. For NPM, we do have them in run(MachineFunction&)
218+
virtual void setAnalyses(MachineBlockFrequencyInfo *MBFI,
219+
MachineLoopInfo *Loops) {
220+
this->MBFI = MBFI;
221+
this->Loops = Loops;
222+
}
218223

219224
AdvisorMode getAdvisorMode() const { return Mode; }
220225

226+
protected:
227+
LLVMContext &Ctx;
228+
MachineBlockFrequencyInfo *MBFI;
229+
MachineLoopInfo *Loops;
230+
221231
private:
222232
const AdvisorMode Mode;
223233
};
224234

225-
RegAllocEvictionAdvisorProvider *createReleaseModeAdvisorProvider();
226-
RegAllocEvictionAdvisorProvider *createDevelopmentModeAdvisorProvider();
235+
RegAllocEvictionAdvisorProvider *
236+
createReleaseModeAdvisorProvider(LLVMContext &Ctx);
237+
RegAllocEvictionAdvisorProvider *
238+
createDevelopmentModeAdvisorProvider(LLVMContext &Ctx);
227239

228-
/// A Module analysis for fetching the Eviction Advisor. This is not a
229-
/// MachineFunction analysis for two reasons:
240+
/// A MachineFunction analysis for fetching the Eviction Advisor.
241+
/// This sets up the Provider lazily and caches it.
230242
/// - in the ML implementation case, the evaluator is stateless but (especially
231243
/// in the development mode) expensive to set up. With a Module Analysis, we
232244
/// `require` it and set it up once.
@@ -241,8 +253,30 @@ class RegAllocEvictionAdvisorAnalysis
241253
friend AnalysisInfoMixin<RegAllocEvictionAdvisorAnalysis>;
242254

243255
public:
244-
using Result = std::unique_ptr<RegAllocEvictionAdvisorProvider>;
245-
Result run(Module &MF, ModuleAnalysisManager &MAM);
256+
struct Result {
257+
// owned by this analysis
258+
RegAllocEvictionAdvisorProvider *Provider;
259+
260+
bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
261+
MachineFunctionAnalysisManager::Invalidator &Inv) {
262+
auto PAC = PA.getChecker<RegAllocEvictionAdvisorAnalysis>();
263+
// If we are in default mode, the provider is always valid.
264+
if (Provider->getAdvisorMode() ==
265+
RegAllocEvictionAdvisorProvider::AdvisorMode::Default)
266+
return !PAC.preservedWhenStateless();
267+
// MBFI and Loops are used in release and development modes, so check
268+
// those.
269+
return !PAC.preservedWhenStateless() ||
270+
Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA) ||
271+
Inv.invalidate<MachineLoopAnalysis>(MF, PA);
272+
}
273+
};
274+
275+
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM);
276+
277+
private:
278+
void initializeProvider(LLVMContext &Ctx);
279+
std::unique_ptr<RegAllocEvictionAdvisorProvider> Provider;
246280
};
247281

248282
/// Specialization for the API used by the analysis infrastructure to create

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,10 +1065,9 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
10651065
template <typename Derived, typename TargetMachineT>
10661066
void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10671067
AddMachinePass &addPass, bool Optimized) const {
1068-
if (Optimized) {
1069-
addPass(RequireAnalysis<RegAllocEvictionAdvisorAnalysis>());
1068+
if (Optimized)
10701069
addPass(RAGreedyPass());
1071-
} else
1070+
else
10721071
addPass(RegAllocFastPass());
10731072
}
10741073

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())

llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ class MLEvictAdvisor : public RegAllocEvictionAdvisor {
393393
class ReleaseModeEvictionAdvisorProvider final
394394
: public RegAllocEvictionAdvisorProvider {
395395
public:
396-
ReleaseModeEvictionAdvisorProvider()
397-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release) {
396+
ReleaseModeEvictionAdvisorProvider(LLVMContext &Ctx)
397+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release, Ctx) {
398398
if (EnableDevelopmentFeatures) {
399399
InputFeatures = {RA_EVICT_FEATURES_LIST(
400400
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -408,15 +408,6 @@ class ReleaseModeEvictionAdvisorProvider final
408408
return R->getAdvisorMode() == AdvisorMode::Release;
409409
}
410410

411-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
412-
for (auto Analysis : AnalysisList) {
413-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
414-
this->MBFI = *MBFI;
415-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
416-
this->Loops = *Loops;
417-
}
418-
}
419-
420411
std::unique_ptr<RegAllocEvictionAdvisor>
421412
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
422413
if (!Runner) {
@@ -429,15 +420,15 @@ class ReleaseModeEvictionAdvisorProvider final
429420
InteractiveChannelBaseName + ".out",
430421
InteractiveChannelBaseName + ".in");
431422
}
423+
assert((MBFI && Loops) &&
424+
"Invalid provider state: must have analysis available");
432425
return std::make_unique<MLEvictAdvisor>(MF, RA, Runner.get(), *MBFI,
433426
*Loops);
434427
}
435428

436429
private:
437430
std::vector<TensorSpec> InputFeatures;
438431
std::unique_ptr<MLModelRunner> Runner;
439-
MachineBlockFrequencyInfo *MBFI;
440-
MachineLoopInfo *Loops;
441432
};
442433

443434
class ReleaseModeEvictionAdvisorAnalysisLegacy final
@@ -450,12 +441,19 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
450441
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
451442
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
452443
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
453-
Provider.setAnalyses({MBFI, Loops});
454-
return Provider.getAdvisor(MF, RA);
444+
Provider->setAnalyses(MBFI, Loops);
445+
return Provider->getAdvisor(MF, RA);
446+
}
447+
448+
void logRewardIfNeeded(const MachineFunction &MF,
449+
llvm::function_ref<float()> GetReward) override {
450+
// No-op in release mode
455451
}
456452

457453
bool doInitialization(Module &M) override {
458-
return Provider.doInitialization(M);
454+
Provider =
455+
std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
456+
return false;
459457
}
460458

461459
static bool classof(const RegAllocEvictionAdvisorAnalysisLegacy *R) {
@@ -469,7 +467,7 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
469467
}
470468

471469
private:
472-
ReleaseModeEvictionAdvisorProvider Provider;
470+
std::unique_ptr<ReleaseModeEvictionAdvisorProvider> Provider;
473471
};
474472

475473
// ===================================
@@ -507,11 +505,8 @@ class DevelopmentModeEvictAdvisor : public MLEvictAdvisor {
507505
class DevelopmentModeEvictionAdvisorProvider final
508506
: public RegAllocEvictionAdvisorProvider {
509507
public:
510-
DevelopmentModeEvictionAdvisorProvider(
511-
MachineBlockFrequencyInfo *MBFI = nullptr,
512-
MachineLoopInfo *Loops = nullptr)
513-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development), MBFI(MBFI),
514-
Loops(Loops) {
508+
DevelopmentModeEvictionAdvisorProvider(LLVMContext &Ctx)
509+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development, Ctx) {
515510
if (EnableDevelopmentFeatures) {
516511
InputFeatures = {RA_EVICT_FEATURES_LIST(
517512
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -531,43 +526,10 @@ class DevelopmentModeEvictionAdvisorProvider final
531526
TensorSpec::createSpec<int32_t>("action_step_type", {1}),
532527
TensorSpec::createSpec<float>("action_reward", {1})};
533528
}
534-
}
535-
// support for isa<> and dyn_cast.
536-
static bool classof(const RegAllocEvictionAdvisorProvider *R) {
537-
return R->getAdvisorMode() == AdvisorMode::Development;
538-
}
539-
540-
void logRewardIfNeeded(const MachineFunction &MF,
541-
llvm::function_ref<float()> GetReward) override {
542-
if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
543-
return;
544-
// The function pass manager would run all the function passes for a
545-
// function, so we assume the last context belongs to this function. If
546-
// this invariant ever changes, we can implement at that time switching
547-
// contexts. At this point, it'd be an error
548-
if (Log->currentContext() != MF.getName()) {
549-
MF.getFunction().getContext().emitError(
550-
"The training log context shouldn't have had changed.");
551-
}
552-
if (Log->hasObservationInProgress())
553-
Log->logReward<float>(GetReward());
554-
}
555-
556-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
557-
for (auto Analysis : AnalysisList) {
558-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
559-
this->MBFI = *MBFI;
560-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
561-
this->Loops = *Loops;
562-
}
563-
}
564-
565-
bool doInitialization(Module &M) override {
566-
LLVMContext &Ctx = M.getContext();
567529
if (ModelUnderTraining.empty() && TrainingLog.empty()) {
568530
Ctx.emitError("Regalloc development mode should be requested with at "
569531
"least logging enabled and/or a training model");
570-
return false;
532+
return;
571533
}
572534
if (ModelUnderTraining.empty())
573535
Runner = std::make_unique<NoInferenceModelRunner>(Ctx, InputFeatures);
@@ -576,15 +538,15 @@ class DevelopmentModeEvictionAdvisorProvider final
576538
Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures);
577539
if (!Runner) {
578540
Ctx.emitError("Regalloc: could not set up the model runner");
579-
return false;
541+
return;
580542
}
581543
if (TrainingLog.empty())
582-
return false;
544+
return;
583545
std::error_code EC;
584546
auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
585547
if (EC) {
586-
M.getContext().emitError(EC.message() + ":" + TrainingLog);
587-
return false;
548+
Ctx.emitError(EC.message() + ":" + TrainingLog);
549+
return;
588550
}
589551
std::vector<TensorSpec> LFS = InputFeatures;
590552
if (auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
@@ -596,7 +558,28 @@ class DevelopmentModeEvictionAdvisorProvider final
596558

597559
Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
598560
/*IncludeReward*/ true);
599-
return false;
561+
return;
562+
}
563+
564+
// support for isa<> and dyn_cast.
565+
static bool classof(const RegAllocEvictionAdvisorProvider *R) {
566+
return R->getAdvisorMode() == AdvisorMode::Development;
567+
}
568+
569+
void logRewardIfNeeded(const MachineFunction &MF,
570+
llvm::function_ref<float()> GetReward) override {
571+
if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
572+
return;
573+
// The function pass manager would run all the function passes for a
574+
// function, so we assume the last context belongs to this function. If
575+
// this invariant ever changes, we can implement at that time switching
576+
// contexts. At this point, it'd be an error
577+
if (Log->currentContext() != MF.getName()) {
578+
MF.getFunction().getContext().emitError(
579+
"The training log context shouldn't have had changed.");
580+
}
581+
if (Log->hasObservationInProgress())
582+
Log->logReward<float>(GetReward());
600583
}
601584

602585
std::unique_ptr<RegAllocEvictionAdvisor>
@@ -617,8 +600,6 @@ class DevelopmentModeEvictionAdvisorProvider final
617600

618601
std::unique_ptr<MLModelRunner> Runner;
619602
std::unique_ptr<Logger> Log;
620-
const MachineBlockFrequencyInfo *MBFI;
621-
const MachineLoopInfo *Loops;
622603
};
623604

624605
class DevelopmentModeEvictionAdvisorAnalysisLegacy final
@@ -628,15 +609,22 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
628609
: RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode::Development) {}
629610

630611
bool doInitialization(Module &M) override {
631-
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
632-
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
633-
Provider.setAnalyses({MBFI, Loops});
634-
return Provider.doInitialization(M);
612+
Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
613+
M.getContext());
614+
return false;
615+
}
616+
617+
void logRewardIfNeeded(const MachineFunction &MF,
618+
llvm::function_ref<float()> GetReward) override {
619+
Provider->logRewardIfNeeded(MF, GetReward);
635620
}
636621

637622
std::unique_ptr<RegAllocEvictionAdvisor>
638623
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
639-
return Provider.getAdvisor(MF, RA);
624+
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
625+
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
626+
Provider->setAnalyses(MBFI, Loops);
627+
return Provider->getAdvisor(MF, RA);
640628
}
641629

642630
// support for isa<> and dyn_cast.
@@ -651,7 +639,7 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
651639
}
652640

653641
private:
654-
DevelopmentModeEvictionAdvisorProvider Provider;
642+
std::unique_ptr<DevelopmentModeEvictionAdvisorProvider> Provider;
655643
};
656644

657645
#endif // #ifdef LLVM_HAVE_TFLITE
@@ -1204,8 +1192,9 @@ void llvm::extractMBBFrequency(
12041192
// Development mode-specific implementations
12051193
#ifdef LLVM_HAVE_TFLITE
12061194

1207-
RegAllocEvictionAdvisorProvider *llvm::createDevelopmentModeAdvisorProvider() {
1208-
return new DevelopmentModeEvictionAdvisorProvider();
1195+
RegAllocEvictionAdvisorProvider *
1196+
llvm::createDevelopmentModeAdvisorProvider(LLVMContext &Ctx) {
1197+
return new DevelopmentModeEvictionAdvisorProvider(Ctx);
12091198
}
12101199

12111200
RegAllocEvictionAdvisorAnalysisLegacy *
@@ -1284,8 +1273,9 @@ bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) {
12841273
}
12851274
#endif // #ifdef LLVM_HAVE_TFLITE
12861275

1287-
RegAllocEvictionAdvisorProvider *llvm::createReleaseModeAdvisorProvider() {
1288-
return new ReleaseModeEvictionAdvisorProvider();
1276+
RegAllocEvictionAdvisorProvider *
1277+
llvm::createReleaseModeAdvisorProvider(LLVMContext &Ctx) {
1278+
return new ReleaseModeEvictionAdvisorProvider(Ctx);
12891279
}
12901280

12911281
RegAllocEvictionAdvisorAnalysisLegacy *

0 commit comments

Comments
 (0)