diff --git a/src/ir/passes/Mem2Reg.cpp b/src/ir/passes/Mem2Reg.cpp index 3bfd55f0..ddfb5300 100644 --- a/src/ir/passes/Mem2Reg.cpp +++ b/src/ir/passes/Mem2Reg.cpp @@ -735,7 +735,7 @@ void RunMem2Reg(Module& module) { } // 启发式:如果 PHI 节点数量过多,跳过该函数 - // 阈值:块数×4 + 最小200,随函数规模线性增长 + // 阈值:max(100, block_count * 2),随函数规模线性增长 // 旧阈值 max(50, block_count) 对 many_mat_cal 等含大量 alloca // 的函数过于保守,导致栈变量无法提升为 SSA vreg int block_count = func->GetBlocks().size(); diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index a8c85d5f..94197f53 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -1044,50 +1044,28 @@ namespace mir const std::unordered_map &gp_assignment, int skip_vreg = -1) { - if (!used_scratch.count(14)) - { - bool x14_used = false; - for (int d : du.defs) - { + auto IsPhysRegUsed = [&](int phys) -> bool { + for (int d : du.defs) { if (d == skip_vreg) continue; auto it = gp_assignment.find(d); - if (it != gp_assignment.end() && it->second == 14) - { x14_used = true; break; } + if (it != gp_assignment.end() && GP_ALLOCATABLE[it->second] == phys) + return true; } - if (!x14_used) - { - for (int u2 : du.uses) - { - auto it = gp_assignment.find(u2); - if (it != gp_assignment.end() && it->second == 14) - { x14_used = true; break; } - } + for (int u2 : du.uses) { + auto it = gp_assignment.find(u2); + if (it != gp_assignment.end() && GP_ALLOCATABLE[it->second] == phys) + return true; } - if (!x14_used) - return 14; - } + return false; + }; + + if (!used_scratch.count(14) && !IsPhysRegUsed(14)) + return 14; for (int r : GP_ALLOCATABLE) { if (used_scratch.count(r)) continue; - bool used = false; - for (int d : du.defs) - { - if (d == skip_vreg) continue; - auto it = gp_assignment.find(d); - if (it != gp_assignment.end() && it->second == r) - { used = true; break; } - } - if (!used) - { - for (int u2 : du.uses) - { - auto it = gp_assignment.find(u2); - if (it != gp_assignment.end() && it->second == r) - { used = true; break; } - } - } - if (!used) return r; + if (!IsPhysRegUsed(r)) return r; } return GP_ALLOCATABLE[0]; } @@ -1098,27 +1076,25 @@ namespace mir const std::unordered_map &fp_assignment, int skip_vreg = -1) { - for (int r : FP_ALLOCATABLE) - { - if (used_scratch.count(r)) continue; - bool used = false; - for (int d : du.defs) - { + auto IsPhysRegUsed = [&](int phys) -> bool { + for (int d : du.defs) { if (d == skip_vreg) continue; auto it = fp_assignment.find(d); - if (it != fp_assignment.end() && it->second == r) - { used = true; break; } + if (it != fp_assignment.end() && FP_ALLOCATABLE[it->second] == phys) + return true; } - if (!used) - { - for (int u2 : du.uses) - { - auto it = fp_assignment.find(u2); - if (it != fp_assignment.end() && it->second == r) - { used = true; break; } - } + for (int u2 : du.uses) { + auto it = fp_assignment.find(u2); + if (it != fp_assignment.end() && FP_ALLOCATABLE[it->second] == phys) + return true; } - if (!used) return r; + return false; + }; + + for (int r : FP_ALLOCATABLE) + { + if (used_scratch.count(r)) continue; + if (!IsPhysRegUsed(r)) return r; } return FP_ALLOCATABLE[0]; } @@ -1403,7 +1379,15 @@ namespace mir } } + // 大函数丢弃 move 偏好以保持分配稳定性 + // 条件1: move偏好数量 >100 直接跳过 + // 条件2: vreg数 * move偏好数 > 600 (conv2d: 71*15=1065) + int mv = static_cast(move_preferences.size()); + if (mv > 100 || static_cast(function.GetNumVRegs()) * mv > 600) + move_preferences.clear(); + // 检测并打破 move 偏好循环 + if (!move_preferences.empty()) { std::unordered_set visited; for (auto &pair : move_preferences) @@ -1431,13 +1415,6 @@ namespace mir } } - // 大函数丢弃 move 偏好以保持分配稳定性 - // 条件1: move偏好数量 >100 直接跳过 - // 条件2: vreg数 * move偏好数 > 600 (conv2d: 71*15=1065) - int mv = static_cast(move_preferences.size()); - if (mv > 100 || static_cast(function.GetNumVRegs()) * mv > 600) - move_preferences.clear(); - std::vector gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE); std::vector fp_alloc(FP_ALLOCATABLE, FP_ALLOCATABLE + FP_NUM_ALLOCATABLE);