diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -359,6 +359,7 @@ void initializeRedundantDbgInstEliminationPass(PassRegistry&); void initializeRegAllocEvictionAdvisorAnalysisPass(PassRegistry &); void initializeRegAllocFastPass(PassRegistry&); +void initializeRegAllocPriorityAdvisorAnalysisPass(PassRegistry &); void initializeRegAllocScoringPass(PassRegistry &); void initializeRegBankSelectPass(PassRegistry&); void initializeRegToMemLegacyPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h --- a/llvm/lib/CodeGen/RegAllocGreedy.h +++ b/llvm/lib/CodeGen/RegAllocGreedy.h @@ -148,16 +148,6 @@ size_t getQueueSize() const { return Queue.size(); } // end (interface to eviction advisers) - // Interface to priority advisers - bool getRegClassPriorityTrumpsGlobalness() const { - return RegClassPriorityTrumpsGlobalness; - } - bool getReverseLocalAssignment() const { return ReverseLocalAssignment; } - // FIXME: this is unnecessary once priority advisers are created by an - // analysis pass, which can fetch the SlotIndexes analysis itself. - SlotIndexes *getIndexes() const { return Indexes; } - // end (interface to priority advisers) - private: // Convenient shortcuts. using PQueue = std::priority_queue>; diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -17,6 +17,7 @@ #include "LiveDebugVariables.h" #include "RegAllocBase.h" #include "RegAllocEvictionAdvisor.h" +#include "RegAllocPriorityAdvisor.h" #include "SpillPlacement.h" #include "SplitKit.h" #include "llvm/ADT/ArrayRef.h" @@ -163,6 +164,7 @@ INITIALIZE_PASS_DEPENDENCY(SpillPlacement) INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass) INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysis) +INITIALIZE_PASS_DEPENDENCY(RegAllocPriorityAdvisorAnalysis) INITIALIZE_PASS_END(RAGreedy, "greedy", "Greedy Register Allocator", false, false) @@ -219,6 +221,7 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -2565,7 +2568,9 @@ ExtraInfo.emplace(); EvictAdvisor = getAnalysis().getAdvisor(*MF, *this); - PriorityAdvisor = std::make_unique(*MF, *this); + PriorityAdvisor = getAnalysis().getAdvisor( + *MF, *this, Indexes, RegClassPriorityTrumpsGlobalness, + ReverseLocalAssignment); VRAI = std::make_unique(*MF, *LIS, *VRM, *Loops, *MBFI); SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI)); diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h --- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h +++ b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.h @@ -31,7 +31,10 @@ /// prefers it. virtual unsigned getPriority(const LiveInterval &LI) const = 0; - RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA); + RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes *const Indexes, + const bool RegClassPriorityTrumpsGlobalness, + const bool ReverseLocalAssignment); protected: const RAGreedy &RA; @@ -47,12 +50,54 @@ class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor { public: - DefaultPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA) - : RegAllocPriorityAdvisor(MF, RA) {} + DefaultPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes *const Indexes, + const bool RegClassPriorityTrumpsGlobalness, + const bool ReverseLocalAssignment) + : RegAllocPriorityAdvisor(MF, RA, Indexes, + RegClassPriorityTrumpsGlobalness, + ReverseLocalAssignment) {} private: unsigned getPriority(const LiveInterval &LI) const override; }; + +class RegAllocPriorityAdvisorAnalysis : public ImmutablePass { +public: + enum class AdvisorMode : int { Default, Release, Development }; + + RegAllocPriorityAdvisorAnalysis(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, + SlotIndexes *const Indexes, + const bool RegClassPriorityTrumpsGlobalness, + const bool ReverseLocalAssignment) = 0; + AdvisorMode getAdvisorMode() const { return Mode; } + +protected: + // This analysis preserves everything, and subclasses may have additional + // requirements. + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + +private: + StringRef getPassName() const override; + const AdvisorMode Mode; +}; + +/// Specialization for the API used by the analysis infrastructure to create +/// an instance of the priority advisor. +template <> Pass *callDefaultCtor(); + +RegAllocPriorityAdvisorAnalysis *createReleaseModePriorityAdvisor(); + +RegAllocPriorityAdvisorAnalysis *createDevelopmentModePriorityAdvisor(); + } // namespace llvm #endif // LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp --- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp +++ b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp @@ -14,16 +14,97 @@ #include "RegAllocGreedy.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/VirtRegMap.h" +#include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" using namespace llvm; -RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF, - const RAGreedy &RA) +static cl::opt Mode( + "regalloc-enable-priority-advisor", cl::Hidden, + cl::init(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default), + cl::desc("Enable regalloc advisor mode"), + cl::values( + clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default, + "default", "Default"), + clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release, + "release", "precompiled"), + clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development, + "development", "for training"))); + +char RegAllocPriorityAdvisorAnalysis::ID = 0; +INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority", + "Regalloc priority policy", false, true) + +namespace { +class DefaultPriorityAdvisorAnalysis final + : public RegAllocPriorityAdvisorAnalysis { +public: + DefaultPriorityAdvisorAnalysis(bool NotAsRequested) + : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default), + NotAsRequested(NotAsRequested) {} + + // support for isa<> and dyn_cast. + static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { + return R->getAdvisorMode() == AdvisorMode::Default; + } + +private: + std::unique_ptr + getAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes *const Indexes, + const bool RegClassPriorityTrumpsGlobalness, + const bool ReverseLocalAssignment) override { + return std::make_unique( + MF, RA, Indexes, RegClassPriorityTrumpsGlobalness, + ReverseLocalAssignment); + } + bool doInitialization(Module &M) override { + if (NotAsRequested) + M.getContext().emitError("Requested regalloc priority advisor analysis " + "could be created. Using default"); + return RegAllocPriorityAdvisorAnalysis::doInitialization(M); + } + const bool NotAsRequested; +}; +} // namespace + +template <> Pass *llvm::callDefaultCtor() { + Pass *Ret = nullptr; + switch (Mode) { + case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default: + Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false); + break; + case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development: + // TODO: add implementation + break; + case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release: + // TODO: add implementation + break; + } + if (Ret) + return Ret; + return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true); +} + +StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const { + switch (getAdvisorMode()) { + case AdvisorMode::Default: + return "Default Regalloc Priority Advisor"; + case AdvisorMode::Release: + return "Release mode Regalloc Priority Advisor"; + case AdvisorMode::Development: + return "Development mode Regalloc Priority Advisor"; + } + llvm_unreachable("Unknown advisor kind"); +} + +RegAllocPriorityAdvisor::RegAllocPriorityAdvisor( + const MachineFunction &MF, const RAGreedy &RA, SlotIndexes *const Indexes, + const bool RegClassPriorityTrumpsGlobalness, + const bool ReverseLocalAssignment) : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()), MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()), - RegClassInfo(RA.getRegClassInfo()), Indexes(RA.getIndexes()), - RegClassPriorityTrumpsGlobalness( - RA.getRegClassPriorityTrumpsGlobalness()), - ReverseLocalAssignment(RA.getReverseLocalAssignment()) {} + RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes), + RegClassPriorityTrumpsGlobalness(RegClassPriorityTrumpsGlobalness), + ReverseLocalAssignment(ReverseLocalAssignment) {}