1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
//===- RegAllocPriorityAdvisor.cpp - live ranges priority advisor ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implementation of the default priority advisor and of the Analysis pass.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/RegAllocPriorityAdvisor.h"
#include "RegAllocGreedy.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
using namespace llvm;
static cl::opt<RegAllocPriorityAdvisorProvider::AdvisorMode> Mode(
"regalloc-enable-priority-advisor", cl::Hidden,
cl::init(RegAllocPriorityAdvisorProvider::AdvisorMode::Default),
cl::desc("Enable regalloc advisor mode"),
cl::values(
clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Default,
"default", "Default"),
clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Release,
"release", "precompiled"),
clEnumValN(RegAllocPriorityAdvisorProvider::AdvisorMode::Development,
"development", "for training"),
clEnumValN(
RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy, "dummy",
"prioritize low virtual register numbers for test and debug")));
char RegAllocPriorityAdvisorAnalysisLegacy::ID = 0;
INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysisLegacy, "regalloc-priority",
"Regalloc priority policy", false, true)
namespace {
class DefaultPriorityAdvisorProvider final
: public RegAllocPriorityAdvisorProvider {
public:
DefaultPriorityAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx)
: RegAllocPriorityAdvisorProvider(AdvisorMode::Default) {
if (NotAsRequested)
Ctx.emitError("Requested regalloc priority advisor analysis "
"could be created. Using default");
}
// support for isa<> and dyn_cast.
static bool classof(const RegAllocPriorityAdvisorProvider *R) {
return R->getAdvisorMode() == AdvisorMode::Default;
}
std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction &MF, const RAGreedy &RA,
SlotIndexes &SI) override {
return std::make_unique<DefaultPriorityAdvisor>(MF, RA, &SI);
}
};
class DummyPriorityAdvisorProvider final
: public RegAllocPriorityAdvisorProvider {
public:
DummyPriorityAdvisorProvider()
: RegAllocPriorityAdvisorProvider(AdvisorMode::Dummy) {}
static bool classof(const RegAllocPriorityAdvisorProvider *R) {
return R->getAdvisorMode() == AdvisorMode::Dummy;
}
std::unique_ptr<RegAllocPriorityAdvisor>
getAdvisor(const MachineFunction &MF, const RAGreedy &RA,
SlotIndexes &SI) override {
return std::make_unique<DummyPriorityAdvisor>(MF, RA, &SI);
}
};
class DefaultPriorityAdvisorAnalysisLegacy final
: public RegAllocPriorityAdvisorAnalysisLegacy {
public:
DefaultPriorityAdvisorAnalysisLegacy(bool NotAsRequested)
: RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Default),
NotAsRequested(NotAsRequested) {}
// support for isa<> and dyn_cast.
static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
return R->getAdvisorMode() == AdvisorMode::Default;
}
private:
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<SlotIndexesWrapperPass>();
RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
}
bool doInitialization(Module &M) override {
Provider.reset(
new DefaultPriorityAdvisorProvider(NotAsRequested, M.getContext()));
return false;
}
const bool NotAsRequested;
};
class DummyPriorityAdvisorAnalysis final
: public RegAllocPriorityAdvisorAnalysisLegacy {
public:
using RegAllocPriorityAdvisorAnalysisLegacy::AdvisorMode;
DummyPriorityAdvisorAnalysis()
: RegAllocPriorityAdvisorAnalysisLegacy(AdvisorMode::Dummy) {}
// support for isa<> and dyn_cast.
static bool classof(const RegAllocPriorityAdvisorAnalysisLegacy *R) {
return R->getAdvisorMode() == AdvisorMode::Dummy;
}
private:
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<SlotIndexesWrapperPass>();
RegAllocPriorityAdvisorAnalysisLegacy::getAnalysisUsage(AU);
}
bool doInitialization(Module &M) override {
Provider.reset(new DummyPriorityAdvisorProvider());
return false;
}
};
} // namespace
void RegAllocPriorityAdvisorAnalysis::initializeProvider(LLVMContext &Ctx) {
if (Provider)
return;
switch (Mode) {
case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy:
Provider.reset(new DummyPriorityAdvisorProvider());
return;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
Provider.reset(
new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/false, Ctx));
return;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
#if defined(LLVM_HAVE_TFLITE)
Provider.reset(createDevelopmentModePriorityAdvisorProvider(Ctx));
#else
Provider.reset(
new DefaultPriorityAdvisorProvider(/*NotAsRequested=*/true, Ctx));
#endif
return;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
Provider.reset(createReleaseModePriorityAdvisorProvider());
return;
}
}
AnalysisKey RegAllocPriorityAdvisorAnalysis::Key;
RegAllocPriorityAdvisorAnalysis::Result
RegAllocPriorityAdvisorAnalysis::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
// Lazily initialize the provider.
initializeProvider(MF.getFunction().getContext());
// The requiring analysis will construct the advisor.
return Result{Provider.get()};
}
template <>
Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysisLegacy>() {
Pass *Ret = nullptr;
switch (Mode) {
case RegAllocPriorityAdvisorProvider::AdvisorMode::Default:
Ret = new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ false);
break;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Development:
#if defined(LLVM_HAVE_TFLITE)
Ret = createDevelopmentModePriorityAdvisorAnalysis();
#endif
break;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Release:
Ret = createReleaseModePriorityAdvisorAnalysis();
break;
case RegAllocPriorityAdvisorProvider::AdvisorMode::Dummy:
Ret = new DummyPriorityAdvisorAnalysis();
break;
}
if (Ret)
return Ret;
return new DefaultPriorityAdvisorAnalysisLegacy(/*NotAsRequested*/ true);
}
StringRef RegAllocPriorityAdvisorAnalysisLegacy::getPassName() const {
switch (getAdvisorMode()) {
case AdvisorMode::Default:
return "Default Regalloc Priority Advisor";
case AdvisorMode::Release:
return "Release mode Regalloc Priority Advisor";
case AdvisorMode::Development:
return "Development mode Regalloc Priority Advisor";
case AdvisorMode::Dummy:
return "Dummy Regalloc Priority Advisor";
}
llvm_unreachable("Unknown advisor kind");
}
RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
const RAGreedy &RA,
SlotIndexes *const Indexes)
: RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
RegClassInfo(RA.getRegClassInfo()), Indexes(Indexes),
RegClassPriorityTrumpsGlobalness(
RA.getRegClassPriorityTrumpsGlobalness()),
ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
|