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 @@ -378,6 +378,7 @@ void initializeReachingDefAnalysisPass(PassRegistry&); void initializeReassociateLegacyPassPass(PassRegistry&); void initializeRedundantDbgInstEliminationPass(PassRegistry&); +void initializeRegAllocEvictionAdvisorAnalysisPass(PassRegistry &); void initializeRegAllocFastPass(PassRegistry&); void initializeRegBankSelectPass(PassRegistry&); void initializeRegToMemLegacyPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -139,6 +139,7 @@ ReachingDefAnalysis.cpp RegAllocBase.cpp RegAllocBasic.cpp + RegAllocEvictionAdvisor.cpp RegAllocFast.cpp RegAllocGreedy.cpp RegAllocPBQP.cpp diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h --- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h +++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.h @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Register.h" #include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Pass.h" namespace llvm { @@ -164,6 +165,136 @@ } void LRE_DidCloneVirtReg(Register New, Register Old); }; + +/// Interface to the eviction advisor, which is responsible for making a +/// decision as to which live ranges should be evicted (if any). +class RegAllocEvictionAdvisor { +public: + RegAllocEvictionAdvisor(const RegAllocEvictionAdvisor &) = delete; + RegAllocEvictionAdvisor(RegAllocEvictionAdvisor &&) = delete; + virtual ~RegAllocEvictionAdvisor() = default; + + /// Find a physical register that can be freed by evicting the FixedRegisters, + /// or return NoRegister. The eviction decision is assumed to be correct (i.e. + /// no fixed live ranges are evicted) and profitable. + virtual MCRegister + tryFindEvictionCandidate(LiveInterval &VirtReg, const AllocationOrder &Order, + uint8_t CostPerUseLimit, + const SmallVirtRegSet &FixedRegisters) const = 0; + + /// Find out if we can evict the live ranges occupying the given PhysReg, + /// which is a hint (preferred register) for VirtReg. + virtual bool + canEvictHintInterference(LiveInterval &VirtReg, MCRegister PhysReg, + const SmallVirtRegSet &FixedRegisters) const = 0; + + /// Returns true if the given \p PhysReg is a callee saved register and has + /// not been used for allocation yet. + bool isUnusedCalleeSavedReg(MCRegister PhysReg) const; + +protected: + RegAllocEvictionAdvisor(const MachineFunction &MF, LiveRegMatrix *Matrix, + LiveIntervals *LIS, VirtRegMap *VRM, + const RegisterClassInfo &RegClassInfo, + ExtraRegInfo *ExtraInfo); + + Register canReassign(LiveInterval &VirtReg, Register PrevReg) const; + + const MachineFunction &MF; + LiveRegMatrix *const Matrix; + LiveIntervals *const LIS; + VirtRegMap *const VRM; + MachineRegisterInfo *const MRI; + const TargetRegisterInfo *const TRI; + const RegisterClassInfo &RegClassInfo; + const ArrayRef RegCosts; + ExtraRegInfo *const ExtraInfo; + + /// Run or not the local reassignment heuristic. This information is + /// obtained from the TargetSubtargetInfo. + const bool EnableLocalReassign; + +private: + unsigned NextCascade = 1; +}; + +/// ImmutableAnalysis abstraction for fetching the Eviction Advisor. We model it +/// as an analysis to decouple the user from the implementation insofar as +/// dependencies on other analyses goes. The motivation for it being an +/// immutable pass is twofold: +/// - in the ML implementation case, the evaluator is stateless but (especially +/// in the development mode) expensive to set up. With an immutable pass, we set +/// it up once. +/// - in the 'development' mode ML case, we want to capture the training log +/// during allocation (this is a log of features encountered and decisions +/// made), and then measure a score, potentially a few steps after allocation +/// completes. So we need the properties of an immutable pass to keep the logger +/// state around until we can make that measurement. +/// +/// Because we need to offer additional services in 'development' mode, the +/// implementations of this analysis need to implement RTTI support. +class RegAllocEvictionAdvisorAnalysis : public ImmutablePass { +public: + enum class AdvisorMode : int { Default, Release, Development }; + + RegAllocEvictionAdvisorAnalysis(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, LiveRegMatrix *Matrix, + LiveIntervals *LIS, VirtRegMap *VRM, + const RegisterClassInfo &RegClassInfo, + ExtraRegInfo *ExtraInfo) = 0; + AdvisorMode getAdvisorMode() const { return Mode; } + +private: + // This analysis preserves everything, and subclasses may have additional + // requirements. + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + + StringRef getPassName() const override; + const AdvisorMode Mode; +}; + +/// Specialization for the API used by the analysis infrastructure to create +/// an instance of the eviction advisor. +template <> Pass *callDefaultCtor(); + +// TODO(mtrofin): implement these. +#ifdef LLVM_HAVE_TF_AOT +RegAllocEvictionAdvisorAnalysis *createReleaseModeAdvisor(); +#endif + +#ifdef LLVM_HAVE_TF_API +RegAllocEvictionAdvisorAnalysis *createDevelopmentModeAdvisor(); +#endif + +// TODO: move to RegAllocEvictionAdvisor.cpp when we move implementation +// out of RegAllocGreedy.cpp +class DefaultEvictionAdvisor : public RegAllocEvictionAdvisor { +public: + DefaultEvictionAdvisor(const MachineFunction &MF, LiveRegMatrix *Matrix, + LiveIntervals *LIS, VirtRegMap *VRM, + const RegisterClassInfo &RegClassInfo, + ExtraRegInfo *ExtraInfo) + : RegAllocEvictionAdvisor(MF, Matrix, LIS, VRM, RegClassInfo, ExtraInfo) { + } + +private: + MCRegister tryFindEvictionCandidate(LiveInterval &, const AllocationOrder &, + uint8_t, + const SmallVirtRegSet &) const override; + bool canEvictHintInterference(LiveInterval &, MCRegister, + const SmallVirtRegSet &) const override; + bool canEvictInterferenceBasedOnCost(LiveInterval &, MCRegister, bool, + EvictionCost &, + const SmallVirtRegSet &) const; + bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool) const; +}; } // namespace llvm #endif // LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp @@ -0,0 +1,121 @@ +//===- RegAllocEvictionAdvisor.cpp - eviction advisor ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implementation of the default eviction advisor and of the Analysis pass. +// +//===----------------------------------------------------------------------===// + +#include "RegAllocEvictionAdvisor.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/RegisterClassInfo.h" +#include "llvm/CodeGen/VirtRegMap.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/PassRegistry.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +static cl::opt Mode( + "regalloc-enable-advisor", cl::Hidden, + cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), + cl::desc("Enable regalloc advisor mode"), + cl::values( + clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, + "default", "Default"), + clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, + "release", "precompiled"), + clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, + "development", "for training"))); + +static cl::opt EnableLocalReassignment( + "enable-local-reassign", cl::Hidden, + cl::desc("Local reassignment can yield better allocation decisions, but " + "may be compile time intensive"), + cl::init(false)); + +#define DEBUG_TYPE "regalloc" + +char RegAllocEvictionAdvisorAnalysis::ID = 0; +INITIALIZE_PASS(RegAllocEvictionAdvisorAnalysis, "regalloc-evict", + "Regalloc eviction policy", false, true) + +namespace { +class DefaultEvictionAdvisorAnalysis final + : public RegAllocEvictionAdvisorAnalysis { +public: + DefaultEvictionAdvisorAnalysis(bool NotAsRequested) + : RegAllocEvictionAdvisorAnalysis(AdvisorMode::Default), + NotAsRequested(NotAsRequested) {} + + // support for isa<> and dyn_cast. + static bool classof(const RegAllocEvictionAdvisorAnalysis *R) { + return R->getAdvisorMode() == AdvisorMode::Default; + } + +private: + std::unique_ptr + getAdvisor(const MachineFunction &MF, LiveRegMatrix *Matrix, + LiveIntervals *LIS, VirtRegMap *VRM, + const RegisterClassInfo &RegClassInfo, + ExtraRegInfo *ExtraInfo) override { + return std::make_unique(MF, Matrix, LIS, VRM, + RegClassInfo, ExtraInfo); + } + bool doInitialization(Module &M) override { + if (NotAsRequested) + M.getContext().emitError("Requested regalloc eviction advisor analysis " + "could be created. Using default"); + return RegAllocEvictionAdvisorAnalysis::doInitialization(M); + } + const bool NotAsRequested; +}; +} // namespace + +template <> Pass *llvm::callDefaultCtor() { + Pass *Ret = nullptr; + switch (Mode) { + case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default: + Ret = new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ false); + break; + case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development: + // TODO(mtrofin): add implementation + break; + case RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release: + // TODO(mtrofin): add implementation + break; + } + if (Ret) + return Ret; + return new DefaultEvictionAdvisorAnalysis(/*NotAsRequested*/ true); +} + +StringRef RegAllocEvictionAdvisorAnalysis::getPassName() const { + switch (getAdvisorMode()) { + case AdvisorMode::Default: + return "Default Regalloc Eviction Advisor"; + case AdvisorMode::Release: + return "Release mode Regalloc Eviction Advisor"; + case AdvisorMode::Development: + return "Development mode Regalloc Eviction Advisor"; + } + llvm_unreachable("Unknown advisor kind"); +} + +RegAllocEvictionAdvisor::RegAllocEvictionAdvisor( + const MachineFunction &MF, LiveRegMatrix *Matrix, LiveIntervals *LIS, + VirtRegMap *VRM, const RegisterClassInfo &RegClassInfo, + ExtraRegInfo *ExtraInfo) + : MF(MF), Matrix(Matrix), LIS(LIS), VRM(VRM), MRI(&VRM->getRegInfo()), + TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RegClassInfo), + RegCosts(TRI->getRegisterCosts(MF)), ExtraInfo(ExtraInfo), + EnableLocalReassign(EnableLocalReassignment || + MF.getSubtarget().enableRALocalReassignment( + MF.getTarget().getOptLevel())) {} 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 @@ -112,12 +112,6 @@ "and interference cutoffs of last chance recoloring"), cl::Hidden); -static cl::opt EnableLocalReassignment( - "enable-local-reassign", cl::Hidden, - cl::desc("Local reassignment can yield better allocation decisions, but " - "may be compile time intensive"), - cl::init(false)); - static cl::opt EnableDeferredSpilling( "enable-deferred-spilling", cl::Hidden, cl::desc("Instead of spilling a variable right away, defer the actual " @@ -174,6 +168,7 @@ PQueue Queue; std::unique_ptr VRAI; Optional ExtraInfo; + std::unique_ptr EvictAdvisor; // Enum CutOffStage to keep a track whether the register allocation failed // because of the cutoffs encountered in last chance recoloring. @@ -305,10 +300,6 @@ /// Callee-save register cost, calculated once per machine function. BlockFrequency CSRCost; - /// Run or not the local reassignment heuristic. This information is - /// obtained from the TargetSubtargetInfo. - bool EnableLocalReassign; - /// Enable or not the consideration of the cost of local intervals created /// by a split candidate when choosing the best split candidate. bool EnableAdvancedRASplitCost; @@ -377,13 +368,6 @@ bool calcCompactRegion(GlobalSplitCandidate&); void splitAroundRegion(LiveRangeEdit&, ArrayRef); void calcGapWeights(MCRegister, SmallVectorImpl &); - Register canReassign(LiveInterval &VirtReg, Register PrevReg) const; - bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool) const; - bool canEvictInterferenceBasedOnCost(LiveInterval &, MCRegister, bool, - EvictionCost &, - const SmallVirtRegSet &) const; - bool canEvictHintInterference(LiveInterval &, MCRegister, - const SmallVirtRegSet &) const; bool canEvictInterferenceInRange(const LiveInterval &VirtReg, MCRegister PhysReg, SlotIndex Start, SlotIndex End, EvictionCost &MaxCost) const; @@ -459,8 +443,6 @@ BlockFrequency getBrokenHintFreq(const HintsInfo &, MCRegister); void collectHintInfo(Register, HintsInfo &); - bool isUnusedCalleeSavedReg(MCRegister PhysReg) const; - /// Greedy RA statistic to remark. struct RAGreedyStats { unsigned Reloads = 0; @@ -527,6 +509,7 @@ INITIALIZE_PASS_DEPENDENCY(EdgeBundles) INITIALIZE_PASS_DEPENDENCY(SpillPlacement) INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass) +INITIALIZE_PASS_DEPENDENCY(RegAllocEvictionAdvisorAnalysis) INITIALIZE_PASS_END(RAGreedy, "greedy", "Greedy Register Allocator", false, false) @@ -593,6 +576,7 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -757,7 +741,8 @@ MCRegister PhysHint = Hint.asMCReg(); LLVM_DEBUG(dbgs() << "missed hint " << printReg(PhysHint, TRI) << '\n'); - if (canEvictHintInterference(VirtReg, PhysHint, FixedRegisters)) { + if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint, + FixedRegisters)) { evictInterference(VirtReg, PhysHint, NewVRegs); return PhysHint; } @@ -783,7 +768,8 @@ // Interference eviction //===----------------------------------------------------------------------===// -Register RAGreedy::canReassign(LiveInterval &VirtReg, Register PrevReg) const { +Register RegAllocEvictionAdvisor::canReassign(LiveInterval &VirtReg, + Register PrevReg) const { auto Order = AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix); MCRegister PhysReg; @@ -822,8 +808,9 @@ /// register. /// @param B The live range to be evicted. /// @param BreaksHint True when B is already assigned to its preferred register. -bool RAGreedy::shouldEvict(LiveInterval &A, bool IsHint, - LiveInterval &B, bool BreaksHint) const { +bool DefaultEvictionAdvisor::shouldEvict(LiveInterval &A, bool IsHint, + LiveInterval &B, + bool BreaksHint) const { bool CanSplit = ExtraInfo->getStage(B) < RS_Spill; // Be fairly aggressive about following hints as long as the evictee can be @@ -840,7 +827,7 @@ /// canEvictHintInterference - return true if the interference for VirtReg /// on the PhysReg, which is VirtReg's hint, can be evicted in favor of VirtReg. -bool RAGreedy::canEvictHintInterference( +bool DefaultEvictionAdvisor::canEvictHintInterference( LiveInterval &VirtReg, MCRegister PhysReg, const SmallVirtRegSet &FixedRegisters) const { EvictionCost MaxCost; @@ -858,7 +845,7 @@ /// @param MaxCost Only look for cheaper candidates and update with new cost /// when returning true. /// @returns True when interference can be evicted cheaper than MaxCost. -bool RAGreedy::canEvictInterferenceBasedOnCost( +bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost( LiveInterval &VirtReg, MCRegister PhysReg, bool IsHint, EvictionCost &MaxCost, const SmallVirtRegSet &FixedRegisters) const { // It is only possible to evict virtual register interference. @@ -1074,7 +1061,7 @@ /// Returns true if the given \p PhysReg is a callee saved register and has not /// been used for allocation yet. -bool RAGreedy::isUnusedCalleeSavedReg(MCRegister PhysReg) const { +bool RegAllocEvictionAdvisor::isUnusedCalleeSavedReg(MCRegister PhysReg) const { MCRegister CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg); if (!CSR) return false; @@ -1082,7 +1069,7 @@ return !Matrix->isPhysRegUsed(PhysReg); } -MCRegister RAGreedy::tryFindEvictionCandidate( +MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate( LiveInterval &VirtReg, const AllocationOrder &Order, uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const { // Keep track of the cheapest interference seen so far. @@ -1156,8 +1143,8 @@ NamedRegionTimer T("evict", "Evict", TimerGroupName, TimerGroupDescription, TimePassesIsEnabled); - MCRegister BestPhys = - tryFindEvictionCandidate(VirtReg, Order, CostPerUseLimit, FixedRegisters); + MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate( + VirtReg, Order, CostPerUseLimit, FixedRegisters); if (BestPhys.isValid()) evictInterference(VirtReg, BestPhys, NewVRegs); return BestPhys; @@ -1830,7 +1817,7 @@ unsigned BestCand = NoCand; for (MCPhysReg PhysReg : Order) { assert(PhysReg); - if (IgnoreCSR && isUnusedCalleeSavedReg(PhysReg)) + if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg)) continue; // Discard bad candidates before we run out of interference cache cursors. @@ -2982,8 +2969,8 @@ // When NewVRegs is not empty, we may have made decisions such as evicting // a virtual register, go with the earlier decisions and use the physical // register. - if (CSRCost.getFrequency() && isUnusedCalleeSavedReg(PhysReg) && - NewVRegs.empty()) { + if (CSRCost.getFrequency() && + EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.empty()) { MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg, CostPerUseLimit, NewVRegs); if (CSRReg || !NewVRegs.empty()) @@ -3247,10 +3234,6 @@ TII = MF->getSubtarget().getInstrInfo(); RCI.runOnMachineFunction(mf); - EnableLocalReassign = EnableLocalReassignment || - MF->getSubtarget().enableRALocalReassignment( - MF->getTarget().getOptLevel()); - EnableAdvancedRASplitCost = ConsiderLocalIntervalCost.getNumOccurrences() ? ConsiderLocalIntervalCost @@ -3286,6 +3269,8 @@ SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops)); SE.reset(new SplitEditor(*SA, *AA, *LIS, *VRM, *DomTree, *MBFI, *VRAI)); ExtraInfo.emplace(); + EvictAdvisor = getAnalysis().getAdvisor( + *MF, Matrix, LIS, VRM, RegClassInfo, &*ExtraInfo); IntfCache.init(MF, Matrix->getLiveUnions(), Indexes, LIS, TRI); GlobalCand.resize(32); // This will grow as needed. SetOfBrokenHints.clear(); diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -14,6 +14,7 @@ ; CHECK-NEXT: Scoped NoAlias Alias Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Machine Branch Probability Analysis +; CHECK-NEXT: Default Regalloc Eviction Advisor ; CHECK-NEXT: ModulePass Manager ; CHECK-NEXT: Pre-ISel Intrinsic Lowering ; CHECK-NEXT: FunctionPass Manager diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll --- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -162,6 +162,7 @@ ; GCN-O1-NEXT:Create Garbage Collector Module Metadata ; GCN-O1-NEXT:Machine Branch Probability Analysis ; GCN-O1-NEXT:Register Usage Information Storage +; GCN-O1-NEXT:Default Regalloc Eviction Advisor ; GCN-O1-NEXT: ModulePass Manager ; GCN-O1-NEXT: Pre-ISel Intrinsic Lowering ; GCN-O1-NEXT: AMDGPU Printf lowering @@ -413,6 +414,7 @@ ; GCN-O1-OPTS-NEXT:Create Garbage Collector Module Metadata ; GCN-O1-OPTS-NEXT:Machine Branch Probability Analysis ; GCN-O1-OPTS-NEXT:Register Usage Information Storage +; GCN-O1-OPTS-NEXT:Default Regalloc Eviction Advisor ; GCN-O1-OPTS-NEXT: ModulePass Manager ; GCN-O1-OPTS-NEXT: Pre-ISel Intrinsic Lowering ; GCN-O1-OPTS-NEXT: AMDGPU Printf lowering @@ -697,6 +699,7 @@ ; GCN-O2-NEXT:Create Garbage Collector Module Metadata ; GCN-O2-NEXT:Machine Branch Probability Analysis ; GCN-O2-NEXT:Register Usage Information Storage +; GCN-O2-NEXT:Default Regalloc Eviction Advisor ; GCN-O2-NEXT: ModulePass Manager ; GCN-O2-NEXT: Pre-ISel Intrinsic Lowering ; GCN-O2-NEXT: AMDGPU Printf lowering @@ -983,6 +986,7 @@ ; GCN-O3-NEXT:Create Garbage Collector Module Metadata ; GCN-O3-NEXT:Machine Branch Probability Analysis ; GCN-O3-NEXT:Register Usage Information Storage +; GCN-O3-NEXT:Default Regalloc Eviction Advisor ; GCN-O3-NEXT: ModulePass Manager ; GCN-O3-NEXT: Pre-ISel Intrinsic Lowering ; GCN-O3-NEXT: AMDGPU Printf lowering diff --git a/llvm/test/CodeGen/Generic/llc-start-stop.ll b/llvm/test/CodeGen/Generic/llc-start-stop.ll --- a/llvm/test/CodeGen/Generic/llc-start-stop.ll +++ b/llvm/test/CodeGen/Generic/llc-start-stop.ll @@ -18,7 +18,7 @@ ; START-AFTER-NEXT: Dominator Tree Construction ; RUN: llc < %s -debug-pass=Structure -start-before=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-BEFORE -; START-BEFORE: -machine-branch-prob -domtree +; START-BEFORE: -machine-branch-prob -regalloc-evict -domtree ; START-BEFORE: FunctionPass Manager ; START-BEFORE: Loop Strength Reduction ; START-BEFORE-NEXT: Basic Alias Analysis (stateless AA impl) diff --git a/llvm/test/CodeGen/MLRegalloc/default-eviction-advisor.ll b/llvm/test/CodeGen/MLRegalloc/default-eviction-advisor.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MLRegalloc/default-eviction-advisor.ll @@ -0,0 +1,16 @@ +; Check that, in the absence of dependencies, we emit an error message when +; trying to use ML-driven advisor. +; REQUIRES: !have_tf_aot +; REQUIRES: !have_tf_api +; RUN: not llc -O2 -regalloc-enable-advisor=development < %s 2>&1 | FileCheck %s +; RUN: not llc -O2 -regalloc-enable-advisor=release < %s 2>&1 | FileCheck %s +; RUN: llc -O2 -regalloc-enable-advisor=default < %s 2>&1 | FileCheck %s --check-prefix=DEFAULT + +define void @f2(i64 %lhs, i64 %rhs, i64* %addr) { + %sum = add i64 %lhs, %rhs + store i64 %sum, i64* %addr + ret void +} + +; CHECK: Requested regalloc eviction advisor analysis could be created. Using default +; DEFAULT-NOT: Requested regalloc eviction advisor analysis could be created. Using default diff --git a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll --- a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll +++ b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll @@ -14,6 +14,7 @@ ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Machine Branch Probability Analysis +; CHECK-NEXT: Default Regalloc Eviction Advisor ; CHECK-NEXT: ModulePass Manager ; CHECK-NEXT: Pre-ISel Intrinsic Lowering ; CHECK-NEXT: FunctionPass Manager diff --git a/llvm/test/CodeGen/X86/opt-pipeline.ll b/llvm/test/CodeGen/X86/opt-pipeline.ll --- a/llvm/test/CodeGen/X86/opt-pipeline.ll +++ b/llvm/test/CodeGen/X86/opt-pipeline.ll @@ -22,6 +22,7 @@ ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Machine Branch Probability Analysis +; CHECK-NEXT: Default Regalloc Eviction Advisor ; CHECK-NEXT: ModulePass Manager ; CHECK-NEXT: Pre-ISel Intrinsic Lowering ; CHECK-NEXT: FunctionPass Manager