Skip to content

Commit 6faee3f

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 0bef4ef commit 6faee3f

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
@@ -1062,10 +1062,9 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
10621062
template <typename Derived, typename TargetMachineT>
10631063
void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10641064
AddMachinePass &addPass, bool Optimized) const {
1065-
if (Optimized) {
1066-
addPass(RequireAnalysis<RegAllocEvictionAdvisorAnalysis>());
1065+
if (Optimized)
10671066
addPass(RAGreedyPass());
1068-
} else
1067+
else
10691068
addPass(RegAllocFastPass());
10701069
}
10711070

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
112112
MachinePostDominatorTreeAnalysis())
113113
MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
114114
MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
115+
MACHINE_FUNCTION_ANALYSIS("regalloc-evict", RegAllocEvictionAdvisorAnalysis())
115116
MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
116117
MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
117118
// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())

llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ class MLEvictAdvisor : public RegAllocEvictionAdvisor {
370370
class ReleaseModeEvictionAdvisorProvider final
371371
: public RegAllocEvictionAdvisorProvider {
372372
public:
373-
ReleaseModeEvictionAdvisorProvider()
374-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release) {
373+
ReleaseModeEvictionAdvisorProvider(LLVMContext &Ctx)
374+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release, Ctx) {
375375
if (EnableDevelopmentFeatures) {
376376
InputFeatures = {RA_EVICT_FEATURES_LIST(
377377
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -385,15 +385,6 @@ class ReleaseModeEvictionAdvisorProvider final
385385
return R->getAdvisorMode() == AdvisorMode::Release;
386386
}
387387

388-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
389-
for (auto Analysis : AnalysisList) {
390-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
391-
this->MBFI = *MBFI;
392-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
393-
this->Loops = *Loops;
394-
}
395-
}
396-
397388
std::unique_ptr<RegAllocEvictionAdvisor>
398389
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
399390
if (!Runner) {
@@ -406,15 +397,15 @@ class ReleaseModeEvictionAdvisorProvider final
406397
InteractiveChannelBaseName + ".out",
407398
InteractiveChannelBaseName + ".in");
408399
}
400+
assert((MBFI && Loops) &&
401+
"Invalid provider state: must have analysis available");
409402
return std::make_unique<MLEvictAdvisor>(MF, RA, Runner.get(), *MBFI,
410403
*Loops);
411404
}
412405

413406
private:
414407
std::vector<TensorSpec> InputFeatures;
415408
std::unique_ptr<MLModelRunner> Runner;
416-
MachineBlockFrequencyInfo *MBFI;
417-
MachineLoopInfo *Loops;
418409
};
419410

420411
class ReleaseModeEvictionAdvisorAnalysisLegacy final
@@ -427,12 +418,19 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
427418
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
428419
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
429420
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
430-
Provider.setAnalyses({MBFI, Loops});
431-
return Provider.getAdvisor(MF, RA);
421+
Provider->setAnalyses(MBFI, Loops);
422+
return Provider->getAdvisor(MF, RA);
423+
}
424+
425+
void logRewardIfNeeded(const MachineFunction &MF,
426+
llvm::function_ref<float()> GetReward) override {
427+
// No-op in release mode
432428
}
433429

434430
bool doInitialization(Module &M) override {
435-
return Provider.doInitialization(M);
431+
Provider =
432+
std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
433+
return false;
436434
}
437435

438436
static bool classof(const RegAllocEvictionAdvisorAnalysisLegacy *R) {
@@ -446,7 +444,7 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
446444
}
447445

448446
private:
449-
ReleaseModeEvictionAdvisorProvider Provider;
447+
std::unique_ptr<ReleaseModeEvictionAdvisorProvider> Provider;
450448
};
451449

