LLVM: lib/CodeGen/RegAllocEvictionAdvisor.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

27

28using namespace llvm;

29

31 "regalloc-enable-advisor", cl::Hidden,

33 cl::desc("Enable regalloc advisor mode"),

36 "default", "Default"),

38 "release", "precompiled"),

41 "development", "for training")));

42

45 cl::desc("Local reassignment can yield better allocation decisions, but "

46 "may be compile time intensive"),

48

49namespace llvm {

51 "regalloc-eviction-max-interference-cutoff", cl::Hidden,

52 cl::desc("Number of interferences after which we declare "

53 "an interference unevictable and bail out. This "

54 "is a compilation cost-saving consideration. To "

55 "disable, pass a very large number."),

57}

58

59#define DEBUG_TYPE "regalloc"

60#ifdef LLVM_HAVE_TF_AOT_REGALLOCEVICTMODEL

61#define LLVM_HAVE_TF_AOT

62#endif

63

66 "Regalloc eviction policy", false, true)

67

68namespace {

69class DefaultEvictionAdvisorProvider final

71public:

72 DefaultEvictionAdvisorProvider(bool NotAsRequested, LLVMContext &Ctx)

74 if (NotAsRequested)

75 Ctx.emitError("Requested regalloc eviction advisor analysis "

76 "could not be created. Using default");

77 }

78

79

81 return R->getAdvisorMode() == AdvisorMode::Default;

82 }

83

84 std::unique_ptr

87 return std::make_unique(MF, RA);

88 }

89};

90

91class DefaultEvictionAdvisorAnalysisLegacy final

93public:

94 DefaultEvictionAdvisorAnalysisLegacy(bool NotAsRequested)

96 NotAsRequested(NotAsRequested) {}

97

99 Provider.reset(

100 new DefaultEvictionAdvisorProvider(NotAsRequested, M.getContext()));

101 return false;

102 }

103

104

106 return R->getAdvisorMode() == AdvisorMode::Default;

107 }

108

109private:

110 const bool NotAsRequested;

111};

112}

113

114AnalysisKey RegAllocEvictionAdvisorAnalysis::Key;

115

116void RegAllocEvictionAdvisorAnalysis::initializeProvider(

118 if (Provider)

119 return;

120 switch (Mode) {

122 Provider.reset(

123 new DefaultEvictionAdvisorProvider(false, Ctx));

124 return;

126#if defined(LLVM_HAVE_TFLITE)

128#else

129 Provider.reset(

130 new DefaultEvictionAdvisorProvider(true, Ctx));

131#endif

132 return;

135 return;

136 }

137}

138

142

144 return Result{Provider.get()};

145}

146

147template <>

149 switch (Mode) {

151 return new DefaultEvictionAdvisorAnalysisLegacy(false);

154

155 if (Ret)

156 return Ret;

157 return new DefaultEvictionAdvisorAnalysisLegacy(true);

158 }

160#if defined(LLVM_HAVE_TFLITE)

162#else

163 return new DefaultEvictionAdvisorAnalysisLegacy(true);

164#endif

165 }

167}

168

172 return "Default Regalloc Eviction Advisor";

174 return "Release mode Regalloc Eviction Advisor";

176 return "Development mode Regalloc Eviction Advisor";

177 }

179}

180

184 LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),

185 MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),

188 MF.getSubtarget().enableRALocalReassignment(

189 MF.getTarget().getOptLevel())) {}

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval &A, bool IsHint,

206 bool BreaksHint) const {

207 bool CanSplit = RA.getExtraInfo().getStage(B) < RS_Spill;

208

209

210

211 if (CanSplit && IsHint && !BreaksHint)

212 return true;

213

214 if (A.weight() > B.weight()) {

216 return true;

217 }

218 return false;

219}

220

221

222

223bool DefaultEvictionAdvisor::canEvictHintInterference(

226 EvictionCost MaxCost;

228 return canEvictInterferenceBasedOnCost(VirtReg, PhysReg, true, MaxCost,

229 FixedRegisters);

230}

231

232

233

234

235

236

237

238

239

240

241bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(

244

246 return false;

247

248 bool IsLocal = VirtReg.empty() || LIS->intervalIsInOneMBB(VirtReg);

249

250

251

252

253

254

255

256

257 unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());

258

259 EvictionCost Cost;

260 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

261 LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);

262

265 return false;

266

267

268 for (const LiveInterval *Intf : reverse(Interferences)) {

269 assert(Intf->reg().isVirtual() &&

270 "Only expecting virtual register interference from query");

271

272

273

274

275 if (FixedRegisters.count(Intf->reg()))

276 return false;

277

278

279 if (RA.getExtraInfo().getStage(*Intf) == RS_Done)

280 return false;

281

282

283

284

285

286

287 bool Urgent =

289 (Intf->isSpillable() ||

290 RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <

292 MRI->getRegClass(Intf->reg())));

293

294 unsigned IntfCascade = RA.getExtraInfo().getCascade(Intf->reg());

295 if (Cascade == IntfCascade)

296 return false;

297

298 if (Cascade < IntfCascade) {

299 if (!Urgent)

300 return false;

301

302

303 Cost.BrokenHints += 10 * MRI->getRegClass(Intf->reg())->getCopyCost();

304 }

