[llvm-branch-commits] [llvm] [CodeGen][NewPM] Port RegAllocPriorityAdvisor analysis to NPM (PR #118462)
Akshat Oke via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 19 03:33:02 PST 2024
https://github.com/optimisan updated https://github.com/llvm/llvm-project/pull/118462
>From f29c9e1026e304bc2a559ff8521a0ce566246499 Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Tue, 3 Dec 2024 10:12:36 +0000
Subject: [PATCH 1/2] [CodeGen][NewPM] Port RegAllocPriorityAdvisor analysis to
NPM
---
.../llvm}/CodeGen/RegAllocPriorityAdvisor.h | 79 +++++++-
llvm/include/llvm/InitializePasses.h | 2 +-
.../llvm/Passes/MachinePassRegistry.def | 1 +
llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp | 6 +-
.../lib/CodeGen/MLRegAllocPriorityAdvisor.cpp | 184 +++++++++++-------
llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp | 2 +-
llvm/lib/CodeGen/RegAllocGreedy.cpp | 9 +-
llvm/lib/CodeGen/RegAllocGreedy.h | 2 +-
llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp | 120 +++++++++---
llvm/lib/Passes/PassBuilder.cpp | 1 +
10 files changed, 294 insertions(+), 112 deletions(-)
rename llvm/{lib => include/llvm}/CodeGen/RegAllocPriorityAdvisor.h (53%)
diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h b/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
similarity index 53%
rename from llvm/lib/CodeGen/RegAllocPriorityAdvisor.h
rename to llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
index 2d42a43c4c6372..bddfe15bf17751 100644
--- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h
+++ b/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
@@ -9,8 +9,10 @@
#ifndef LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
#define LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
@@ -56,12 +58,73 @@ class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor {
unsigned getPriority(const LiveInterval &LI) const override;
};
-class RegAllocPriorityAdvisorAnalysis : public ImmutablePass {
+/// Common provider for getting the priority advisor and logging rewards.
+/// Legacy analysis forwards all calls to this provider.
+/// New analysis serves the provider as the analysis result.
+/// Expensive setup is done in the constructor, so that the advisor can be
+/// created quickly for every machine function.
+/// TODO: Remove once legacy PM support is dropped.
+class RegAllocPriorityAdvisorProvider {
public:
enum class AdvisorMode : int { Default, Release, Development };
- RegAllocPriorityAdvisorAnalysis(AdvisorMode Mode)
- : ImmutablePass(ID), Mode(Mode){};
+ RegAllocPriorityAdvisorProvider(AdvisorMode Mode) : Mode(Mode) {}
+
+ virtual ~RegAllocPriorityAdvisorProvider() = default;
+
+ virtual void logRewardIfNeeded(const MachineFunction &MF,
+ llvm::function_ref<float()> GetReward) {};
+
+ virtual std::unique_ptr<RegAllocPriorityAdvisor>
+ getAdvisor(const MachineFunction &MF, const RAGreedy &RA) = 0;
+
+ void setAnalyses(SlotIndexes *SI) { this->SI = SI; }
+
+ AdvisorMode getAdvisorMode() const { return Mode; }
+
+protected:
+ SlotIndexes *SI;
+
+private:
+ const AdvisorMode Mode;
+};
+
+RegAllocPriorityAdvisorProvider *createReleaseModePriorityAdvisorProvider();
+
+RegAllocPriorityAdvisorProvider *
+createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx);
+
+class RegAllocPriorityAdvisorAnalysis
+ : public AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis> {
+ static AnalysisKey Key;
+ friend AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis>;
+
+public:
+ struct Result {
+ // Owned by this analysis.
+ RegAllocPriorityAdvisorProvider *Provider;
+
+ bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
+ MachineFunctionAnalysisManager::Invalidator &Inv) {
+ auto PAC = PA.getChecker<RegAllocPriorityAdvisorAnalysis>();
+ return !PAC.preservedWhenStateless() ||
+ Inv.invalidate<SlotIndexesAnalysis>(MF, PA);
+ }
+ };
+
+ Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
+
+private:
+ void initializeProvider(LLVMContext &Ctx);
+ std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider;
+};
+
+class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass {
+public:
+ enum class AdvisorMode : int { Default, Release, Development };
+
+ RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode)
+ : ImmutablePass(ID), Mode(Mode) {};
static char ID;
/// Get an advisor for the given context (i.e. machine function, etc)
@@ -69,7 +132,7 @@ class RegAllocPriorityAdvisorAnalysis : public ImmutablePass {
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) = 0;
AdvisorMode getAdvisorMode() const { return Mode; }
virtual void logRewardIfNeeded(const MachineFunction &MF,
- llvm::function_ref<float()> GetReward){};
+ llvm::function_ref<float()> GetReward) {};
protected:
// This analysis preserves everything, and subclasses may have additional
@@ -85,11 +148,13 @@ class RegAllocPriorityAdvisorAnalysis : public ImmutablePass {
/// Specialization for the API used by the analysis infrastructure to create
/// an instance of the priority advisor.
-template <> Pass *callDefaultCtor<RegAllocPriorityAdvisorAnalysis>();
+template <> Pass *callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>();
-RegAllocPriorityAdvisorAnalysis *createReleaseModePriorityAdvisor();
+RegAllocPriorityAdvisorAnalysisLegacy *
+createReleaseModePriorityAdvisorAnalysis();
-RegAllocPriorityAdvisorAnalysis *createDevelopmentModePriorityAdvisor();
+RegAllocPriorityAdvisorAnalysisLegacy *
+createDevelopmentModePriorityAdvisorAnalysis();
} // namespace llvm
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 8915bf258005a7..e74b85c0de886f 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -255,7 +255,7 @@ void initializeReachingDefAnalysisPass(PassRegistry &);
void initializeReassociateLegacyPassPass(PassRegistry &);
void initializeRegAllocEvictionAdvisorAnalysisLegacyPass(PassRegistry &);
void initializeRegAllocFastPass(PassRegistry &);
-void initializeRegAllocPriorityAdvisorAnalysisPass(PassRegistry &);
+void initializeRegAllocPriorityAdvisorAnalysisLegacyPass(PassRegistry &);
void initializeRegAllocScoringPass(PassRegistry &);
void initializeRegBankSelectPass(PassRegistry &);
void initializeRegToMemWrapperPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index faa7c68ad2acc6..c23e4af1a342bd 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -115,6 +115,7 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
MACHINE_FUNCTION_ANALYSIS("regalloc-evict", RegAllocEvictionAdvisorAnalysis())
+MACHINE_FUNCTION_ANALYSIS("regalloc-priority", RegAllocPriorityAdvisorAnalysis())
MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
MACHINE_FUNCTION_ANALYSIS("spill-code-placement", SpillPlacementAnalysis())
MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
diff --git a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
index 368bf592ebac90..f31ee7a5030db8 100644
--- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
+++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
@@ -115,7 +115,7 @@ class RegAllocScoring : public MachineFunctionPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
AU.addRequired<RegAllocEvictionAdvisorAnalysisLegacy>();
- AU.addRequired<RegAllocPriorityAdvisorAnalysis>();
+ AU.addRequired<RegAllocPriorityAdvisorAnalysisLegacy>();
AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -1229,8 +1229,8 @@ bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) {
getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().logRewardIfNeeded(
MF, GetReward);
- getAnalysis<RegAllocPriorityAdvisorAnalysis>().logRewardIfNeeded(MF,
- GetReward);
+ getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().logRewardIfNeeded(
+ MF, GetReward);
return false;
}
#endif // #ifdef LLVM_HAVE_TFLITE
diff --git a/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
index 9638df81770c1e..dfc06eaa0bfe69 100644
--- a/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
+++ b/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
@@ -12,7 +12,6 @@
#include "AllocationOrder.h"
#include "RegAllocGreedy.h"
-#include "RegAllocPriorityAdvisor.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/InteractiveModelRunner.h"
#include "llvm/Analysis/MLModelRunner.h"
@@ -25,6 +24,7 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/VirtRegMap.h"
@@ -121,23 +121,11 @@ static const std::vector<TensorSpec> InputFeatures{
// ===================================
// Release (AOT) - specifics
// ===================================
-class ReleaseModePriorityAdvisorAnalysis final
- : public RegAllocPriorityAdvisorAnalysis {
+class ReleaseModePriorityAdvisorProvider final
+ : public RegAllocPriorityAdvisorProvider {
public:
- ReleaseModePriorityAdvisorAnalysis()
- : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Release) {}
- // support for isa<> and dyn_cast.
- static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
- return R->getAdvisorMode() == AdvisorMode::Release;
- }
-
-private:
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<SlotIndexesWrapperPass>();
- RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
- }
-
+ ReleaseModePriorityAdvisorProvider()
+ : RegAllocPriorityAdvisorProvider(AdvisorMode::Release) {}
std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
if (!Runner) {
@@ -150,12 +138,44 @@ class ReleaseModePriorityAdvisorAnalysis final
InteractiveChannelBaseName + ".out",
InteractiveChannelBaseName + ".in");
}
- return std::make_unique<MLPriorityAdvisor>(
- MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI(), Runner.get());
+ assert(SI && "SlotIndexes result must be set");
+ return std::make_unique<MLPriorityAdvisor>(MF, RA, SI, Runner.get());
}
+
+private:
std::unique_ptr<MLModelRunner> Runner;
};
+RegAllocPriorityAdvisorProvider *createReleaseModePriorityAdvisorProvider() {
+ return new ReleaseModePriorityAdvisorProvider();
+}
+
+class ReleaseModePriorityAdvisorAnalysisLegacy final
+ : public RegAllocPriorityAdvisorAnalysisLegacy {
+public:
+ ReleaseModePriorityAdvisorAnalysisLegacy()
+ : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Release) {}
+ // support for isa<> and dyn_cast.
+ static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
+ return R->getAdvisorMode() == AdvisorMode::Release;
+ }
+
+private:
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<SlotIndexesWrapperPass>();
+ RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
+ }
+
+ std::unique_ptr<RegAllocPriorityAdvisor>
+ getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
+ return Provider->getAdvisor(MF, RA);
+ }
+
+ std::unique_ptr<ReleaseModePriorityAdvisorProvider> Provider;
+};
+
// ===================================
// Development mode-specifics
// ===================================
@@ -186,46 +206,17 @@ class DevelopmentModePriorityAdvisor : public MLPriorityAdvisor {
Logger *const Log;
};
-class DevelopmentModePriorityAdvisorAnalysis final
- : public RegAllocPriorityAdvisorAnalysis {
-public:
- DevelopmentModePriorityAdvisorAnalysis()
- : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Development) {}
- // support for isa<> and dyn_cast.
- static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
- return R->getAdvisorMode() == AdvisorMode::Development;
- }
-
- void logRewardIfNeeded(const MachineFunction &MF,
- llvm::function_ref<float()> GetReward) override {
- if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
- return;
- // The function pass manager would run all the function passes for a
- // function, so we assume the last context belongs to this function. If
- // this invariant ever changes, we can implement at that time switching
- // contexts. At this point, it'd be an error
- if (Log->currentContext() != MF.getName()) {
- MF.getFunction().getContext().emitError(
- "The training log context shouldn't have had changed.");
- }
- if (Log->hasObservationInProgress())
- Log->logReward<float>(GetReward());
- }
-
-private:
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<SlotIndexesWrapperPass>();
- RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
- }
+class DevelopmentModePriorityAdvisorProvider final
+ : public RegAllocPriorityAdvisorProvider {
+public:
// Save all the logs (when requested).
- bool doInitialization(Module &M) override {
- LLVMContext &Ctx = M.getContext();
+ DevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx)
+ : RegAllocPriorityAdvisorProvider(AdvisorMode::Development) {
if (ModelUnderTraining.empty() && TrainingLog.empty()) {
Ctx.emitError("Regalloc development mode should be requested with at "
"least logging enabled and/or a training model");
- return false;
+ return;
}
if (ModelUnderTraining.empty())
Runner = std::make_unique<NoInferenceModelRunner>(Ctx, InputFeatures);
@@ -234,15 +225,15 @@ class DevelopmentModePriorityAdvisorAnalysis final
Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures);
if (!Runner) {
Ctx.emitError("Regalloc: could not set up the model runner");
- return false;
+ return;
}
if (TrainingLog.empty())
- return false;
+ return;
std::error_code EC;
auto OS = std::make_unique<raw_fd_ostream>(TrainingLog, EC);
if (EC) {
- M.getContext().emitError(EC.message() + ":" + TrainingLog);
- return false;
+ Ctx.emitError(EC.message() + ":" + TrainingLog);
+ return;
}
std::vector<TensorSpec> LFS = InputFeatures;
if (auto *MUTR = dyn_cast<ModelUnderTrainingRunner>(Runner.get()))
@@ -254,7 +245,22 @@ class DevelopmentModePriorityAdvisorAnalysis final
Log = std::make_unique<Logger>(std::move(OS), LFS, Reward,
/*IncludeReward*/ true);
- return false;
+ }
+
+ void logRewardIfNeeded(const MachineFunction &MF,
+ llvm::function_ref<float()> GetReward) override {
+ if (!Log || !Log->hasAnyObservationForContext(MF.getName()))
+ return;
+ // The function pass manager would run all the function passes for a
+ // function, so we assume the last context belongs to this function. If
+ // this invariant ever changes, we can implement at that time switching
+ // contexts. At this point, it'd be an error
+ if (Log->currentContext() != MF.getName()) {
+ MF.getFunction().getContext().emitError(
+ "The training log context shouldn't have had changed.");
+ }
+ if (Log->hasObservationInProgress())
+ Log->logReward<float>(GetReward());
}
std::unique_ptr<RegAllocPriorityAdvisor>
@@ -264,23 +270,68 @@ class DevelopmentModePriorityAdvisorAnalysis final
if (Log) {
Log->switchContext(MF.getName());
}
-
+ assert(SI && "SlotIndexes result must be set");
return std::make_unique<DevelopmentModePriorityAdvisor>(
- MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI(), Runner.get(),
- Log.get());
+ MF, RA, SI, Runner.get(), Log.get());
}
std::unique_ptr<MLModelRunner> Runner;
std::unique_ptr<Logger> Log;
};
+
+RegAllocPriorityAdvisorProvider *
+createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx) {
+ return new DevelopmentModePriorityAdvisorProvider(Ctx);
+}
+
+class DevelopmentModePriorityAdvisorAnalysisLegacy final
+ : public RegAllocPriorityAdvisorAnalysisLegacy {
+public:
+ DevelopmentModePriorityAdvisorAnalysisLegacy()
+ : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Development) {}
+
+ // support for isa<> and dyn_cast.
+ static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
+ return R->getAdvisorMode() == AdvisorMode::Development;
+ }
+
+ void logRewardIfNeeded(const MachineFunction &MF,
+ llvm::function_ref<float()> GetReward) override {
+ Provider->logRewardIfNeeded(MF, GetReward);
+ }
+
+private:
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<SlotIndexesWrapperPass>();
+ RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
+ }
+
+ // Save all the logs (when requested).
+ bool doInitialization(Module &M) override {
+ Provider = std::make_unique<DevelopmentModePriorityAdvisorProvider>(
+ M.getContext());
+ return false;
+ ;
+ }
+
+ std::unique_ptr<RegAllocPriorityAdvisor>
+ getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
+ return Provider->getAdvisor(MF, RA);
+ }
+
+ std::unique_ptr<DevelopmentModePriorityAdvisorProvider> Provider;
+};
#endif //#ifdef LLVM_HAVE_TFLITE
} // namespace llvm
-RegAllocPriorityAdvisorAnalysis *llvm::createReleaseModePriorityAdvisor() {
+RegAllocPriorityAdvisorAnalysisLegacy *
+llvm::createReleaseModePriorityAdvisorAnalysis() {
return llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() ||
!InteractiveChannelBaseName.empty()
- ? new ReleaseModePriorityAdvisorAnalysis()
+ ? new ReleaseModePriorityAdvisorAnalysisLegacy()
: nullptr;
}
@@ -310,8 +361,9 @@ unsigned MLPriorityAdvisor::getPriority(const LiveInterval &LI) const {
}
#ifdef LLVM_HAVE_TFLITE
-RegAllocPriorityAdvisorAnalysis *llvm::createDevelopmentModePriorityAdvisor() {
- return new DevelopmentModePriorityAdvisorAnalysis();
+RegAllocPriorityAdvisorAnalysisLegacy *
+llvm::createDevelopmentModePriorityAdvisorAnalysis() {
+ return new DevelopmentModePriorityAdvisorAnalysisLegacy();
}
unsigned
diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
index e00b81d8dcf61d..7e93bebed73bb7 100644
--- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
+++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
@@ -12,11 +12,11 @@
#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
#include "AllocationOrder.h"
#include "RegAllocGreedy.h"
-#include "RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/LiveRegMatrix.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/IR/Module.h"
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 4571e982e24183..2a5597631a73e5 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -15,7 +15,6 @@
#include "AllocationOrder.h"
#include "InterferenceCache.h"
#include "RegAllocBase.h"
-#include "RegAllocPriorityAdvisor.h"
#include "SplitKit.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
@@ -46,6 +45,7 @@
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
@@ -165,7 +165,7 @@ INITIALIZE_PASS_DEPENDENCY(EdgeBundlesWrapperLegacy)
INITIALIZE_PASS_DEPENDENCY(SpillPlacementWrapperLegacy)
INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysisLegacy)
-INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysis)
+INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysisLegacy)
INITIALIZE_PASS_END(RAGreedy, "greedy",
"Greedy Register Allocator", false, false)
@@ -220,7 +220,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<SpillPlacementWrapperLegacy>();
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
AU.addRequired<RegAllocEvictionAdvisorAnalysisLegacy>();
- AU.addRequired<RegAllocPriorityAdvisorAnalysis>();
+ AU.addRequired<RegAllocPriorityAdvisorAnalysisLegacy>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -2750,7 +2750,8 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
EvictAdvisor =
getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().getProvider()->getAdvisor(*MF, *this);
PriorityAdvisor =
- getAnalysis<RegAllocPriorityAdvisorAnalysis>().getAdvisor(*MF, *this);
+ getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().getAdvisor(*MF,
+ *this);
VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI));
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 001a1e86a96914..89ceefd37795bc 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -14,7 +14,6 @@
#include "InterferenceCache.h"
#include "RegAllocBase.h"
-#include "RegAllocPriorityAdvisor.h"
#include "SplitKit.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
@@ -28,6 +27,7 @@
#include "llvm/CodeGen/LiveRangeEdit.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/SpillPlacement.h"
#include "llvm/CodeGen/Spiller.h"
diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
index 0650aaff56ea00..09078fc57b1bf1 100644
--- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
+++ b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "RegAllocPriorityAdvisor.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "RegAllocGreedy.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/VirtRegMap.h"
@@ -20,76 +20,138 @@
using namespace llvm;
-static cl::opt<RegAllocPriorityAdvisorAnalysis::AdvisorMode> Mode(
+static cl::opt<RegAllocPriorityAdvisorProvider::AdvisorMode> Mode(
"regalloc-enable-priority-advisor", cl::Hidden,
- cl::init(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default),
+ cl::init(RegAllocPriorityAdvisorProvider::AdvisorMode::Default),
cl::desc("Enable regalloc advisor mode"),
cl::values(
- clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default,
+ clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Default,
"default", "Default"),
- clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release,
+ clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Release,
"release", "precompiled"),
- clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development,
+ clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Development,
"development", "for training")));
-char RegAllocPriorityAdvisorAnalysis::ID = 0;
-INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority",
+char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0;
+INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority",
"Regalloc priority policy", false, true)
namespace {
-class DefaultPriorityAdvisorAnalysis final
- : public RegAllocPriorityAdvisorAnalysis {
+
+class DefaultPriorityAdvisorProvider final
+ : public RegAllocPriorityAdvisorProvider {
public:
- DefaultPriorityAdvisorAnalysis(bool NotAsRequested)
- : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default),
+ DefaultPriorityAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx)
+ : RegAllocPriorityAdvisorProvider(AdvisorMode::Default) {
+ if (NotAsRequested)
+ Ctx.emitError("Requested regalloc priority advisor analysis "
+ "could be created. Using default");
+ }
+
+ // support for isa<> and dyn_cast.
+ static bool classof(const RegAllocPriorityAdvisorProvider *R) {
+ return R->getAdvisorMode() == AdvisorMode::Default;
+ }
+
+ std::unique_ptr<RegAllocPriorityAdvisor>
+ getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ assert(SI && "SlotIndexes result must be set");
+ return std::make_unique<DefaultPriorityAdvisor>(MF, RA, SI);
+ }
+};
+
+class DefaultPriorityAdvisorAnalysisLegacy final
+ : public RegAllocPriorityAdvisorAnalysisLegacy {
+public:
+ DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested)
+ : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default),
NotAsRequested(NotAsRequested) {}
// support for isa<> and dyn_cast.
- static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
+ static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
return R->getAdvisorMode() == AdvisorMode::Default;
}
private:
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<SlotIndexesWrapperPass>();
- RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
+ RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
}
+
std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
- return std::make_unique<DefaultPriorityAdvisor>(
- MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI());
+ Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
+ return Provider->getAdvisor(MF, RA);
}
bool doInitialization(Module &M) override {
- if (NotAsRequested)
- M.getContext().emitError("Requested regalloc priority advisor analysis "
- "could be created. Using default");
- return RegAllocPriorityAdvisorAnalysis::doInitialization(M);
+ Provider.reset(
+ new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext()));
+ return false;
}
+
const bool NotAsRequested;
+ std::unique_ptr<DefaultPriorityAdvisorProvider> Provider;
};
} // namespace
-template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
+void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) {
+ if (Provider)
+ return;
+
+ switch (Mode) {
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
+ Provider.reset(
+ new DefaultPriorityAdvisorProvider(/*NotAsRequested*/ false, Ctx));
+ break;
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
+#if defined(LLVM_HAVE_TFLITE)
+ Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx));
+#endif
+ break;
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
+ Provider.reset(createReleaseModePriorityAdvisorProvider());
+ break;
+ }
+ if (!Provider)
+ Provider.reset(
+ new DefaultPriorityAdvisorProvider(/*NotAsRequested*/ true, Ctx));
+}
+
+AnalysisKey RegAllocPriorityAdvisorAnalysis::Key;
+
+RegAllocPriorityAdvisorAnalysis::Result
+RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ // Lazily initialize the provider.
+ initializeProvider(MF.getFunction().getContext());
+ // On each run, update the analysis for the provider.
+ Provider->setAnalyses(&MFAM.getResult<SlotIndexesAnalysis>(MF));
+ // The requiring analysis will construct the advisor.
+ return Result{Provider.get()};
+}
+
+template <>
+Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>() {
Pass *Ret = nullptr;
switch (Mode) {
- case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default:
- Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false);
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
+ Ret = new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ false);
break;
- case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development:
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
#if defined(LLVM_HAVE_TFLITE)
- Ret = createDevelopmentModePriorityAdvisor();
+ Ret = createDevelopmentModePriorityAdvisorAnalysis();
#endif
break;
- case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release:
- Ret = createReleaseModePriorityAdvisor();
+ case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
+ Ret = createReleaseModePriorityAdvisorAnalysis();
break;
}
if (Ret)
return Ret;
- return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true);
+ return new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ true);
}
-StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const {
+StringRef RegAllocPriorityAdvisorAnalysisLegacy::getPassName() const {
switch (getAdvisorMode()) {
case AdvisorMode::Default:
return "Default Regalloc Priority Advisor";
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 132492ccbdd55e..5394e06282e50c 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -125,6 +125,7 @@
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
#include "llvm/CodeGen/RegAllocFast.h"
+#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "llvm/CodeGen/RegUsageInfoCollector.h"
#include "llvm/CodeGen/RegUsageInfoPropagate.h"
#include "llvm/CodeGen/RegisterUsageInfo.h"
>From 7e882f784f8944edc28f6c0dc1fb2d4643210e9b Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Wed, 11 Dec 2024 09:03:53 +0000
Subject: [PATCH 2/2] use the provider as the analysis result
Avoid setting the advisor from the legacy wrapper after setting all
other analyses.
---
.../llvm/CodeGen/RegAllocPriorityAdvisor.h | 5 +++--
.../lib/CodeGen/MLRegAllocPriorityAdvisor.cpp | 19 ++++++++++---------
llvm/lib/CodeGen/RegAllocGreedy.cpp | 6 +++---
llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp | 8 ++++----
4 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h b/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
index bddfe15bf17751..f557165692a46a 100644
--- a/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
+++ b/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h
@@ -128,8 +128,7 @@ class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass {
static char ID;
/// Get an advisor for the given context (i.e. machine function, etc)
- virtual std::unique_ptr<RegAllocPriorityAdvisor>
- getAdvisor(const MachineFunction &MF, const RAGreedy &RA) = 0;
+ virtual std::unique_ptr<RegAllocPriorityAdvisorProvider> &getProvider() = 0;
AdvisorMode getAdvisorMode() const { return Mode; }
virtual void logRewardIfNeeded(const MachineFunction &MF,
llvm::function_ref<float()> GetReward) {};
@@ -141,6 +140,8 @@ class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass {
AU.setPreservesAll();
}
+ std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider;
+
private:
StringRef getPassName() const override;
const AdvisorMode Mode;
diff --git a/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
index dfc06eaa0bfe69..dd598767f1bbc2 100644
--- a/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
+++ b/llvm/lib/CodeGen/MLRegAllocPriorityAdvisor.cpp
@@ -167,13 +167,17 @@ class ReleaseModePriorityAdvisorAnalysisLegacy final
RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
}
- std::unique_ptr<RegAllocPriorityAdvisor>
- getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ std::unique_ptr<RegAllocPriorityAdvisorProvider> &getProvider() override {
Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
- return Provider->getAdvisor(MF, RA);
+ return Provider;
}
- std::unique_ptr<ReleaseModePriorityAdvisorProvider> Provider;
+ bool doInitialization(Module &M) override {
+ Provider = std::make_unique<ReleaseModePriorityAdvisorProvider>();
+ return false;
+ }
+
+ // std::unique_ptr<ReleaseModePriorityAdvisorProvider> Provider;
};
// ===================================
@@ -315,13 +319,10 @@ class DevelopmentModePriorityAdvisorAnalysisLegacy final
;
}
- std::unique_ptr<RegAllocPriorityAdvisor>
- getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ std::unique_ptr<RegAllocPriorityAdvisorProvider> &getProvider() override {
Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
- return Provider->getAdvisor(MF, RA);
+ return Provider;
}
-
- std::unique_ptr<DevelopmentModePriorityAdvisorProvider> Provider;
};
#endif //#ifdef LLVM_HAVE_TFLITE
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 2a5597631a73e5..59fba6199e4600 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2749,9 +2749,9 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
ExtraInfo.emplace();
EvictAdvisor =
getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().getProvider()->getAdvisor(*MF, *this);
- PriorityAdvisor =
- getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>().getAdvisor(*MF,
- *this);
+ PriorityAdvisor = getAnalysis<RegAllocPriorityAdvisorAnalysisLegacy>()
+ .getProvider()
+ ->getAdvisor(*MF, *this);
VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI));
diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
index 09078fc57b1bf1..6699da052de5cf 100644
--- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
+++ b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp
@@ -78,11 +78,11 @@ class DefaultPriorityAdvisorAnalysisLegacy final
RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
}
- std::unique_ptr<RegAllocPriorityAdvisor>
- getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
+ std::unique_ptr<RegAllocPriorityAdvisorProvider> &getProvider() override {
Provider->setAnalyses(&getAnalysis<SlotIndexesWrapperPass>().getSI());
- return Provider->getAdvisor(MF, RA);
+ return Provider;
}
+
bool doInitialization(Module &M) override {
Provider.reset(
new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext()));
@@ -90,7 +90,7 @@ class DefaultPriorityAdvisorAnalysisLegacy final
}
const bool NotAsRequested;
- std::unique_ptr<DefaultPriorityAdvisorProvider> Provider;
+ // std::unique_ptr<DefaultPriorityAdvisorProvider> Provider;
};
} // namespace
More information about the llvm-branch-commits
mailing list