xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1*bdd1243dSDimitry Andric //===- RegAllocPriorityAdvisor.cpp - live ranges priority advisor ---------===//
2*bdd1243dSDimitry Andric //
3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bdd1243dSDimitry Andric //
7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8*bdd1243dSDimitry Andric //
9*bdd1243dSDimitry Andric // Implementation of the default priority advisor and of the Analysis pass.
10*bdd1243dSDimitry Andric //
11*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
12*bdd1243dSDimitry Andric 
13*bdd1243dSDimitry Andric #include "RegAllocPriorityAdvisor.h"
14*bdd1243dSDimitry Andric #include "RegAllocGreedy.h"
15*bdd1243dSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
16*bdd1243dSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
17*bdd1243dSDimitry Andric #include "llvm/IR/Module.h"
18*bdd1243dSDimitry Andric #include "llvm/InitializePasses.h"
19*bdd1243dSDimitry Andric #include "llvm/Pass.h"
20*bdd1243dSDimitry Andric 
21*bdd1243dSDimitry Andric using namespace llvm;
22*bdd1243dSDimitry Andric 
23*bdd1243dSDimitry Andric static cl::opt<RegAllocPriorityAdvisorAnalysis::AdvisorMode> Mode(
24*bdd1243dSDimitry Andric     "regalloc-enable-priority-advisor", cl::Hidden,
25*bdd1243dSDimitry Andric     cl::init(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default),
26*bdd1243dSDimitry Andric     cl::desc("Enable regalloc advisor mode"),
27*bdd1243dSDimitry Andric     cl::values(
28*bdd1243dSDimitry Andric         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default,
29*bdd1243dSDimitry Andric                    "default", "Default"),
30*bdd1243dSDimitry Andric         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release,
31*bdd1243dSDimitry Andric                    "release", "precompiled"),
32*bdd1243dSDimitry Andric         clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development,
33*bdd1243dSDimitry Andric                    "development", "for training")));
34*bdd1243dSDimitry Andric 
35*bdd1243dSDimitry Andric char RegAllocPriorityAdvisorAnalysis::ID = 0;
36*bdd1243dSDimitry Andric INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority",
37*bdd1243dSDimitry Andric                 "Regalloc priority policy", false, true)
38*bdd1243dSDimitry Andric 
39*bdd1243dSDimitry Andric namespace {
40*bdd1243dSDimitry Andric class DefaultPriorityAdvisorAnalysis final
41*bdd1243dSDimitry Andric     : public RegAllocPriorityAdvisorAnalysis {
42*bdd1243dSDimitry Andric public:
43*bdd1243dSDimitry Andric   DefaultPriorityAdvisorAnalysis(bool NotAsRequested)
44*bdd1243dSDimitry Andric       : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Default),
45*bdd1243dSDimitry Andric         NotAsRequested(NotAsRequested) {}
46*bdd1243dSDimitry Andric 
47*bdd1243dSDimitry Andric   // support for isa<> and dyn_cast.
48*bdd1243dSDimitry Andric   static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
49*bdd1243dSDimitry Andric     return R->getAdvisorMode() == AdvisorMode::Default;
50*bdd1243dSDimitry Andric   }
51*bdd1243dSDimitry Andric 
52*bdd1243dSDimitry Andric private:
53*bdd1243dSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
54*bdd1243dSDimitry Andric     AU.addRequired<SlotIndexes>();
55*bdd1243dSDimitry Andric     RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
56*bdd1243dSDimitry Andric   }
57*bdd1243dSDimitry Andric   std::unique_ptr<RegAllocPriorityAdvisor>
58*bdd1243dSDimitry Andric   getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
59*bdd1243dSDimitry Andric     return std::make_unique<DefaultPriorityAdvisor>(
60*bdd1243dSDimitry Andric         MF, RA, &getAnalysis<SlotIndexes>());
61*bdd1243dSDimitry Andric   }
62*bdd1243dSDimitry Andric   bool doInitialization(Module &M) override {
63*bdd1243dSDimitry Andric     if (NotAsRequested)
64*bdd1243dSDimitry Andric       M.getContext().emitError("Requested regalloc priority advisor analysis "
65*bdd1243dSDimitry Andric                                "could be created. Using default");
66*bdd1243dSDimitry Andric     return RegAllocPriorityAdvisorAnalysis::doInitialization(M);
67*bdd1243dSDimitry Andric   }
68*bdd1243dSDimitry Andric   const bool NotAsRequested;
69*bdd1243dSDimitry Andric };
70*bdd1243dSDimitry Andric } // namespace
71*bdd1243dSDimitry Andric 
72*bdd1243dSDimitry Andric template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
73*bdd1243dSDimitry Andric   Pass *Ret = nullptr;
74*bdd1243dSDimitry Andric   switch (Mode) {
75*bdd1243dSDimitry Andric   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default:
76*bdd1243dSDimitry Andric     Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false);
77*bdd1243dSDimitry Andric     break;
78*bdd1243dSDimitry Andric   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development:
79*bdd1243dSDimitry Andric #if defined(LLVM_HAVE_TFLITE)
80*bdd1243dSDimitry Andric     Ret = createDevelopmentModePriorityAdvisor();
81*bdd1243dSDimitry Andric #endif
82*bdd1243dSDimitry Andric     break;
83*bdd1243dSDimitry Andric   case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release:
84*bdd1243dSDimitry Andric #if defined(LLVM_HAVE_TF_AOT_REGALLOCPRIORITYMODEL)
85*bdd1243dSDimitry Andric     Ret = createReleaseModePriorityAdvisor();
86*bdd1243dSDimitry Andric #endif
87*bdd1243dSDimitry Andric     break;
88*bdd1243dSDimitry Andric   }
89*bdd1243dSDimitry Andric   if (Ret)
90*bdd1243dSDimitry Andric     return Ret;
91*bdd1243dSDimitry Andric   return new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ true);
92*bdd1243dSDimitry Andric }
93*bdd1243dSDimitry Andric 
94*bdd1243dSDimitry Andric StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const {
95*bdd1243dSDimitry Andric   switch (getAdvisorMode()) {
96*bdd1243dSDimitry Andric   case AdvisorMode::Default:
97*bdd1243dSDimitry Andric     return "Default Regalloc Priority Advisor";
98*bdd1243dSDimitry Andric   case AdvisorMode::Release:
99*bdd1243dSDimitry Andric     return "Release mode Regalloc Priority Advisor";
100*bdd1243dSDimitry Andric   case AdvisorMode::Development:
101*bdd1243dSDimitry Andric     return "Development mode Regalloc Priority Advisor";
102*bdd1243dSDimitry Andric   }
103*bdd1243dSDimitry Andric   llvm_unreachable("Unknown advisor kind");
104*bdd1243dSDimitry Andric }
105*bdd1243dSDimitry Andric 
106*bdd1243dSDimitry Andric RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
107*bdd1243dSDimitry Andric                                                  const RAGreedy &RA,
108*bdd1243dSDimitry Andric                                                  SlotIndexes *const Indexes)
109*bdd1243dSDimitry Andric     : RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
110*bdd1243dSDimitry Andric       MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
111*bdd1243dSDimitry Andric       RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes),
112*bdd1243dSDimitry Andric       RegClassPriorityTrumpsGlobalness(
113*bdd1243dSDimitry Andric           RA.getRegClassPriorityTrumpsGlobalness()),
114*bdd1243dSDimitry Andric       ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
115