Skip to content

Commit 499590e

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 a0ebf4f commit 499590e

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
@@ -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
@@ -376,8 +376,8 @@ class MLEvictAdvisor : public RegAllocEvictionAdvisor {
376376
class ReleaseModeEvictionAdvisorProvider final
377377
: public RegAllocEvictionAdvisorProvider {
378378
public:
379-
ReleaseModeEvictionAdvisorProvider()
380-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release) {
379+
ReleaseModeEvictionAdvisorProvider(LLVMContext &Ctx)
380+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Release, Ctx) {
381381
if (EnableDevelopmentFeatures) {
382382
InputFeatures = {RA_EVICT_FEATURES_LIST(
383383
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -391,15 +391,6 @@ class ReleaseModeEvictionAdvisorProvider final
391391
return R->getAdvisorMode() == AdvisorMode::Release;
392392
}
393393

394-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
395-
for (auto Analysis : AnalysisList) {
396-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
397-
this->MBFI = *MBFI;
398-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
399-
this->Loops = *Loops;
400-
}
401-
}
402-
403394
std::unique_ptr<RegAllocEvictionAdvisor>
404395
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
405396
if (!Runner) {
@@ -412,15 +403,15 @@ class ReleaseModeEvictionAdvisorProvider final
412403
InteractiveChannelBaseName + ".out",
413404
InteractiveChannelBaseName + ".in");
414405
}
406+
assert((MBFI && Loops) &&
407+
"Invalid provider state: must have analysis available");
415408
return std::make_unique<MLEvictAdvisor>(MF, RA, Runner.get(), *MBFI,
416409
*Loops);
417410
}
418411

419412
private:
420413
std::vector<TensorSpec> InputFeatures;
421414
std::unique_ptr<MLModelRunner> Runner;
422-
MachineBlockFrequencyInfo *MBFI;
423-
MachineLoopInfo *Loops;
424415
};
425416

426417
class ReleaseModeEvictionAdvisorAnalysisLegacy final
@@ -433,12 +424,19 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
433424
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
434425
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
435426
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
436-
Provider.setAnalyses({MBFI, Loops});
437-
return Provider.getAdvisor(MF, RA);
427+
Provider->setAnalyses(MBFI, Loops);
428+
return Provider->getAdvisor(MF, RA);
429+
}
430+
431+
void logRewardIfNeeded(const MachineFunction &MF,
432+
llvm::function_ref<float()> GetReward) override {
433+
// No-op in release mode
438434
}
439435

440436
bool doInitialization(Module &M) override {
441-
return Provider.doInitialization(M);
437+
Provider =
438+
std::make_unique<ReleaseModeEvictionAdvisorProvider>(M.getContext());
439+
return false;
442440
}
443441

444442
static bool classof(const RegAllocEvictionAdvisorAnalysisLegacy *R) {
@@ -452,7 +450,7 @@ class ReleaseModeEvictionAdvisorAnalysisLegacy final
452450
}
453451

454452
private:
455-
ReleaseModeEvictionAdvisorProvider Provider;
453+
std::unique_ptr<ReleaseModeEvictionAdvisorProvider> Provider;
456454
};
457455

