Skip to content

Commit 5133080

Browse files
committed
[RegAlloc] Add interval-set based register allocator skeleton
This adds a prototype pass `-regalloc=intervals`, which uses IntervalSet instead of SegmentTree. Currently only handles trivial cases.
1 parent 002d28f commit 5133080

File tree

9 files changed

+1271
-150
lines changed

9 files changed

+1271
-150
lines changed

llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace {
3434
(void) llvm::createBasicRegisterAllocator();
3535
(void) llvm::createGreedyRegisterAllocator();
3636
(void) llvm::createDefaultPBQPRegisterAllocator();
37-
// 強制把你的 TU 拉進來(引用工廠函式即可)
37+
(void) llvm::createRegAllocIntervals();
3838
(void) llvm::createRegAllocSegmentTree();
3939

4040
(void)llvm::createBURRListDAGScheduler(nullptr,

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ LLVM_ABI FunctionPass *createGreedyRegisterAllocator(RegAllocFilterFunc F);
236236
///
237237
LLVM_ABI FunctionPass *createDefaultPBQPRegisterAllocator();
238238

239+
LLVM_ABI FunctionPass *createRegAllocIntervals();
240+
239241
// 在 Passes.h 中找到其他寄存器分配器的声明,并在附近添加:
240242
LLVM_ABI FunctionPass *createRegAllocSegmentTree();
241243

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#ifndef LLVM_CODEGEN_REGALLOCINTERVALS_H
2+
#define LLVM_CODEGEN_REGALLOCINTERVALS_H
3+
4+
#include "RegAllocBase.h"
5+
#include "llvm/CodeGen/MachineFunctionPass.h"
6+
#include "llvm/CodeGen/LiveIntervals.h"
7+
#include "llvm/CodeGen/LiveRegMatrix.h"
8+
#include "llvm/CodeGen/VirtRegMap.h"
9+
#include "llvm/CodeGen/Spiller.h"
10+
#include "llvm/Pass.h"
11+
#include "llvm/ADT/DenseMap.h"
12+
#include <map>
13+
#include <queue>
14+
15+
namespace llvm {
16+
17+
class Spiller;
18+
19+
/// 簡單的 [L,R) 區間集合(互斥、合併)
20+
struct IntervalSet {
21+
std::map<SlotIndex, SlotIndex> S;
22+
23+
// Clear all intervals
24+
void clear() {
25+
S.clear(); // Clear the map that stores intervals
26+
}
27+
28+
bool overlaps(SlotIndex L, SlotIndex R) const {
29+
if (!L.isValid() || !R.isValid() || !(L < R)) return false;
30+
auto it = S.lower_bound(L);
31+
if (it != S.begin()) {
32+
auto pit = std::prev(it);
33+
if (pit->second > L) return true;
34+
}
35+
while (it != S.end() && it->first < R) return true;
36+
return false;
37+
}
38+
39+
void add(SlotIndex L, SlotIndex R) {
40+
if (!L.isValid() || !R.isValid() || !(L < R)) return;
41+
auto it = S.lower_bound(L);
42+
auto newL = L, newR = R;
43+
if (it != S.begin()) {
44+
auto pit = std::prev(it);
45+
if (pit->second >= L) {
46+
newL = std::min(newL, pit->first);
47+
newR = std::max(newR, pit->second);
48+
it = S.erase(pit);
49+
}
50+
}
51+
while (it != S.end() && it->first <= newR) {
52+
newL = std::min(newL, it->first);
53+
newR = std::max(newR, it->second);
54+
it = S.erase(it);
55+
}
56+
S.emplace(newL, newR);
57+
}
58+
};
59+
60+
/// 極簡骨架:用 IntervalSet 思路,暫不做真正分配。
61+
class RegAllocIntervals : public MachineFunctionPass, public RegAllocBase {
62+
public:
63+
static char ID;
64+
RegAllocIntervals();
65+
66+
StringRef getPassName() const override {
67+
return "Interval-set Register Allocator (skeleton)";
68+
}
69+
70+
void getAnalysisUsage(AnalysisUsage &AU) const override;
71+
72+
bool runOnMachineFunction(MachineFunction &MF) override;
73+
74+
// === RegAllocBase 純虛覆寫(最小骨架) ===
75+
Spiller &spiller() override { return *SpillerInstance; }
76+
void enqueueImpl(const LiveInterval *LI) override;
77+
const LiveInterval *dequeue() override;
78+
MCRegister selectOrSplit(const LiveInterval &VirtReg,
79+
SmallVectorImpl<Register> &SplitVRegs) override;
80+
81+
// Add missing method declarations
82+
void allocatePhysRegs();
83+
void handleSpill(Register VirtReg);
84+
unsigned tryEvictOrAllocate(LiveInterval &LI);
85+
unsigned tryAllocateRegister(LiveInterval &LI);
86+
void updatePhysReg(unsigned PhysReg, const LiveInterval &LI);
87+
88+
private:
89+
// Add missing member variables
90+
MachineFunction *MF;
91+
LiveIntervals *LIS;
92+
VirtRegMap *VRM;
93+
MachineRegisterInfo *MRI;
94+
const TargetRegisterInfo *TRI;
95+
std::vector<IntervalSet> RegUnitIntervals; // 以 reg-unit id
96+
97+
// Physical register intervals
98+
std::vector<IntervalSet> PhysRegIntervals;
99+
100+
std::unique_ptr<Spiller> SpillerInstance;
101+
102+
// 最簡的 queue:按 (size, ~vreg) 排
103+
using PQueueTy = std::priority_queue<std::pair<unsigned, unsigned>>;
104+
PQueueTy Q;
105+
106+
// 每個 physreg 一份占用集合(這只是骨架,尚未真正使用)
107+
DenseMap<unsigned, IntervalSet> PRUse;
108+
};
109+
110+
/// 工廠函式給 RegisterRegAlloc 使用
111+
FunctionPass *createRegAllocIntervals();
112+
113+
// Forward declare the initializer function
114+
void initializeRegAllocIntervalsPass(PassRegistry &);
115+
116+
} // end namespace llvm
117+
118+
#endif // LLVM_CODEGEN_REGALLOCINTERVALS_H

0 commit comments

Comments
 (0)