xref: /llvm-project/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp (revision 11e482c4a32be6a315e5bf2ae7599cf10eb84836)
1 //===- RegAllocPriorityAdvisor.cpp - live ranges priority advisor ---------===//
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 // Implementation of the default priority advisor and of the Analysis pass.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RegAllocPriorityAdvisor.h"
14 #include "RegAllocGreedy.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/VirtRegMap.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/Pass.h"
20 
21 using namespace llvm;
22 
23 static cl::opt<RegAllocPriorityAdvisorAnalysis::AdvisorMode> Mode(
24     "regalloc-enable-priority-advisor", cl::Hidden,
25     cl::init(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default),
26     cl::desc("Enable regalloc advisor mode"),
27     cl::values(
28         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default,
29                    "default", "Default"),
30         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release,
31                    "release", "precompiled"),
32         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development,
33                    "development", "for training"),
34         clEnumValN(
35             RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy, "dummy",
36             "prioritize low virtual register numbers for test and debug")));
37 
38 char RegAllocPriorityAdvisorAnalysis::ID = 0;
39 INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority",
40                 "Regalloc priority policy", false, true)
41 
42 namespace {
43 class DefaultPriorityAdvisorAnalysis final
44     : public RegAllocPriorityAdvisorAnalysis {
45 public:
46   DefaultPriorityAdvisorAnalysis(bool NotAsRequested)
47       : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default),
48         NotAsRequested(NotAsRequested) {}
49 
50   // support for isa<> and dyn_cast.
51   static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
52     return R->getAdvisorMode() == AdvisorMode::Default;
53   }
54 
55 private:
56   void getAnalysisUsage(AnalysisUsage &AU) const override {
57     AU.addRequired<SlotIndexesWrapperPass>();
58     RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
59   }
60   std::unique_ptr<RegAllocPriorityAdvisor>
61   getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
62     return std::make_unique<DefaultPriorityAdvisor>(
63         MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI());
64   }
65   bool doInitialization(Module &M) override {
66     if (NotAsRequested)
67       M.getContext().emitError("Requested regalloc priority advisor analysis "
68                                "could be created. Using default");
69     return RegAllocPriorityAdvisorAnalysis::doInitialization(M);
70   }
71   const bool NotAsRequested;
72 };
73 
74 class DummyPriorityAdvisorAnalysis final
75     : public RegAllocPriorityAdvisorAnalysis {
76 public:
77   DummyPriorityAdvisorAnalysis()
78       : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Dummy) {}
79 
80   // support for isa<> and dyn_cast.
81   static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
82     return R->getAdvisorMode() == AdvisorMode::Dummy;
83   }
84 
85 private:
86   void getAnalysisUsage(AnalysisUsage &AU) const override {
87     AU.addRequired<SlotIndexesWrapperPass>();
88     RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
89   }
90 
91   std::unique_ptr<RegAllocPriorityAdvisor>
92   getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
93     return std::make_unique<DummyPriorityAdvisor>(
94         MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI());
95   }
96 };
97 
98 } // namespace
99 
100 template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
101   Pass *Ret = nullptr;
102   switch (Mode) {
103   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default:
104     Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false);
105     break;
106   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy:
107     Ret = new DummyPriorityAdvisorAnalysis();
108     break;
109   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development:
110 #if defined(LLVM_HAVE_TFLITE)
111     Ret = createDevelopmentModePriorityAdvisor();
112 #endif
113     break;
114   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release:
115     Ret = createReleaseModePriorityAdvisor();
116     break;
117   }
118   if (Ret)
119     return Ret;
120   return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true);
121 }
122 
123 StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const {
124   switch (getAdvisorMode()) {
125   case AdvisorMode::Default:
126     return "Default Regalloc Priority Advisor";
127   case AdvisorMode::Release:
128     return "Release mode Regalloc Priority Advisor";
129   case AdvisorMode::Development:
130     return "Development mode Regalloc Priority Advisor";
131   case AdvisorMode::Dummy:
132     return "Dummy Regalloc Priority Advisor";
133   }
134   llvm_unreachable("Unknown advisor kind");
135 }
136 
137 RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
138                                                  const RAGreedy &RA,
139                                                  SlotIndexes *const Indexes)
140     : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
141       MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
142       RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes),
143       RegClassPriorityTrumpsGlobalness(
144           RA.getRegClassPriorityTrumpsGlobalness()),
145       ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
146