458456
// ===================================
@@ -490,11 +488,8 @@ class DevelopmentModeEvictAdvisor : public MLEvictAdvisor {
490488
class DevelopmentModeEvictionAdvisorProvider final
491489
: public RegAllocEvictionAdvisorProvider {
492490
public:
493-
DevelopmentModeEvictionAdvisorProvider(
494-
MachineBlockFrequencyInfo *MBFI = nullptr,
495-
MachineLoopInfo *Loops = nullptr)
496-
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development), MBFI(MBFI),
497-
Loops(Loops) {
491+
DevelopmentModeEvictionAdvisorProvider(LLVMContext &Ctx)
492+
: RegAllocEvictionAdvisorProvider(AdvisorMode::Development, Ctx) {
498493
if (EnableDevelopmentFeatures) {
499494
InputFeatures = {RA_EVICT_FEATURES_LIST(
500495
_DECL_FEATURES) RA_EVICT_FIRST_DEVELOPMENT_FEATURE(_DECL_FEATURES)
@@ -514,43 +509,10 @@ class DevelopmentModeEvictionAdvisorProvider final
514509
TensorSpec::createSpec<int32_t>("action_step_type", {1}),
515510
TensorSpec::createSpec<float>("action_reward", {1})};
516511
}
517-
}
518-
// support for isa<> and dyn_cast.
519-
static bool classof(const RegAllocEvictionAdvisorProvider *R) {
520-
return R->getAdvisorMode() == AdvisorMode::Development;
521-
}
522-
523-
void logRewardIfNeeded(const MachineFunction &MF,
524-
llvm::function_ref<float()> GetReward) override {
525-
if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
526-
return;
527-
// The function pass manager would run all the function passes for a
528-
// function, so we assume the last context belongs to this function. If
529-
// this invariant ever changes, we can implement at that time switching
530-
// contexts. At this point, it'd be an error
531-
if (Log->currentContext() != MF.getName()) {
532-
MF.getFunction().getContext().emitError(
533-
"The training log context shouldn't have had changed.");
534-
}
535-
if (Log->hasObservationInProgress())
536-
Log->logReward<float>(GetReward());
537-
}
538-
539-
void setAnalyses(std::initializer_list<llvm::Any> AnalysisList) override {
540-
for (auto Analysis : AnalysisList) {
541-
if (auto **MBFI = llvm::any_cast<MachineBlockFrequencyInfo *>(&Analysis))
542-
this->MBFI = *MBFI;
543-
if (auto **Loops = llvm::any_cast<MachineLoopInfo *>(&Analysis))
544-
this->Loops = *Loops;
545-
}
546-
}
547-
548-
bool doInitialization(Module &M) override {
549-
LLVMContext &Ctx = M.getContext();
550512
if (ModelUnderTraining.empty() && TrainingLog.empty()) {
551513
Ctx.emitError("Regalloc development mode should be requested with at "
552514
"least logging enabled and/or a training model");
553-
return false;
515+
return;
554516
}
555517
if (ModelUnderTraining.empty())
556518
Runner = std::make_unique<NoInferenceModelRunner>(Ctx, InputFeatures);
@@ -559,15 +521,15 @@ class DevelopmentModeEvictionAdvisorProvider final
559521
Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures);
560522
if (!Runner) {
561523
Ctx.emitError("Regalloc: could not set up the model runner");
562-
return false;
524+
return;
563525
}
564526
if (TrainingLog.empty())
565-
return false;
527+
return;
566528
std::error_code EC;
567529
auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
568530
if (EC) {
569-
M.getContext().emitError(EC.message() + ":" + TrainingLog);
570-
return false;
531+
Ctx.emitError(EC.message() + ":" + TrainingLog);
532+
return;
571533
}
572534
std::vector<TensorSpec> LFS = InputFeatures;
573535
if (auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
@@ -579,7 +541,28 @@ class DevelopmentModeEvictionAdvisorProvider final
579541

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

585568
std::unique_ptr<RegAllocEvictionAdvisor>
@@ -600,8 +583,6 @@ class DevelopmentModeEvictionAdvisorProvider final
600583

601584
std::unique_ptr<MLModelRunner> Runner;
602585
std::unique_ptr<Logger> Log;
603-
const MachineBlockFrequencyInfo *MBFI;
604-
const MachineLoopInfo *Loops;
605586
};
606587

607588
class DevelopmentModeEvictionAdvisorAnalysisLegacy final
@@ -611,15 +592,22 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
611592
: RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode::Development) {}
612593

613594
bool doInitialization(Module &M) override {
614-
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
615-
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
616-
Provider.setAnalyses({MBFI, Loops});
617-
return Provider.doInitialization(M);
595+
Provider = std::make_unique<DevelopmentModeEvictionAdvisorProvider>(
596+
M.getContext());
597+
return false;
598+
}
599+
600+
void logRewardIfNeeded(const MachineFunction &MF,
601+
llvm::function_ref<float()> GetReward) override {
602+
Provider->logRewardIfNeeded(MF, GetReward);
618603
}
619604

620605
std::unique_ptr<RegAllocEvictionAdvisor>
621606
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
622-
return Provider.getAdvisor(MF, RA);
607+
auto *MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
608+
auto *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
609+
Provider->setAnalyses(MBFI, Loops);
610+
return Provider->getAdvisor(MF, RA);
623611
}
624612

625613
// support for isa<> and dyn_cast.
@@ -634,7 +622,7 @@ class DevelopmentModeEvictionAdvisorAnalysisLegacy final
634622
}
635623

636624
private:
637-
DevelopmentModeEvictionAdvisorProvider Provider;
625+
std::unique_ptr<DevelopmentModeEvictionAdvisorProvider> Provider;
638626
};
639627

640628
#endif // #ifdef LLVM_HAVE_TFLITE
@@ -1171,8 +1159,9 @@ void llvm::extractMBBFrequency(
11711159
// Development mode-specific implementations
11721160
#ifdef LLVM_HAVE_TFLITE
11731161

1174-
RegAllocEvictionAdvisorProvider *llvm::createDevelopmentModeAdvisorProvider() {
1175-
return new DevelopmentModeEvictionAdvisorProvider();
1162+
RegAllocEvictionAdvisorProvider *
1163+
llvm::createDevelopmentModeAdvisorProvider(LLVMContext &Ctx) {
1164+
return new DevelopmentModeEvictionAdvisorProvider(Ctx);
11761165
}
11771166

11781167
RegAllocEvictionAdvisorAnalysisLegacy *
@@ -1251,8 +1240,9 @@ bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) {
12511240
}
12521241
#endif // #ifdef LLVM_HAVE_TFLITE
12531242

1254-
RegAllocEvictionAdvisorProvider *llvm::createReleaseModeAdvisorProvider() {
1255-
return new ReleaseModeEvictionAdvisorProvider();
1243+
RegAllocEvictionAdvisorProvider *
1244+
llvm::createReleaseModeAdvisorProvider(LLVMContext &Ctx) {
1245+
return new ReleaseModeEvictionAdvisorProvider(Ctx);
12561246
}
12571247

12581248
RegAllocEvictionAdvisorAnalysisLegacy *

0 commit comments

Comments
 (0)