3131#include < memory>
3232#include < utility>
3333#include < algorithm>
34+ #include < queue>
3435
3536namespace llvm {
3637
@@ -40,99 +41,73 @@ class MachineRegisterInfo;
4041class TargetRegisterInfo ;
4142class VirtRegMap ;
4243
43- // / SegmentTreeRegisterAllocator implements a register allocator by leveraging
44- // / a segment tree to efficiently track the availability of physical registers
45- // / across their live ranges.
46- class RegAllocSegmentTree : public MachineFunctionPass , public RegAllocBase , private LiveRangeEdit ::Delegate {
47-
48- // 非常重要的:用於記錄每個物理暫存器當前的分配區間
49- // Key: 物理暫存器編號 (PhysReg)
50- // Value: 一個包含多個(LiveInterval, VirtReg)的列表,表示該物理暫存器上分配了哪些虛擬暫存器及其生命期
51- // 但注意:一個物理暫存器在同一時間只能被一個虛擬暫存器佔用,所以這實際上是一系列不重疊的區間
52- // 我們通常用一個按開始時間排序的區間列表來表示一個物理暫存器的使用情況
53- // 我們將為每個物理暫存器建立一個線段樹
54-
44+ class RegAllocSegmentTree : public MachineFunctionPass ,
45+ public RegAllocBase,
46+ private LiveRangeEdit::Delegate {
5547public:
56- // 线段树节点结构体
57- struct SegmentTreeNode {
58- SlotIndex MaxEnd; // 该节点覆盖区间内的最大结束时间
59-
60- SegmentTreeNode () : MaxEnd(SlotIndex()) {}
61- };
62-
6348 static char ID; // 静态成员声明
6449
6550 RegAllocSegmentTree ();
6651
67- // / 主要的分配接口,繼承自 MachineFunctionPass
52+ // MachineFunctionPass interface
6853 bool runOnMachineFunction (MachineFunction &mf) override ;
69-
70- // / 獲取此分配器的名稱
7154 StringRef getPassName () const override { return " Segment Tree Register Allocator" ; }
7255
7356 // / 獲取分析依賴
74- void getAnalysisUsage (AnalysisUsage &AU) const override {
75- AU.setPreservesCFG ();
76- AU.addRequired <SlotIndexesWrapperPass>();
77- AU.addPreserved <SlotIndexesWrapperPass>();
78- AU.addRequired <LiveIntervalsWrapperPass>();
79- AU.addPreserved <LiveIntervalsWrapperPass>();
80- AU.addRequired <LiveStacksWrapperLegacy>();
81- AU.addPreserved <LiveStacksWrapperLegacy>();
82- AU.addRequired <MachineBlockFrequencyInfoWrapperPass>();
83- AU.addPreserved <MachineBlockFrequencyInfoWrapperPass>();
84- AU.addRequired <MachineDominatorTreeWrapperPass>();
85- AU.addPreserved <MachineDominatorTreeWrapperPass>();
86- AU.addRequired <MachineLoopInfoWrapperPass>();
87- AU.addPreserved <MachineLoopInfoWrapperPass>();
88- AU.addRequired <VirtRegMapWrapperLegacy>();
89- AU.addPreserved <VirtRegMapWrapperLegacy>();
90- AU.addRequired <LiveRegMatrixWrapperLegacy>();
91- AU.addPreserved <LiveRegMatrixWrapperLegacy>();
92- MachineFunctionPass::getAnalysisUsage (AU);
93- }
9457
9558 // 我們需要覆蓋這個方法來初始化我們的自定義數據結構
9659 void init (VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat);
9760
98- // 我們需要覆蓋這個方法來實現主要的分配邏輯
99- void allocatePhysRegs ();
100-
10161 // 你自己的 finalize(宣告)
10262 void finalizeAlloc (MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM) const ;
10363
64+ #ifndef NDEBUG
65+ bool verifyAllocation (MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM);
66+ #endif
67+
10468 // 你堅持要的同名接口(注意:**不要**寫 override)
10569 void postOptimization (Spiller &VRegSpiller, LiveIntervals &LIS);
106- protected:
107- // 必须实现的纯虚函数
108- Spiller &spiller () override ;
109- void enqueueImpl (const LiveInterval *LI) override ;
110- const LiveInterval *dequeue () override ;
111- MCRegister selectOrSplit (const LiveInterval &VirtReg,
112- SmallVectorImpl<Register> &splitLVRs) override ;
11370
11471private:
72+ // Timer group constants
73+ static const char TimerGroupName[];
74+ static const char TimerGroupDescription[];
75+
76+ // Performance statistics
77+ mutable unsigned NumInterferenceChecks = 0 ;
78+ mutable unsigned NumSegTreeUpdates = 0 ;
79+ mutable unsigned NumCoordRebuilds = 0 ;
80+ mutable unsigned NumAllocAttempts = 0 ;
81+ mutable unsigned NumSpills = 0 ;
82+
83+ // Convenient shortcuts.
84+ using PQueue = std::priority_queue<std::pair<unsigned , unsigned >>;
85+ using SmallLISet = SmallSetVector<const LiveInterval *, 4 >;
86+
11587 void resetAllocatorState (); // ← 新增
88+ void precomputeAllCoordinates ();
11689 void performSegmentTreeSpecificOptimizations (LiveIntervals &LIS);
11790 void validatePostOptimizationState (LiveIntervals &LIS);
11891
11992 MachineFunction *MF = nullptr ;
93+
94+ // Shortcuts to some useful interface.
95+ const TargetInstrInfo *TII = nullptr ;
96+
12097 LiveIntervals *LIS = nullptr ;
12198 VirtRegMap *VRM = nullptr ;
12299 LiveRegMatrix *LRM = nullptr ;
123100 MachineRegisterInfo *MRI = nullptr ;
101+ const TargetRegisterInfo *TRI = nullptr ;
124102
125103 RegisterClassInfo RCI;
126104
127- std::unique_ptr<Spiller> VRegSpiller ; // Add this line
105+ std::unique_ptr<Spiller> SpillerInstance ; // Add this line
128106
129107 // 工作佇列與去重集合
130- llvm::SmallVector<const LiveInterval*, 64 > WorkQ ;
108+ llvm::SmallVector<const LiveInterval*, 64 > CurQueue ;
131109 llvm::SmallDenseSet<unsigned , 64 > InQ; // 記 vreg id,避免重複排入
132110
133- // Legacy demo per-physreg trees (kept for compatibility paths).
134- SmallVector<std::vector<SegmentTreeNode>> PhysRegSegmentTrees;
135-
136111 // Bookkeeping of allocated intervals per physical register (for rebuild).
137112 std::vector<std::vector<std::pair<SlotIndex, SlotIndex>>> PhysRegIntervals;
138113
@@ -166,22 +141,6 @@ class RegAllocSegmentTree : public MachineFunctionPass, public RegAllocBase, pri
166141 // 可放檢查(含別名):任一段 maxCover>0 就不可放
167142 bool canPlaceOnPhysReg (unsigned PhysReg, const LiveInterval &LI) const ;
168143
169- // 线段树构建辅助函数(递归)
170- void buildSegmentTree (SegmentTreeNode *tree, unsigned idx,
171- unsigned l, unsigned r,
172- const std::vector<SlotIndex> &ends);
173-
174- // 为物理寄存器构建线段树
175- void buildSegmentTreeForPhysReg (unsigned PhysReg, const std::vector<SlotIndex>& intervals);
176-
177- // 查询物理寄存器在指定区间是否可用
178- bool querySegmentTreeForRange (unsigned PhysReg, SlotIndex Start, SlotIndex End) const ;
179-
180- // 线段树查询辅助函数
181- bool querySegmentTree (const SegmentTreeNode *tree, unsigned idx,
182- unsigned tree_l, unsigned tree_r,
183- SlotIndex query_start, SlotIndex query_end) const ;
184-
185144 // 嘗試為給定的虛擬暫存器分配一個物理暫存器
186145 // 返回分配的物理暫存器,若失敗則返回0
187146 unsigned tryAllocateRegister (LiveInterval &VirtReg);
@@ -197,11 +156,27 @@ class RegAllocSegmentTree : public MachineFunctionPass, public RegAllocBase, pri
197156
198157 // 更新物理寄存器的线段树(分配区间后)
199158 void updateSegmentTreeForPhysReg (unsigned PhysReg, SlotIndex Start, SlotIndex End);
159+
160+ // 清理失败的虚拟寄存器
161+ void cleanupFailedVReg (Register FailedVReg, unsigned Depth,
162+ SmallVectorImpl<Register> &SplitRegs);
163+
164+ // 找到合適的拆分點
165+ SlotIndex findSplitPoint (const LiveInterval &LI);
166+ public:
167+ // RegAllocBase interface
168+ Spiller &spiller () override { return *SpillerInstance; };
169+ void enqueueImpl (const LiveInterval *LI) override ;
170+ const LiveInterval *dequeue () override ;
171+ MCRegister selectOrSplit (const LiveInterval &VirtReg,
172+ SmallVectorImpl<Register> &splitLVRs) override ;
173+
174+ void getAnalysisUsage (AnalysisUsage &AU) const override ;
200175};
201176
202177// 創建SegmentTreeRegisterAllocator實例的函數
203178FunctionPass *createRegAllocSegmentTree ();
204179
205180} // end namespace llvm
206181
207- #endif // LLVM_CODEGEN_REGALLOCSEGMENTTREE_H
182+ #endif // LLVM_CODEGEN_REGALLOCSEGMENTTREE_H
0 commit comments