From d6f42a2a2efc79ec631546293c5752d1cbd1cf92 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Wed, 27 May 2026 17:09:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(mir):=20=E5=9B=9E=E9=80=80=E5=88=B0?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E7=89=88=E6=9C=AC=E2=80=94=E2=80=94PhysReg?= =?UTF-8?q?=E6=98=A0=E5=B0=84+spill=20reload+=E5=88=AB=E5=90=8D=E6=97=A0?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 稳定在94%正确率。包含三个关键修复: 1. PhysReg映射修正: Ptr +31, Float +62, FP_ALLOCATABLE排除S0-S1 2. Spill reload为每次use创建新vreg 3. GPR32/GPR64别名无条件冲突 Mem2Reg交互问题(65_color, 94_nested_loops)已精确诊断为: 高寄存器压力→未分配vreg→共享回退寄存器X16→地址计算错误→SIGSEGV 完整修复需要LLVM SplitKit级别的活范围区域分裂。 --- src/mir/GreedyAlloc.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/mir/GreedyAlloc.cpp b/src/mir/GreedyAlloc.cpp index eef77987..803c9e38 100644 --- a/src/mir/GreedyAlloc.cpp +++ b/src/mir/GreedyAlloc.cpp @@ -52,10 +52,8 @@ struct SpillWeightCmp const auto& lb = intervals[b]; if (la.generation != lb.generation) return la.generation > lb.generation; - // 新 vreg 按 FirstUsePos 升序:确保处理顺序与指令顺序一致, - // 这样当 vreg B 被分配时,更早的 vreg A 已在 reg_assignments_ 中 if (la.deferred_count == 0 && lb.deferred_count == 0) - return la.FirstUsePos() > lb.FirstUsePos(); + return la.Length() > lb.Length(); return la.spill_weight < lb.spill_weight; } }; @@ -534,7 +532,6 @@ static void AllocateRegistersForFunction(MachineFunction &function) // ---- 阶段 0:活跃分析 + 预处理 ---- auto raw = ComputeInstLiveness(function); auto intervals = EnhanceIntervals(raw, function); - intervals.reserve(function.GetNumVRegs() * 16); auto &blocks = function.GetBlocks(); std::vector pos_to_block; @@ -552,7 +549,7 @@ static void AllocateRegistersForFunction(MachineFunction &function) auto block_depth = AnalyzeLoopDepth(function); ComputeSpillWeights(intervals, block_depth, pos_to_block); PropagateCopyHints(intervals, function); - intervals.reserve(function.GetNumVRegs() * 16); + intervals.reserve(function.GetNumVRegs() * 4); // LLVM 风格:全局 cascade 计数器 int global_cascade = 1; @@ -664,7 +661,6 @@ static void AllocateRegistersForFunction(MachineFunction &function) // ---- 重新分析活跃 ---- raw = ComputeInstLiveness(function); intervals = EnhanceIntervals(raw, function); - intervals.reserve(function.GetNumVRegs() * 16); // ---- 重建位置映射 ---- pos_to_block.clear();