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