@@ -115,7 +115,7 @@ bool RegAllocSegmentTree::runOnMachineFunction(MachineFunction &MF) {
115115 // 主要的分配循环
116116 bool AllocComplete = false ;
117117 unsigned Round = 0 ;
118- const unsigned MaxRounds = 5 ; // 防止无限循环
118+ const unsigned MaxRounds = 100 ; // 防止无限循环
119119
120120 while (!AllocComplete && Round < MaxRounds) {
121121 LLVM_DEBUG (dbgs () << " Segment Tree Regalloc round " << Round << " :\n " );
@@ -126,6 +126,8 @@ bool RegAllocSegmentTree::runOnMachineFunction(MachineFunction &MF) {
126126
127127 // 尝试分配所有虚拟寄存器
128128 bool HasSpills = false ;
129+ bool HasUnAllocated = false ;
130+
129131 for (LiveInterval *LI : VRegsToAlloc) {
130132 unsigned VirtReg = LI->reg ();
131133 if (VRM->hasPhys (VirtReg)) // 可能已经通过合并分配了
@@ -139,19 +141,22 @@ bool RegAllocSegmentTree::runOnMachineFunction(MachineFunction &MF) {
139141 VRM->assignVirt2Phys (VirtReg, PhysReg);
140142 updateSegmentTreeForInterval (*LI, PhysReg);
141143 } else {
142- // 分配失败,需要溢出
143- HasSpills = true ;
144- spillVirtReg (*LI);
144+ // 尝试溢出
145+ if (LI->isSpillable ()) {
146+ HasSpills = true ;
147+ spillVirtReg (*LI);
148+ } else {
149+ HasUnAllocated = true ;
150+ LLVM_DEBUG (dbgs () << " Virtual register " << VirtReg
151+ << " cannot be spilled or allocated\n " );
152+ }
145153 }
146154 }
147155
148- // 如果没有溢出,分配完成
149- if (!HasSpills) {
150- AllocComplete = true ;
151- } else {
152- // 处理溢出后,可能需要重新计算LiveIntervals并重新分配
153- // 这里需要实现溢出后的处理逻辑
154-
156+ // 检查是否完成分配
157+ AllocComplete = !HasSpills && !HasUnAllocated;
158+
159+ if (!AllocComplete) {
155160 // 重新收集需要分配的虚拟寄存器
156161 VRegsToAlloc.clear ();
157162 for (unsigned i = 0 , e = MF.getRegInfo ().getNumVirtRegs (); i != e; ++i) {
@@ -161,13 +166,17 @@ bool RegAllocSegmentTree::runOnMachineFunction(MachineFunction &MF) {
161166 LiveInterval *LI = &LIS->getInterval (Reg);
162167 if (LI->empty ())
163168 continue ;
164- VRegsToAlloc.push_back (LI);
169+ // 只收集尚未分配的寄存器
170+ if (!VRM->hasPhys (Reg)) {
171+ VRegsToAlloc.push_back (LI);
172+ }
173+ }
174+
175+ // 如果没有需要处理的寄存器,但AllocComplete为false,这是一个错误
176+ if (VRegsToAlloc.empty () && !AllocComplete) {
177+ LLVM_DEBUG (dbgs () << " Warning: No registers to process but allocation not complete\n " );
178+ AllocComplete = true ; // 强制完成
165179 }
166-
167- // 重新排序
168- llvm::sort (VRegsToAlloc, [](const LiveInterval *A, const LiveInterval *B) {
169- return A->getSize () > B->getSize ();
170- });
171180 }
172181
173182 ++Round;
@@ -194,12 +203,26 @@ Spiller &RegAllocSegmentTree::spiller() {
194203}
195204
196205void RegAllocSegmentTree::enqueueImpl (const LiveInterval *LI) {
197- // 简单实现:暂时不做任何操作
206+
207+ if (!LI) return ;
208+ unsigned V = LI->reg ();
209+ if (!V) return ;
210+ // 不處理已經空掉或僅 debug 定義的 vreg
211+ if (MF && MF->getRegInfo ().reg_nodbg_empty (V)) return ;
212+
213+ // 只有第一次進佇列會插入成功
214+ if (InQ.insert (V).second ) {
215+ WorkQ.push_back (LI);
216+ LLVM_DEBUG (dbgs () << " enqueue vreg " << V << " (queue size=" << WorkQ.size () << " )\n " );
217+ }
198218}
199219
200220const LiveInterval *RegAllocSegmentTree::dequeue () {
201- // 返回nullptr或简单实现
202- return nullptr ;
221+ if (WorkQ.empty ()) return nullptr ;
222+ const LiveInterval *LI = WorkQ.back ();
223+ WorkQ.pop_back ();
224+ if (LI) InQ.erase (LI->reg ());
225+ return LI;
203226}
204227
205228MCRegister RegAllocSegmentTree::selectOrSplit (const LiveInterval &VirtReg,
@@ -238,13 +261,8 @@ void RegAllocSegmentTree::init(VirtRegMap &vrm, LiveIntervals &lis,
238261
239262 this ->MRI = &MF->getRegInfo ();
240263
241- // 2. 為每個暫存器類別初始化線段樹
242- // 這是一個簡化的示例。實際實現中,您需要遍歷所有可分配的物理暫存器
243- for (unsigned RCId = 0 ; RCId < TRI->getNumRegClasses (); ++RCId) {
244- // 獲取該暫存器類別中的所有物理暫存器
245- // 初始化對應的線段樹...
246- // PhysRegSegmentTrees[RCId].resize(...);
247- }
264+ // 确保保留寄存器信息已冻结
265+ MRI->freezeReservedRegs ();
248266
249267 LLVM_DEBUG (dbgs () << " Initializing Segment Tree Register Allocator with "
250268 << NumPhysRegs << " physical registers\n " );
@@ -319,6 +337,12 @@ unsigned RegAllocSegmentTree::tryAllocateRegister(LiveInterval &VirtReg) {
319337 LLVM_DEBUG (dbgs () << " Skipping physreg 0\n " );
320338 continue ;
321339 }
340+
341+ // 检查该物理寄存器是否是保留寄存器
342+ if (MRI->isReserved (PhysReg)) {
343+ LLVM_DEBUG (dbgs () << " Skipping reserved physreg " << PhysReg << " \n " );
344+ continue ;
345+ }
322346
323347 // 检查该物理寄存器是否在VirtReg的整个生命期内都可用
324348 if (isPhysRegAvailable (PhysReg, VirtReg)) {
@@ -562,114 +586,88 @@ void RegAllocSegmentTree::segtreeBuild(unsigned PhysReg) {
562586}
563587
564588void RegAllocSegmentTree::spillVirtReg (LiveInterval &VirtReg) {
565- assert (MF && LIS && VRM &&
566- " RA pointers must be initialized before spilling " );
589+ assert (MF && LIS && VRM);
590+ LLVM_DEBUG ( dbgs () << " Spilling vreg " << VirtReg. reg () << ' \n ' );
567591
568- LLVM_DEBUG (dbgs () << " Spilling virtual register: " << VirtReg.reg () << ' \n ' );
569-
570- // Create a LiveRangeEdit object for the virtual register
571592 SmallVector<Register, 4 > NewVRegs;
572593 LiveRangeEdit LRE (&VirtReg, NewVRegs, *MF, *LIS, VRM, this , &DeadRemats);
573-
574- // Use the spiller with the LiveRangeEdit object
594+
575595 spiller ().spill (LRE);
576-
577- // 將新生成的虛擬寄存器加入隊列
578- for (Register NewVReg : NewVRegs) {
579- if (!LIS->hasInterval (NewVReg))
580- continue ;
581- LiveInterval &NewLI = LIS->getInterval (NewVReg);
596+
597+ for (Register NV : NewVRegs) {
598+ if (!LIS->hasInterval (NV)) continue ;
599+ LiveInterval &NewLI = LIS->getInterval (NV);
582600 enqueue (&NewLI);
583601 }
584602}
585603
586- void RegAllocSegmentTree::finalizeAlloc (MachineFunction &MF,
587- LiveIntervals &LIS,
588- VirtRegMap &VRM) {
589- // 设置机器寄存器信息指针
590- MRI = &MF.getRegInfo ();
604+ void RegAllocSegmentTree::finalizeAlloc (MachineFunction &MF,
605+ LiveIntervals &LIS,
606+ VirtRegMap &VRM) const {
607+ MachineRegisterInfo &MRI = MF.getRegInfo ();
591608
592- // 处理空区间(没有实际生命期的虚拟寄存器)
593- for (unsigned i = 0 , e = MF.getRegInfo ().getNumVirtRegs (); i != e; ++i) {
594- unsigned Reg = Register::index2VirtReg (i);
595- if (MF.getRegInfo ().reg_nodbg_empty (Reg))
609+ LLVM_DEBUG (dbgs () << " Finalizing allocation - checking all virtual registers\n " );
610+
611+ // 處理所有虛擬寄存器,確保都有分配
612+ for (unsigned I = 0 , E = MRI.getNumVirtRegs (); I != E; ++I) {
613+ Register Reg = Register::index2VirtReg (I);
614+ if (MRI.reg_nodbg_empty (Reg))
615+ continue ;
616+
617+ // 如果已經分配,跳過
618+ if (VRM.hasPhys (Reg))
596619 continue ;
620+
621+ // 強制分配策略
622+ LiveInterval &LI = LIS.getInterval (Reg);
623+ const TargetRegisterClass &RC = *MRI.getRegClass (Reg);
597624
598- LiveInterval *LI = &LIS. getInterval (Reg);
599- if (LI-> empty () && !VRM. hasPhys (Reg)) {
600- // 为空区间分配任意可用的物理寄存器
601- const TargetRegisterClass *RC = MF. getRegInfo (). getRegClass (Reg);
602- if (RC-> getNumRegs () > 0 ) {
603- // 选择第一个可用的物理寄存器
604- MCRegister PhysReg = *RC-> begin ();
605- VRM.assignVirt2Phys (Reg, PhysReg);
606- LLVM_DEBUG ( dbgs () << " Assigned empty interval " << Reg
607- << " to physical register " << PhysReg << " \n " ) ;
625+ LLVM_DEBUG ( dbgs () << " Force-allocating unassigned register "
626+ << printReg (Reg, TRI) << " \n " );
627+
628+ // 尋找第一個可用的物理寄存器
629+ Register PReg = 0 ;
630+ ArrayRef<MCPhysReg> Order = RC. getRawAllocationOrder (MF);
631+ for (MCPhysReg CandidateReg : Order) {
632+ if (CandidateReg != 0 && ! VRM.getRegInfo (). isReserved (CandidateReg)) {
633+ PReg = CandidateReg;
634+ break ;
608635 }
609636 }
637+
638+ // 如果仍然找不到,使用第一個非零寄存器(即使是保留寄存器)
639+ if (PReg == 0 && !Order.empty ()) {
640+ PReg = Order[0 ];
641+ }
642+
643+ if (PReg != 0 ) {
644+ VRM.assignVirt2Phys (Reg, PReg);
645+ LLVM_DEBUG (dbgs () << " Force-assigned " << printReg (Reg, TRI)
646+ << " to " << printReg (PReg, TRI) << " \n " );
647+ } else {
648+ // 這應該永遠不會發生
649+ llvm_unreachable (" Cannot find any physical register for virtual register" );
650+ }
610651 }
611652
612- // 清理线段树数据结构
613- PhysRegSegmentTrees.clear ();
614-
615- // 验证分配结果
653+ // 驗證所有虛擬寄存器都已分配
616654 LLVM_DEBUG ({
617- bool HasErrors = false ;
618-
619- // 检查所有虚拟寄存器是否都已分配
620- for (unsigned i = 0 , e = MF.getRegInfo ().getNumVirtRegs (); i != e; ++i) {
621- unsigned Reg = Register::index2VirtReg (i);
622- if (MF.getRegInfo ().reg_nodbg_empty (Reg))
655+ bool AllAllocated = true ;
656+ for (unsigned I = 0 , E = MRI.getNumVirtRegs (); I != E; ++I) {
657+ Register Reg = Register::index2VirtReg (I);
658+ if (MRI.reg_nodbg_empty (Reg))
623659 continue ;
624660
625- LiveInterval *LI = &LIS.getInterval (Reg);
626- if (!LI->empty () && !VRM.hasPhys (Reg)) {
627- dbgs () << " Error: Virtual register " << Reg
628- << " was not allocated!\n " ;
629- HasErrors = true ;
661+ if (!VRM.hasPhys (Reg)) {
662+ dbgs () << " ERROR: Virtual register " << Reg << " still not allocated!\n " ;
663+ AllAllocated = false ;
630664 }
631665 }
632666
633- // 检查物理寄存器冲突
634- for (unsigned i = 0 , e = MF.getRegInfo ().getNumVirtRegs (); i != e; ++i) {
635- unsigned Reg = Register::index2VirtReg (i);
636- if (!VRM.hasPhys (Reg) || MF.getRegInfo ().reg_nodbg_empty (Reg))
637- continue ;
638-
639- MCRegister PhysReg = VRM.getPhys (Reg);
640- LiveInterval *LI = &LIS.getInterval (Reg);
641-
642- // 检查是否有其他虚拟寄存器分配到同一个物理寄存器
643- for (unsigned j = i + 1 ; j < e; ++j) {
644- unsigned OtherReg = Register::index2VirtReg (j);
645- if (!VRM.hasPhys (OtherReg) || MF.getRegInfo ().reg_nodbg_empty (OtherReg))
646- continue ;
647-
648- if (VRM.getPhys (OtherReg) == PhysReg) {
649- LiveInterval *OtherLI = &LIS.getInterval (OtherReg);
650-
651- // 检查区间是否重叠
652- if (LI->overlaps (*OtherLI)) {
653- dbgs () << " Error: Virtual registers " << Reg << " and " << OtherReg
654- << " both assigned to physical register " << PhysReg
655- << " with overlapping live ranges!\n " ;
656- HasErrors = true ;
657- }
658- }
659- }
660- }
661-
662- if (!HasErrors) {
663- dbgs () << " Segment Tree allocation successfully completed for "
664- << MF.getName () << " \n " ;
665- } else {
666- dbgs () << " Segment Tree allocation completed with errors for "
667- << MF.getName () << " \n " ;
667+ if (AllAllocated) {
668+ dbgs () << " SUCCESS: All virtual registers have been allocated\n " ;
668669 }
669670 });
670-
671- // 重置分配器状态,为下一个函数做准备
672- resetAllocatorState ();
673671}
674672
675673void RegAllocSegmentTree::resetAllocatorState () {
@@ -680,6 +678,9 @@ void RegAllocSegmentTree::resetAllocatorState() {
680678 PRTree.clear ();
681679 DeadRemats.clear ();
682680 FailedVRegs.clear ();
681+
682+ WorkQ.clear ();
683+ InQ.clear ();
683684}
684685
685686void RegAllocSegmentTree::postOptimization (Spiller &VRegSpiller, LiveIntervals &LIS) {
0 commit comments