Skip to content

Commit de01e65

Browse files
committed
feat(codegen): WIP Segment-Tree RA with lazy tree + coord compression
- New allocator: PRCoords + PRTree (range-add / range-max with lazy) - ensureCoordsAndTree(): rebuild-on-new-endpoints + interval replay - isPhysRegAvailable(): alias-aware; queries new tree after ensuring coords - updateSegmentTreeForPhysReg(): writes range add to selected physreg - init/reset: initialize/clear PRCoords/PRTree/PhysRegIntervals - SlotIndexes dependency handled; pipeline runs to completion Known gaps: - Rebuild frequency could be optimized (batch endpoints) - Legacy MaxEnd helpers still present (unused) - More tests for alias-heavy and spill cases Verified: - llc -O2 -regalloc=segtre produces assembly - -debug-only=regallocsegtre shows coherent updates/queries - -verify-machineinstrs passes
1 parent 49397ad commit de01e65

File tree

2 files changed

+253
-54
lines changed

2 files changed

+253
-54
lines changed

llvm/include/llvm/CodeGen/RegAllocSegmentTree.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "llvm/ADT/SmallVector.h"
3030
#include <vector>
3131
#include <memory>
32+
#include <utility>
33+
#include <algorithm>
3234

3335
namespace llvm {
3436

@@ -71,6 +73,8 @@ class RegAllocSegmentTree : public MachineFunctionPass, public RegAllocBase, pri
7173
/// 獲取分析依賴
7274
void getAnalysisUsage(AnalysisUsage &AU) const override {
7375
AU.setPreservesCFG();
76+
AU.addRequired<SlotIndexesWrapperPass>();
77+
AU.addPreserved<SlotIndexesWrapperPass>();
7478
AU.addRequired<LiveIntervalsWrapperPass>();
7579
AU.addPreserved<LiveIntervalsWrapperPass>();
7680
AU.addRequired<LiveStacksWrapperLegacy>();
@@ -120,10 +124,41 @@ class RegAllocSegmentTree : public MachineFunctionPass, public RegAllocBase, pri
120124

121125
std::unique_ptr<Spiller> VRegSpiller; // Add this line
122126

123-
// 改为动态分配或使用其他数据结构
127+
// Legacy demo per-physreg trees (kept for compatibility paths).
124128
SmallVector<std::vector<SegmentTreeNode>> PhysRegSegmentTrees;
125129

126-
// 或者,更高效的實現可能使用一個大的線段樹數組,並通過索引來訪問不同暫存器的樹
130+
// Bookkeeping of allocated intervals per physical register (for rebuild).
131+
std::vector<std::vector<std::pair<SlotIndex, SlotIndex>>> PhysRegIntervals;
132+
133+
//===------------------------------------------------------------------===//
134+
// Lazy segment tree (range add / range max) with coordinate compression
135+
//===------------------------------------------------------------------===//
136+
struct SegNode {
137+
int maxCover = 0; // 節點覆蓋區間內的最大覆蓋次數
138+
int lazyAdd = 0; // lazy 累加(尚未下推)
139+
};
140+
141+
// 每個 PhysReg 的座標壓縮點(遞增),點數 m → 段數 m-1
142+
std::vector<std::vector<SlotIndex>> PRCoords;
143+
144+
// 每個 PhysReg 的 lazy 線段樹
145+
std::vector<std::vector<SegNode>> PRTree;
146+
147+
// —— 內部工具 —— //
148+
// 確保 PR 的座標包含 [S,E) 的端點;必要時重建樹並回放既有區間
149+
void ensureCoordsAndTree(unsigned PhysReg, SlotIndex S, SlotIndex E);
150+
// 把 SlotIndex 映射成座標索引(必須已存在於 PRCoords[PR])
151+
unsigned coordIndex(unsigned PhysReg, SlotIndex X) const;
152+
153+
// 線段樹操作
154+
void segtreeBuild(unsigned PhysReg);
155+
void segtreeUpdate(unsigned PhysReg, unsigned idx, unsigned L, unsigned R,
156+
unsigned ql, unsigned qr, int add);
157+
int segtreeQueryMax(unsigned PhysReg, unsigned idx, unsigned L, unsigned R,
158+
unsigned ql, unsigned qr);
159+
160+
// 可放檢查(含別名):任一段 maxCover>0 就不可放
161+
bool canPlaceOnPhysReg(unsigned PhysReg, const LiveInterval &LI) const;
127162

128163
// 线段树构建辅助函数(递归)
129164
void buildSegmentTree(SegmentTreeNode *tree, unsigned idx,

0 commit comments

Comments
 (0)