xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/RegAllocPriorityAdvisor.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- RegAllocPriorityAdvisor.h - live ranges priority advisor -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
10 #define LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
11 
12 #include "llvm/CodeGen/MachineBasicBlock.h"
13 #include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
14 #include "llvm/CodeGen/SlotIndexes.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/Pass.h"
17 
18 namespace llvm {
19 
20 class MachineFunction;
21 class VirtRegMap;
22 class RAGreedy;
23 
24 /// Interface to the priority advisor, which is responsible for prioritizing
25 /// live ranges.
26 class RegAllocPriorityAdvisor {
27 public:
28   RegAllocPriorityAdvisor(const RegAllocPriorityAdvisor &) = delete;
29   RegAllocPriorityAdvisor(RegAllocPriorityAdvisor &&) = delete;
30   virtual ~RegAllocPriorityAdvisor() = default;
31 
32   /// Find the priority value for a live range. A float value is used since ML
33   /// prefers it.
34   virtual unsigned getPriority(const LiveInterval &LI) const = 0;
35 
36   RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA,
37                           SlotIndexes *const Indexes);
38 
39 protected:
40   const RAGreedy &RA;
41   LiveIntervals *const LIS;
42   VirtRegMap *const VRM;
43   MachineRegisterInfo *const MRI;
44   const TargetRegisterInfo *const TRI;
45   const RegisterClassInfo &RegClassInfo;
46   SlotIndexes *const Indexes;
47   const bool RegClassPriorityTrumpsGlobalness;
48   const bool ReverseLocalAssignment;
49 };
50 
51 class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor {
52 public:
DefaultPriorityAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes * const Indexes)53   DefaultPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA,
54                          SlotIndexes *const Indexes)
55       : RegAllocPriorityAdvisor(MF, RA, Indexes) {}
56 
57 private:
58   unsigned getPriority(const LiveInterval &LI) const override;
59 };
60 
61 /// Stupid priority advisor which just enqueues in virtual register number
62 /// order, for debug purposes only.
63 class DummyPriorityAdvisor : public RegAllocPriorityAdvisor {
64 public:
DummyPriorityAdvisor(const MachineFunction & MF,const RAGreedy & RA,SlotIndexes * const Indexes)65   DummyPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA,
66                        SlotIndexes *const Indexes)
67       : RegAllocPriorityAdvisor(MF, RA, Indexes) {}
68 
69 private:
70   unsigned getPriority(const LiveInterval &LI) const override;
71 };
72 
73 /// Common provider for getting the priority advisor and logging rewards.
74 /// Legacy analysis forwards all calls to this provider.
75 /// New analysis serves the provider as the analysis result.
76 /// Expensive setup is done in the constructor, so that the advisor can be
77 /// created quickly for every machine function.
78 /// TODO: Remove once legacy PM support is dropped.
79 class RegAllocPriorityAdvisorProvider {
80 public:
81   enum class AdvisorMode : int { Default, Release, Development, Dummy };
82 
RegAllocPriorityAdvisorProvider(AdvisorMode Mode)83   RegAllocPriorityAdvisorProvider(AdvisorMode Mode) : Mode(Mode) {}
84 
85   virtual ~RegAllocPriorityAdvisorProvider() = default;
86 
logRewardIfNeeded(const MachineFunction & MF,function_ref<float ()> GetReward)87   virtual void logRewardIfNeeded(const MachineFunction &MF,
88                                  function_ref<float()> GetReward) {};
89 
90   virtual std::unique_ptr<RegAllocPriorityAdvisor>
91   getAdvisor(const MachineFunction &MF, const RAGreedy &RA,
92              SlotIndexes &SI) = 0;
93 
getAdvisorMode()94   AdvisorMode getAdvisorMode() const { return Mode; }
95 
96 private:
97   const AdvisorMode Mode;
98 };
99 
100 class RegAllocPriorityAdvisorAnalysis
101     : public AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis> {
102   static AnalysisKey Key;
103   friend AnalysisInfoMixin<RegAllocPriorityAdvisorAnalysis>;
104 
105 public:
106   struct Result {
107     // Owned by this analysis.
108     RegAllocPriorityAdvisorProvider *Provider;
109 
invalidateResult110     bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
111                     MachineFunctionAnalysisManager::Invalidator &Inv) {
112       auto PAC = PA.getChecker<RegAllocPriorityAdvisorAnalysis>();
113       return !PAC.preservedWhenStateless() ||
114              Inv.invalidate<SlotIndexesAnalysis>(MF, PA);
115     }
116   };
117 
118   Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
119 
120 private:
121   void initializeProvider(LLVMContext &Ctx);
122   void initializeMLProvider(RegAllocPriorityAdvisorProvider::AdvisorMode Mode,
123                             LLVMContext &Ctx);
124   std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider;
125 };
126 
127 class RegAllocPriorityAdvisorAnalysisLegacy : public ImmutablePass {
128 public:
129   using AdvisorMode = RegAllocPriorityAdvisorProvider::AdvisorMode;
RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode)130   RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode Mode)
131       : ImmutablePass(ID), Mode(Mode) {};
132   static char ID;
133 
134   /// Get an advisor for the given context (i.e. machine function, etc)
getProvider()135   RegAllocPriorityAdvisorProvider &getProvider() { return *Provider; }
getAdvisorMode()136   AdvisorMode getAdvisorMode() const { return Mode; }
logRewardIfNeeded(const MachineFunction & MF,llvm::function_ref<float ()> GetReward)137   virtual void logRewardIfNeeded(const MachineFunction &MF,
138                                  llvm::function_ref<float()> GetReward) {};
139 
140 protected:
141   // This analysis preserves everything, and subclasses may have additional
142   // requirements.
getAnalysisUsage(AnalysisUsage & AU)143   void getAnalysisUsage(AnalysisUsage &AU) const override {
144     AU.setPreservesAll();
145   }
146 
147   std::unique_ptr<RegAllocPriorityAdvisorProvider> Provider;
148 
149 private:
150   StringRef getPassName() const override;
151   const AdvisorMode Mode;
152 };
153 
154 /// Specialization for the API used by the analysis infrastructure to create
155 /// an instance of the priority advisor.
156 template <> Pass *callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>();
157 
158 RegAllocPriorityAdvisorAnalysisLegacy *
159 createReleaseModePriorityAdvisorAnalysis();
160 
161 RegAllocPriorityAdvisorAnalysisLegacy *
162 createDevelopmentModePriorityAdvisorAnalysis();
163 
164 LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider *
165 createReleaseModePriorityAdvisorProvider();
166 
167 LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocPriorityAdvisorProvider *
168 createDevelopmentModePriorityAdvisorProvider(LLVMContext &Ctx);
169 
170 } // namespace llvm
171 
172 #endif // LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
173