From c12b6830b87c7dddafdd8b9ca673ff7a2db87c59 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Tue, 26 May 2026 14:43:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(regalloc):=20MAX=5FSPILL=5FROUNDS=3D1=20+?= =?UTF-8?q?=20=E4=BF=9D=E5=AE=88=E4=BF=AE=E5=A4=8D=E9=98=88=E5=80=BC=2020?= =?UTF-8?q?=E2=86=92200=EF=BC=8C=E4=BF=AE=E5=A4=8D=20spill=20=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:block-level liveness 下多轮 spill 创建的 reload vreg 与保守修复 (block_defs 全干涉)交互,产生错误寄存器分配,导致段错误/输出不匹配。 修复: - MAX_SPILL_ROUNDS 3→1:防止多轮 spill 产生错误 reload vreg - 保守修复阈值 20→200:避免过度干涉导致图着色错误分配 修复用例: - 04_arr_defn3:段错误 → 正确 (14) - 05_arr_defn4:错误输出 → 正确 (21) - 09_BFS:bad_alloc/段错误 → 正确 - 13_LCA、54_hidden_var 等多个预存故障也一并修复 剩余已知问题:84_long_array2(编译超时)、30_many_dimensions(GEP偏移) --- src/mir/RegAlloc.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index dc62affb..a337399b 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -555,7 +555,9 @@ namespace mir } // 保守修复:对包含大量 vreg 定义的 block,强制 def 间全干涉 - // 防止 spill reload vreg 的短活区间导致错误寄存器复用 + // 防止 spill reload vreg 的短活区间导致错误寄存器复用。 + // 阈值从 20 提高到 200——低阈值与 MAX_SPILL_ROUNDS=1 组合在 + // 09_BFS 等函数上导致过度干涉,图着色产生错误分配。 for (size_t bi = 0; bi < blocks.size(); ++bi) { std::set block_defs; @@ -566,7 +568,7 @@ namespace mir if (d >= 0 && IsGPClass(function.GetVRegClass(d))) block_defs.insert(d); } - if (block_defs.size() > 20) + if (block_defs.size() > 200) { for (int u : block_defs) for (int v : block_defs) @@ -1422,10 +1424,12 @@ namespace mir if (function.GetNumVRegs() == 0) return; - // 限制 spill 轮次,防止 spill 代码指数级膨胀。 - // 大函数(>120 vreg)最多 3 轮,普通函数最多 3 轮。 - // 10 轮在 67-vreg 的 mm1 上产生了 11,785 个 spill slot (14→25→48→...→5890) - const int MAX_SPILL_ROUNDS = 3; + // 限制 spill 轮次为 1:block-level liveness 下多轮 spill 创建 + // 的 reload vreg 与保守修复(block_defs 全干涉)交互,产生错误 + // 寄存器分配。1 轮足够——循环外 RewriteWithAllocation 用 scratch + // 寄存器处理所有剩余 spill。修复:04_arr_defn3/05_arr_defn4 段错误 + // 及 09_BFS bad_alloc。 + const int MAX_SPILL_ROUNDS = 1; for (int round = 0; round < MAX_SPILL_ROUNDS; ++round) { // 构建 VReg → 定义指令映射(用于再物化判断)