Skip to content

Commit ad8eb85

Browse files
Flpha0830mtrofin
authored andcommitted
[NFC][MLGO] ML Regalloc Priority Advisor
This patch introduces the priority analysis and the priority advisor, the default implementation, and the scaffolding for introducing the other implementations of the advisor. Reviewed By: mtrofin Differential Revision: https://reviews.llvm.org/D131220
1 parent 148116a commit ad8eb85

File tree

5 files changed

+122
-9
lines changed

5 files changed

+122
-9
lines changed

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ add_llvm_component_library(LLVMCodeGen
171171
RegAllocFast.cpp
172172
RegAllocGreedy.cpp
173173
RegAllocPBQP.cpp
174+
RegAllocPriorityAdvisor.cpp
174175
RegAllocScore.cpp
175176
RegisterClassInfo.cpp
176177
RegisterCoalescer.cpp

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,16 +279,28 @@ void RAGreedy::enqueueImpl(const LiveInterval *LI) { enqueue(Queue, LI); }
279279
void RAGreedy::enqueue(PQueue &CurQueue, const LiveInterval *LI) {
280280
// Prioritize live ranges by size, assigning larger ranges first.
281281
// The queue holds (size, reg) pairs.
282-
const unsigned Size = LI->getSize();
283282
const Register Reg = LI->reg();
284283
assert(Reg.isVirtual() && "Can only enqueue virtual registers");
285-
unsigned Prio;
286284

287285
auto Stage = ExtraInfo->getOrInitStage(Reg);
288286
if (Stage == RS_New) {
289287
Stage = RS_Assign;
290288
ExtraInfo->setStage(Reg, Stage);
291289
}
290+
291+
unsigned Ret = PriorityAdvisor->getPriority(*LI);
292+
293+
// The virtual register number is a tie breaker for same-sized ranges.
294+
// Give lower vreg numbers higher priority to assign them first.
295+
CurQueue.push(std::make_pair(Ret, ~Reg));
296+
}
297+
298+
unsigned DefaultPriorityAdvisor::getPriority(const LiveInterval &LI) const {
299+
const unsigned Size = LI.getSize();
300+
const Register Reg = LI.reg();
301+
unsigned Prio;
302+
LiveRangeStage Stage = RA.getExtraInfo().getStage(LI);
303+
292304
if (Stage == RS_Split) {
293305
// Unsplit ranges that couldn't be allocated immediately are deferred until
294306
// everything else has been allocated.
@@ -309,18 +321,18 @@ void RAGreedy::enqueue(PQueue &CurQueue, const LiveInterval *LI) {
309321
(2 * RegClassInfo.getNumAllocatableRegs(&RC));
310322
unsigned GlobalBit = 0;
311323

312-
if (Stage == RS_Assign && !ForceGlobal && !LI->empty() &&
313-
LIS->intervalIsInOneMBB(*LI)) {
324+
if (Stage == RS_Assign && !ForceGlobal && !LI.empty() &&
325+
LIS->intervalIsInOneMBB(LI)) {
314326
// Allocate original local ranges in linear instruction order. Since they
315327
// are singly defined, this produces optimal coloring in the absence of
316328
// global interference and other constraints.
317329
if (!ReverseLocalAssignment)
318-
Prio = LI->beginIndex().getInstrDistance(Indexes->getLastIndex());
330+
Prio = LI.beginIndex().getInstrDistance(Indexes->getLastIndex());
319331
else {
320332
// Allocating bottom up may allow many short LRGs to be assigned first
321333
// to one of the cheap registers. This could be much faster for very
322334
// large blocks on targets with many physical registers.
323-
Prio = Indexes->getZeroIndex().getInstrDistance(LI->endIndex());
335+
Prio = Indexes->getZeroIndex().getInstrDistance(LI.endIndex());
324336
}
325337
} else {
326338
// Allocate global and split ranges in long->short order. Long ranges that
@@ -341,9 +353,8 @@ void RAGreedy::enqueue(PQueue &CurQueue, const LiveInterval *LI) {
341353
if (VRM->hasKnownPreference(Reg))
342354
Prio |= (1u << 30);
343355
}
344-
// The virtual register number is a tie breaker for same-sized ranges.
345-
// Give lower vreg numbers higher priority to assign them first.
346-
CurQueue.push(std::make_pair(Prio, ~Reg));
356+
357+
return Prio;
347358
}
348359

349360
const LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); }
@@ -2554,6 +2565,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
25542565
ExtraInfo.emplace();
25552566
EvictAdvisor =
25562567
getAnalysis<RegAllocEvictionAdvisorAnalysis>().getAdvisor(*MF, *this);
2568+
PriorityAdvisor = std::make_unique<DefaultPriorityAdvisor>(*MF, *this);
25572569

25582570
VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
25592571
SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, *VRAI));

llvm/lib/CodeGen/RegAllocGreedy.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "InterferenceCache.h"
1616
#include "RegAllocBase.h"
1717
#include "RegAllocEvictionAdvisor.h"
18+
#include "RegAllocPriorityAdvisor.h"
1819
#include "SpillPlacement.h"
1920
#include "SplitKit.h"
2021
#include "llvm/ADT/ArrayRef.h"
@@ -147,6 +148,16 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass,
147148
size_t getQueueSize() const { return Queue.size(); }
148149
// end (interface to eviction advisers)
149150

151+
// Interface to priority advisers
152+
bool getRegClassPriorityTrumpsGlobalness() const {
153+
return RegClassPriorityTrumpsGlobalness;
154+
}
155+
bool getReverseLocalAssignment() const { return ReverseLocalAssignment; }
156+
// FIXME: this is unnecessary once priority advisers are created by an
157+
// analysis pass, which can fetch the SlotIndexes analysis itself.
158+
SlotIndexes *getIndexes() const { return Indexes; }
159+
// end (interface to priority advisers)
160+
150161
private:
151162
// Convenient shortcuts.
152163
using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
@@ -180,6 +191,8 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass,
180191
Optional<ExtraRegInfo> ExtraInfo;
181192
std::unique_ptr<RegAllocEvictionAdvisor> EvictAdvisor;
182193

194+
std::unique_ptr<RegAllocPriorityAdvisor> PriorityAdvisor;
195+
183196
// Enum CutOffStage to keep a track whether the register allocation failed
184197
// because of the cutoffs encountered in last chance recoloring.
185198
// Note: This is used as bitmask. New value should be next power of 2.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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/InitializePasses.h"
18+
#include "llvm/Pass.h"
19+
20+
using namespace llvm;
21+
22+
RegAllocPriorityAdvisor::RegAllocPriorityAdvisor(const MachineFunction &MF,
23+
const RAGreedy &RA)
24+
: RA(RA), LIS(RA.getLiveIntervals()), VRM(RA.getVirtRegMap()),
25+
MRI(&VRM->getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()),
26+
RegClassInfo(RA.getRegClassInfo()), Indexes(RA.getIndexes()),
27+
RegClassPriorityTrumpsGlobalness(
28+
RA.getRegClassPriorityTrumpsGlobalness()),
29+
ReverseLocalAssignment(RA.getReverseLocalAssignment()) {}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===- RegAllocPriorityAdvisor.h - live ranges priority advisor -*- C++ -*-===//
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+
#ifndef LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
10+
#define LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H
11+
12+
#include "RegAllocEvictionAdvisor.h"
13+
#include "llvm/CodeGen/SlotIndexes.h"
14+
#include "llvm/Pass.h"
15+
16+
namespace llvm {
17+
18+
class MachineFunction;
19+
class VirtRegMap;
20+
class RAGreedy;
21+
22+
/// Interface to the priority advisor, which is responsible for prioritizing
23+
/// live ranges.
24+
class RegAllocPriorityAdvisor {
25+
public:
26+
RegAllocPriorityAdvisor(const RegAllocPriorityAdvisor &) = delete;
27+
RegAllocPriorityAdvisor(RegAllocPriorityAdvisor &&) = delete;
28+
virtual ~RegAllocPriorityAdvisor() = default;
29+
30+
/// Find the priority value for a live range. A float value is used since ML
31+
/// prefers it.
32+
virtual unsigned getPriority(const LiveInterval &LI) const = 0;
33+
34+
RegAllocPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA);
35+
36+
protected:
37+
const RAGreedy &RA;
38+
LiveIntervals *const LIS;
39+
VirtRegMap *const VRM;
40+
MachineRegisterInfo *const MRI;
41+
const TargetRegisterInfo *const TRI;
42+
const RegisterClassInfo &RegClassInfo;
43+
SlotIndexes *const Indexes;
44+
const bool RegClassPriorityTrumpsGlobalness;
45+
const bool ReverseLocalAssignment;
46+
};
47+
48+
class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor {
49+
public:
50+
DefaultPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA)
51+
: RegAllocPriorityAdvisor(MF, RA) {}
52+
53+
private:
54+
unsigned getPriority(const LiveInterval &LI) const override;
55+
};
56+
} // namespace llvm
57+
58+
#endif // LLVM_CODEGEN_REGALLOCPRIORITYADVISOR_H

0 commit comments

Comments
 (0)