https://github.com/optimisan updated https://github.com/llvm/llvm-project/pull/118462
>From ea0cf8d1805dd4ef093d30dd1f4538c9747be851 Mon Sep 17 00:00:00 2001 From: Akshat Oke <akshat....@amd.com> Date: Tue, 3 Dec 2024 10:12:36 +0000 Subject: [PATCH] [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 69851e420c3d13..87faf111a30cc9 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -254,7 +254,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 baddcb9eb3b5b1..18272f282dde83 100644 --- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp +++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp @@ -109,7 +109,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); } @@ -1213,8 +1213,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 1307ed2651a91a..08fb2105c72b55 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 50b335702e49a0..d3a7f4cb6f1206 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); } @@ -2751,7 +2751,8 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { getAnalysis<RegAllocEvictionAdvisorAnalysisLegacy>().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 db2f2050d215ae..e1aa1497891506 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" _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits