diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h b/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h similarity index 54% rename from llvm/lib/CodeGen/RegAllocPriorityAdvisor.h rename to llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h index 0758743c2b140..b0355795370d8 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 { @@ -68,20 +70,72 @@ class DummyPriorityAdvisor : 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, Dummy }; - RegAllocPriorityAdvisorAnalysis(AdvisorMode Mode) - : ImmutablePass(ID), Mode(Mode){}; + RegAllocPriorityAdvisorProvider(AdvisorMode Mode) : Mode(Mode) {} + + virtual ~RegAllocPriorityAdvisorProvider() = default; + + virtual void logRewardIfNeeded(const MachineFunction &MF, + function_ref GetReward) {}; + + virtual std::unique_ptr + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes &SI) = 0; + + AdvisorMode getAdvisorMode() const { return Mode; } + +private: + const AdvisorMode Mode; +}; + +class RegAllocPriorityAdvisorAnalysis + : public AnalysisInfoMixin { + static AnalysisKey Key; + friend AnalysisInfoMixin; + +public: + struct Result { + // Owned by this analysis. + RegAllocPriorityAdvisorProvider *Provider; + + bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, + MachineFunctionAnalysisManager::Invalidator &Inv) { + auto PAC = PA.getChecker(); + return !PAC.preservedWhenStateless() || + Inv.invalidate(MF, PA); + } + }; + + Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM); + +private: + void initializeProvider(LLVMContext &Ctx); + void initializeMLProvider(RegAllocPriorityAdvisorProvider::AdvisorMode Mode, + LLVMContext &Ctx); + std::unique_ptr Provider; +}; + +class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass { +public: + using AdvisorMode = RegAllocPriorityAdvisorProvider::AdvisorMode; + RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode) + : ImmutablePass(ID), Mode(Mode) {}; static char ID; /// Get an advisor for the given context (i.e. machine function, etc) - virtual std::unique_ptr - getAdvisor(const MachineFunction &MF, const RAGreedy &RA) = 0; + RegAllocPriorityAdvisorProvider &getProvider() { return *Provider; } AdvisorMode getAdvisorMode() const { return Mode; } virtual void logRewardIfNeeded(const MachineFunction &MF, - llvm::function_ref GetReward){}; + llvm::function_ref GetReward) {}; protected: // This analysis preserves everything, and subclasses may have additional @@ -90,6 +144,8 @@ class RegAllocPriorityAdvisorAnalysis : public ImmutablePass { AU.setPreservesAll(); } + std::unique_ptr Provider; + private: StringRef getPassName() const override; const AdvisorMode Mode; @@ -97,11 +153,19 @@ class RegAllocPriorityAdvisorAnalysis : public ImmutablePass { /// Specialization for the API used by the analysis infrastructure to create /// an instance of the priority advisor. -template <> Pass *callDefaultCtor(); +template <> Pass *callDefaultCtor(); + +RegAllocPriorityAdvisorAnalysisLegacy * +createReleaseModePriorityAdvisorAnalysis(); + +RegAllocPriorityAdvisorAnalysisLegacy * +createDevelopmentModePriorityAdvisorAnalysis(); -RegAllocPriorityAdvisorAnalysis *createReleaseModePriorityAdvisor(); +LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider * +createReleaseModePriorityAdvisorProvider(); -RegAllocPriorityAdvisorAnalysis *createDevelopmentModePriorityAdvisor(); +LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider * +createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx); } // namespace llvm diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 81a602c8889d8..5b30eb53208a8 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -253,7 +253,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 2b5e258682585..373bd047e2395 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 1a8e11de909e8..8215d07b74dba 100644 --- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp +++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp @@ -116,7 +116,7 @@ class RegAllocScoring : public MachineFunctionPass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -1242,8 +1242,8 @@ bool RegAllocScoring::runOnMachineFunction(MachineFunction &MF) { getAnalysis().logRewardIfNeeded( MF, GetReward); - getAnalysis().logRewardIfNeeded(MF, - GetReward); + getAnalysis().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 9638df81770c1..50ecd3ce2c88c 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,25 +121,14 @@ static const std::vector 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(); - RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); - } - + ReleaseModePriorityAdvisorProvider() + : RegAllocPriorityAdvisorProvider(AdvisorMode::Release) {} std::unique_ptr - getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes &SI) override { if (!Runner) { if (InteractiveChannelBaseName.empty()) Runner = std::make_unique>( @@ -150,12 +139,36 @@ class ReleaseModePriorityAdvisorAnalysis final InteractiveChannelBaseName + ".out", InteractiveChannelBaseName + ".in"); } - return std::make_unique( - MF, RA, &getAnalysis().getSI(), Runner.get()); + return std::make_unique(MF, RA, &SI, Runner.get()); } + +private: std::unique_ptr Runner; }; +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(); + RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); + } + + bool doInitialization(Module &M) override { + Provider = std::make_unique(); + return false; + } +}; + // =================================== // Development mode-specifics // =================================== @@ -186,46 +199,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 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(GetReward()); - } - -private: - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesAll(); - AU.addRequired(); - 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(Ctx, InputFeatures); @@ -234,15 +218,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(TrainingLog, EC); if (EC) { - M.getContext().emitError(EC.message() + ":" + TrainingLog); - return false; + Ctx.emitError(EC.message() + ":" + TrainingLog); + return; } std::vector LFS = InputFeatures; if (auto *MUTR = dyn_cast(Runner.get())) @@ -254,33 +238,80 @@ class DevelopmentModePriorityAdvisorAnalysis final Log = std::make_unique(std::move(OS), LFS, Reward, /*IncludeReward*/ true); - return false; + } + + void logRewardIfNeeded(const MachineFunction &MF, + llvm::function_ref 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(GetReward()); } std::unique_ptr - getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes &SI) override { if (!Runner) return nullptr; if (Log) { Log->switchContext(MF.getName()); } - return std::make_unique( - MF, RA, &getAnalysis().getSI(), Runner.get(), - Log.get()); + MF, RA, &SI, Runner.get(), Log.get()); } std::unique_ptr Runner; std::unique_ptr Log; }; + +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 GetReward) override { + Provider->logRewardIfNeeded(MF, GetReward); + } + +private: + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); + } + + // Save all the logs (when requested). + bool doInitialization(Module &M) override { + Provider = std::make_unique( + M.getContext()); + return false; + ; + } +}; #endif //#ifdef LLVM_HAVE_TFLITE } // namespace llvm -RegAllocPriorityAdvisorAnalysis *llvm::createReleaseModePriorityAdvisor() { +RegAllocPriorityAdvisorAnalysisLegacy * +llvm::createReleaseModePriorityAdvisorAnalysis() { return llvm::isEmbeddedModelEvaluatorValid() || !InteractiveChannelBaseName.empty() - ? new ReleaseModePriorityAdvisorAnalysis() + ? new ReleaseModePriorityAdvisorAnalysisLegacy() : nullptr; } @@ -310,8 +341,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 @@ -356,4 +388,14 @@ DevelopmentModePriorityAdvisor::getPriority(const LiveInterval &LI) const { return static_cast(Prio); } +RegAllocPriorityAdvisorProvider * +llvm::createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx) { + return new DevelopmentModePriorityAdvisorProvider(Ctx); +} + #endif // #ifdef LLVM_HAVE_TFLITE + +RegAllocPriorityAdvisorProvider * +llvm::createReleaseModePriorityAdvisorProvider() { + return new ReleaseModePriorityAdvisorProvider(); +} diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp index 2369615ef0fb6..30523611977f4 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 9318c1df0b5e2..bd81d630f9d1f 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(); AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -2770,8 +2770,9 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { getAnalysis().getProvider(); EvictAdvisor = EvictAdvisorProvider.getAdvisor(*MF, *this, MBFI, Loops); - PriorityAdvisor = - getAnalysis().getAdvisor(*MF, *this); + PriorityAdvisor = getAnalysis() + .getProvider() + .getAdvisor(*MF, *this, *Indexes); VRAI = std::make_unique(*MF, *LIS, *VRM, *Loops, *MBFI); SpillerInstance.reset( diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h index 1d55a8241d760..1698607984bcd 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 4525b8fc5a383..544ff72a04efd 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,107 +20,180 @@ using namespace llvm; -static cl::opt Mode( +static cl::opt 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"), clEnumValN( - RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy, "dummy", + RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy, "dummy", "prioritize low virtual register numbers for test and debug"))); -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: + 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 + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes &SI) override { + return std::make_unique(MF, RA, &SI); + } +}; + +class DummyPriorityAdvisorProvider final + : public RegAllocPriorityAdvisorProvider { +public: + DummyPriorityAdvisorProvider() + : RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {} + + static bool classof(const RegAllocPriorityAdvisorProvider *R) { + return R->getAdvisorMode() == AdvisorMode::Dummy; + } + + std::unique_ptr + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes &SI) override { + return std::make_unique(MF, RA, &SI); + } +}; + +class DefaultPriorityAdvisorAnalysisLegacy final + : public RegAllocPriorityAdvisorAnalysisLegacy { public: - DefaultPriorityAdvisorAnalysis(bool NotAsRequested) - : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default), + 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(); - RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); - } - std::unique_ptr - getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { - return std::make_unique( - MF, RA, &getAnalysis().getSI()); + RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); } + 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; }; class DummyPriorityAdvisorAnalysis final - : public RegAllocPriorityAdvisorAnalysis { + : public RegAllocPriorityAdvisorAnalysisLegacy { public: + using RegAllocPriorityAdvisorAnalysisLegacy::AdvisorMode; DummyPriorityAdvisorAnalysis() - : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Dummy) {} + : RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {} // support for isa<> and dyn_cast. - static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { + static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) { return R->getAdvisorMode() == AdvisorMode::Dummy; } private: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); - RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); + RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU); } - std::unique_ptr - getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { - return std::make_unique( - MF, RA, &getAnalysis().getSI()); + bool doInitialization(Module &M) override { + Provider.reset(new DummyPriorityAdvisorProvider()); + return false; } }; } // namespace -template <> Pass *llvm::callDefaultCtor() { +void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) { + if (Provider) + return; + switch (Mode) { + case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: + Provider.reset(new DummyPriorityAdvisorProvider()); + return; + case RegAllocPriorityAdvisorProvider::AdvisorMode::Default: + Provider.reset( + new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/false, Ctx)); + return; + case RegAllocPriorityAdvisorProvider::AdvisorMode::Development: +#if defined(LLVM_HAVE_TFLITE) + Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx)); +#else + Provider.reset( + new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx)); +#endif + return; + case RegAllocPriorityAdvisorProvider::AdvisorMode::Release: + Provider.reset(createReleaseModePriorityAdvisorProvider()); + return; + } +} + +AnalysisKey RegAllocPriorityAdvisorAnalysis::Key; + +RegAllocPriorityAdvisorAnalysis::Result +RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + // Lazily initialize the provider. + initializeProvider(MF.getFunction().getContext()); + // The requiring analysis will construct the advisor. + return Result{Provider.get()}; +} + +template <> +Pass *llvm::callDefaultCtor() { Pass *Ret = nullptr; switch (Mode) { - case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default: - Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false); - break; - case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy: - Ret = new DummyPriorityAdvisorAnalysis(); + 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; + case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy: + Ret = new DummyPriorityAdvisorAnalysis(); 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 96939f89279c6..5bb2e7d0abdd9 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -129,6 +129,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/RegisterCoalescerPass.h"