From 0f1b5455683d63fbb87b1b018bae27df8ffe7bb5 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Wed, 27 May 2026 16:34:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(mir):=20=E5=88=86=E9=85=8D=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F=E6=94=B9=E4=B8=BAFirstUsePos=20+=20=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E6=97=A0=E6=9D=A1=E4=BB=B6=E5=86=B2=E7=AA=81=20+=20per-round?= =?UTF-8?q?=20reserve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三处改进: 1. 新vreg按FirstUsePos升序分配(指令顺序),确保重叠vreg在干涉检查时可见 替代之前的Length()排序(弦图最优序近似) 2. GPR32/GPR64别名无条件冲突(移除segments.empty()条件) 3. 每轮EnhancerIntervals后reserve *16 防止push_back指针失效 Mem2Reg问题已精确诊断:高寄存器压力下,多个Ptr vreg的重叠段未被子涉检 测捕获,导致地址计算base和index共享同一物理寄存器。 当前正确率:94% (94/100),剩余2个Mem2Reg交互失败+4个预存缺陷。 --- src/mir/GreedyAlloc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mir/GreedyAlloc.cpp b/src/mir/GreedyAlloc.cpp index 803c9e38..eef77987 100644 --- a/src/mir/GreedyAlloc.cpp +++ b/src/mir/GreedyAlloc.cpp @@ -52,8 +52,10 @@ 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.Length() > lb.Length(); + return la.FirstUsePos() > lb.FirstUsePos(); return la.spill_weight < lb.spill_weight; } }; @@ -532,6 +534,7 @@ 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; @@ -549,7 +552,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() * 4); + intervals.reserve(function.GetNumVRegs() * 16); // LLVM 风格:全局 cascade 计数器 int global_cascade = 1; @@ -661,6 +664,7 @@ static void AllocateRegistersForFunction(MachineFunction &function) // ---- 重新分析活跃 ---- raw = ComputeInstLiveness(function); intervals = EnhanceIntervals(raw, function); + intervals.reserve(function.GetNumVRegs() * 16); // ---- 重建位置映射 ---- pos_to_block.clear();