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 
35 char RegAllocPriorityAdvisorAnalysis::ID = 0;
36 INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority",
37                 "Regalloc priority policy", false, true)
38 
39 namespace {
40 class DefaultPriorityAdvisorAnalysis final
41     : public RegAllocPriorityAdvisorAnalysis {
42 public:
43   DefaultPriorityAdvisorAnalysis(bool NotAsRequested)
44       : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default),
45         NotAsRequested(NotAsRequested) {}
46 
47   // support for isa<> and dyn_cast.
48   static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
49     return R->getAdvisorMode() == AdvisorMode::Default;
50   }
51 
52 private:
53   void getAnalysisUsage(AnalysisUsage &AU) const override {
54     AU.addRequired<SlotIndexes>();
55     RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
56   }
57   std::unique_ptr<RegAllocPriorityAdvisor>
58   getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
59     return std::make_unique<DefaultPriorityAdvisor>(
60         MF, RA, &getAnalysis<SlotIndexes>());
61   }
62   bool doInitialization(Module &M) override {
63     if (NotAsRequested)
64       M.getContext().emitError("Requested regalloc priority advisor analysis "
65                                "could be created. Using default");
66     return RegAllocPriorityAdvisorAnalysis::doInitialization(M);
67   }
68   const bool NotAsRequested;
69 };
70 } // namespace
71 
72 template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
73   Pass *Ret = nullptr;
74   switch (Mode) {
75   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default:
76     Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false);
77     break;
78   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development:
79 #if defined(LLVM_HAVE_TFLITE)
80     Ret = createDevelopmentModePriorityAdvisor();
81 #endif
82     break;
83   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release:
84 #if defined(LLVM_HAVE_TF_AOT_REGALLOCPRIORITYMODEL)
85     Ret = createReleaseModePriorityAdvisor();
86 #endif
87     break;
88   }
89   if (Ret)
90     return Ret;
91   return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true);
92 }
93 
94 StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const {
95   switch (getAdvisorMode()) {
96   case AdvisorMode::Default:
97     return "Default Regalloc Priority Advisor";
98   case AdvisorMode::Release:
99     return "Release mode Regalloc Priority Advisor";
100   case AdvisorMode::Development:
101     return "Development mode Regalloc Priority Advisor";
102   }
103   llvm_unreachable("Unknown advisor kind");
104 }
105 
106 RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
107                                                  const RAGreedy &RA,
108                                                  SlotIndexes *const Indexes)
109     : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
110       MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
111       RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes),
112       RegClassPriorityTrumpsGlobalness(
113           RA.getRegClassPriorityTrumpsGlobalness()),
114       ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
115