305

306 bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());

307

308 if (BreaksHint)

309 Cost.BrokenHints += MRI->getRegClass(Intf->reg())->getCopyCost();

310

311 Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());

312

313 if (Cost >= MaxCost)

314 return false;

315 if (Urgent)

316 continue;

317

318 if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))

319 return false;

320

321

322

323 if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf) &&

325 return false;

326 }

327 }

328 }

329 MaxCost = Cost;

330 return true;

331}

332

333MCRegister DefaultEvictionAdvisor::tryFindEvictionCandidate(

335 uint8_t CostPerUseLimit, const SmallVirtRegSet &FixedRegisters) const {

336

337 EvictionCost BestCost;

339 MCRegister BestPhys;

340 auto MaybeOrderLimit = getOrderLimit(VirtReg, Order, CostPerUseLimit);

341 if (!MaybeOrderLimit)

343 unsigned OrderLimit = *MaybeOrderLimit;

344

345

346

347 if (CostPerUseLimit < uint8_t(~0u)) {

350 }

351

353 ++I) {

354 MCRegister PhysReg = *I;

357 !canEvictInterferenceBasedOnCost(VirtReg, PhysReg, false, BestCost,

358 FixedRegisters))

359 continue;

360

361

362 BestPhys = PhysReg;

363

364

365 if (I.isHint())

366 break;

367 }

368 return BestPhys;

369}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

Module.h This file contains the declarations for the Module class.

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))

static cl::opt< bool > EnableLocalReassignment("enable-local-reassign", cl::Hidden, cl::desc("Local reassignment can yield better allocation decisions, but " "may be compile time intensive"), cl::init(false))

SI optimize exec mask operations pre RA

Iterator getOrderLimitEnd(unsigned OrderLimit) const

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

This is an important class for using LLVM in a threaded context.

const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())

LiveInterval - This class represents the liveness of a register, or stack slot.

bool isSpillable() const

isSpillable - Can this interval be spilled?

@ IK_VirtReg

Virtual register interference.

Wrapper class representing physical registers. Should be passed by value.

static constexpr unsigned NoRegister

MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...

Function & getFunction()

Return the LLVM function that this machine code represents.

A Module instance is used to store all the information related to an LLVM module.

Pass interface - Implemented by all 'passes'.

virtual bool doInitialization(Module &)

doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

ImmutableAnalysis abstraction for fetching the Eviction Advisor.

RegAllocEvictionAdvisorAnalysisLegacy(AdvisorMode Mode)

AdvisorMode getAdvisorMode() const

Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM)

Definition RegAllocEvictionAdvisor.cpp:140

Common provider for legacy and new pass managers.

virtual std::unique_ptr< RegAllocEvictionAdvisor > getAdvisor(const MachineFunction &MF, const RAGreedy &RA, MachineBlockFrequencyInfo *MBFI, MachineLoopInfo *Loops)=0

RegAllocEvictionAdvisorProvider(AdvisorMode Mode, LLVMContext &Ctx)

const TargetRegisterInfo *const TRI

std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const

const ArrayRef< uint8_t > RegCosts

MachineRegisterInfo *const MRI

const RegisterClassInfo & RegClassInfo

const MachineFunction & MF

RegAllocEvictionAdvisor(const RegAllocEvictionAdvisor &)=delete

bool canReassign(const LiveInterval &VirtReg, MCRegister FromReg) const

const bool EnableLocalReassign

Run or not the local reassignment heuristic.

bool canAllocatePhysReg(unsigned CostPerUseLimit, MCRegister PhysReg) const

LiveRegMatrix *const Matrix

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

StringRef - Represent a constant reference to a string, i.e.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

ValuesClass values(OptsTy... Options)

Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

SmallSet< Register, 16 > SmallVirtRegSet

RegAllocEvictionAdvisorAnalysisLegacy * createReleaseModeAdvisorAnalysisLegacy()

RegAllocEvictionAdvisorProvider * createDevelopmentModeAdvisorProvider(LLVMContext &Ctx)

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

auto reverse(ContainerTy &&C)

Pass * callDefaultCtor< RegAllocEvictionAdvisorAnalysisLegacy >()

Specialization for the API used by the analysis infrastructure to create an instance of the eviction ...

Definition RegAllocEvictionAdvisor.cpp:148

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

@ RS_Spill

Live range will be spilled. No more splitting will be attempted.

@ RS_Done

There is nothing more we can do to this live range.

cl::opt< unsigned > EvictInterferenceCutoff

LLVM_ATTRIBUTE_RETURNS_NONNULL RegAllocEvictionAdvisorProvider * createReleaseModeAdvisorProvider(LLVMContext &Ctx)

RegAllocEvictionAdvisorAnalysisLegacy * createDevelopmentModeAdvisorAnalysisLegacy()

A special type used by analysis passes to provide an address that identifies that particular analysis...

Cost of evicting interference - used by default advisor, and the eviction chain heuristic in RegAlloc...

unsigned BrokenHints

Total number of broken hints.

float MaxWeight

Maximum spill weight evicted.

void setBrokenHints(unsigned NHints)