452450
// ===================================
@@ -484,11 +482,8 @@ class DevelopmentModeEvictAdvisor : public MLEvictAdvisor {
484482
class DevelopmentModeEvictionAdvisorProvider final
485483
: public RegAllocEvictionAdvisorProvider {
486484
public:
487-
DevelopmentModeEvictionAdvisorProvider(
488-
MachineBlockFrequencyInfo *MBFI = nullptr,
489-
MachineLoopInfo *Loops = nullptr)
490-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development), MBFI(MBFI),
491-
Loops(Loops) {
485+
DevelopmentModeEvictionAdvisorProvider(LLVMContext &Ctx)
486+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development, Ctx) {
492487
if (EnableDevelopmentFeatures) {
493488
InputFeatures = {RA_EVICT_FEATURES_LIST(
494489
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -508,43 +503,10 @@ class DevelopmentModeEvictionAdvisorProvider final
508503
TensorSpec::createSpec<int32_t>("action_step_type", {1}),
509504
TensorSpec::createSpec<float>("action_reward", {1})};
510505
}
511-
}
512-
// support for isa<> and dyn_cast.
513-
static bool classof(const RegAllocEvictionAdvisorProvider *R) {
514-
return R->getAdvisorMode() == AdvisorMode::Development;
515-
}
516-
517-
void logRewardIfNeeded(const MachineFunction &MF,
518-
llvm::function_ref<float()> GetReward) override {
519-
if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
520-
return;
521-
// The function pass manager would run all the function passes for a
522-
// function, so we assume the last context belongs to this function. If
523-
// this invariant ever changes, we can implement at that time switching
524-
// contexts. At this point, it'd be an error
525-
if (Log->currentContext() != MF.getName()) {
526-
MF.getFunction().getContext().emitError(
527-
"The training log context shouldn't have had changed.");
528-
}
529-
if (Log->hasObservationInProgress())
530-
Log->logReward<float>(GetReward());
531-
}
532-
533-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
534-
for (auto Analysis : AnalysisList) {
535-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
536-
this->MBFI = *MBFI;
537-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
538-
this->Loops = *Loops;
539-
}
540-
}
541-
542-
bool doInitialization(Module &M) override {
543-
LLVMContext &Ctx = M.getContext();
544506
if (ModelUnderTraining.empty() && TrainingLog.empty()) {
545507
Ctx.emitError("Regalloc development mode should be requested with at "
546508
"least logging enabled and/or a training model");
547-
return false;
509+
return;
548510
}
549511
if (ModelUnderTraining.empty())
550512
Runner = std::make_unique<NoInferenceModelRunner>(Ctx, InputFeatures);
@@ -553,15 +515,15 @@ class DevelopmentModeEvictionAdvisorProvider final
553515
Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures);
554516
if (!Runner) {
555517
Ctx.emitError("Regalloc: could not set up the model runner");
556-
return false;
518+
return;
557519
}
558520
if (TrainingLog.empty())
559-
return false;
521+
return;
560522
std::error_code EC;
561523
auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
562524
if (EC) {
563-
M.getContext().emitError(EC.message() + ":" + TrainingLog);
564-
return false;
525+
Ctx.emitError(EC.message() + ":" + TrainingLog);
526+
return;
565527
}
566528
std::vector<TensorSpec> LFS = InputFeatures;
567529
if (auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
@@ -573,7 +535,28 @@ class DevelopmentModeEvictionAdvisorProvider final
573535

574536
Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
575537
/*IncludeReward*/ true);
576-
return false;
538+
return;
539+
}
540+
541+
// support for isa<> and dyn_cast.
542+
static bool classof(const RegAllocEvictionAdvisorProvider *R) {
543+
return R->getAdvisorMode() == AdvisorMode::Development;
544+
}
545+
546+
void logRewardIfNeeded(const MachineFunction &MF,
547+
llvm::function_ref<float()> GetReward) override {
548+
if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
549+
return;
550+
// The function pass manager would run all the function passes for a
551+
// function, so we assume the last context belongs to this function. If
552+
// this invariant ever changes, we can implement at that time switching
553+
// contexts. At this point, it'd be an error
554+
if (Log->currentContext() != MF.getName()) {
555+
MF.getFunction().getContext().emitError(
556+
"The training log context shouldn't have had changed.");
557+
}
558+
if (Log->hasObservationInProgress())
559+
Log->logReward<float>(GetReward());
577560
}
578561

579562
std::unique_ptr<RegAllocEvictionAdvisor>
@@ -594,8 +577,6 @@ class DevelopmentModeEvictionAdvisorProvider final
594577

595578
std::unique_ptr<MLModelRunner> Runner;
596579
std::unique_ptr<Logger> Log;
597-
const MachineBlockFrequencyInfo *MBFI;
598-
const MachineLoopInfo *Loops;
599580
};
600581

601582
class DevelopmentModeEvictionAdvisorAnalysisLegacy final
@@ -605,15 +586,22 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
605586
: RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode::Development) {}
606587

607588
bool doInitialization(Module &M) override {
608-
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
609-
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
610-
Provider.setAnalyses({MBFI, Loops});
611-
return Provider.doInitialization(M);
589+
Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
590+
M.getContext());
591+
return false;
592+
}
593+
594+
void logRewardIfNeeded(const MachineFunction &MF,
595+
llvm::function_ref<float()> GetReward) override {
596+
Provider->logRewardIfNeeded(MF, GetReward);
612597
}
613598

614599
std::unique_ptr<RegAllocEvictionAdvisor>
615600
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
616-
return Provider.getAdvisor(MF, RA);
601+
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
602+
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
603+
Provider->setAnalyses(MBFI, Loops);
604+
return Provider->getAdvisor(MF, RA);
617605
}
618606

619607
// support for isa<> and dyn_cast.
@@ -628,7 +616,7 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
628616
}
629617

630618
private:
631-
DevelopmentModeEvictionAdvisorProvider Provider;
619+
std::unique_ptr<DevelopmentModeEvictionAdvisorProvider> Provider;
632620
};
633621

634622
#endif //#ifdef LLVM_HAVE_TFLITE
@@ -1156,8 +1144,9 @@ void llvm::extractMBBFrequency(
11561144
// Development mode-specific implementations
11571145
#ifdef LLVM_HAVE_TFLITE
11581146

1159-
RegAllocEvictionAdvisorProvider *llvm::createDevelopmentModeAdvisorProvider() {
1160-
return new DevelopmentModeEvictionAdvisorProvider();
1147+
RegAllocEvictionAdvisorProvider *
1148+
llvm::createDevelopmentModeAdvisorProvider(LLVMContext &Ctx) {
1149+
return new DevelopmentModeEvictionAdvisorProvider(Ctx);
11611150
}
11621151

11631152
RegAllocEvictionAdvisorAnalysisLegacy *
@@ -1236,8 +1225,9 @@ bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) {
12361225
}
12371226
#endif // #ifdef LLVM_HAVE_TFLITE
12381227

1239-
RegAllocEvictionAdvisorProvider *llvm::createReleaseModeAdvisorProvider() {
1240-
return new ReleaseModeEvictionAdvisorProvider();
1228+
RegAllocEvictionAdvisorProvider *
1229+
llvm::createReleaseModeAdvisorProvider(LLVMContext &Ctx) {
1230+
return new ReleaseModeEvictionAdvisorProvider(Ctx);
12411231
}
12421232

12431233
RegAllocEvictionAdvisorAnalysisLegacy *

0 commit comments

Comments
 (0)