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 → 定义指令映射(用于再物化判断)