From d51cbc49f1dfc0292faa05f95b13fbf89d588856 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 01:26:05 +0800 Subject: [PATCH] =?UTF-8?q?perf(mir):=20RegAlloc=20=E5=81=8F=E7=BD=AE?= =?UTF-8?q?=E7=9D=80=E8=89=B2=E8=B0=83=E5=92=8C=EF=BC=88copy=5Fedges=20coa?= =?UTF-8?q?lescing=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 收集 MovReg 两端 vreg 为 copy_edges,逆向着色时优先选源操作数颜色。 减少无意义 MovReg 残留,全用例改善(matmul -3.5%, h-10 -3.5%)。 --- src/mir/RegAlloc.cpp | 92 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 9 deletions(-) diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index 8a99870d..857019c7 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -611,7 +611,8 @@ namespace mir static GraphColoringResult ColorGraph( InterferenceGraph &graph, const std::vector &allocatable_regs, - MachineFunction & /*function*/) + MachineFunction & /*function*/, + const std::unordered_map> ©_edges = {}) { const int K = static_cast(allocatable_regs.size()); GraphColoringResult result; @@ -738,12 +739,35 @@ namespace mir } int assigned_color = -1; - for (int c : allocatable_regs) + + // 偏置着色:优先使用 copy edge 源操作数的颜色 + auto copy_it = copy_edges.find(v); + if (copy_it != copy_edges.end()) { - if (used_colors.find(c) == used_colors.end()) + for (int neighbor : copy_it->second) { - assigned_color = c; - break; + auto nit = colored.find(neighbor); + if (nit != colored.end()) + { + int pref = nit->second; + if (used_colors.find(pref) == used_colors.end()) + { + assigned_color = pref; + break; + } + } + } + } + + if (assigned_color < 0) + { + for (int c : allocatable_regs) + { + if (used_colors.find(c) == used_colors.end()) + { + assigned_color = c; + break; + } } } @@ -991,6 +1015,34 @@ namespace mir { auto block_liveness = ComputeBlockLiveness(function); + // 收集 copy edges (MovReg 连接的 vreg 对) + std::unordered_map> gp_copy_edges; + std::unordered_map> fp_copy_edges; + for (auto &block : function.GetBlocks()) + { + for (auto &inst : block->GetInstructions()) + { + if (inst.GetOpcode() == Opcode::MovReg) + { + const auto &ops = inst.GetOperands(); + if (ops.size() >= 2 && + ops[0].GetKind() == Operand::Kind::VReg && + ops[1].GetKind() == Operand::Kind::VReg) + { + int dst = ops[0].GetVRegId(); + int src = ops[1].GetVRegId(); + if (function.GetVRegClass(dst) == function.GetVRegClass(src)) + { + auto &edges = IsGPClass(function.GetVRegClass(dst)) + ? gp_copy_edges : fp_copy_edges; + edges[dst].push_back(src); + edges[src].push_back(dst); + } + } + } + } + } + std::vector gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE); std::vector fp_alloc(FP_ALLOCATABLE, FP_ALLOCATABLE + FP_NUM_ALLOCATABLE); @@ -998,8 +1050,8 @@ namespace mir BuildInterferenceForGP(function, block_liveness, gp_alloc, gp_graph); BuildInterferenceForFP(function, block_liveness, fp_alloc, fp_graph); - auto gp_result = ColorGraph(gp_graph, gp_alloc, function); - auto fp_result = ColorGraph(fp_graph, fp_alloc, function); + auto gp_result = ColorGraph(gp_graph, gp_alloc, function, gp_copy_edges); + auto fp_result = ColorGraph(fp_graph, fp_alloc, function, fp_copy_edges); if (gp_result.spilled.empty() && fp_result.spilled.empty()) { @@ -1090,13 +1142,35 @@ namespace mir } auto block_liveness = ComputeBlockLiveness(function); + + // 收集 copy edges + std::unordered_map> fp_copy_edges_fb; + std::unordered_map> gp_copy_edges_fb; + for (auto &block : function.GetBlocks()) + for (auto &inst : block->GetInstructions()) + if (inst.GetOpcode() == Opcode::MovReg) + { + const auto &ops = inst.GetOperands(); + if (ops.size() >= 2 && ops[0].GetKind() == Operand::Kind::VReg && + ops[1].GetKind() == Operand::Kind::VReg) + { + int dst = ops[0].GetVRegId(), src = ops[1].GetVRegId(); + if (function.GetVRegClass(dst) == function.GetVRegClass(src)) + { + auto &e = IsGPClass(function.GetVRegClass(dst)) ? gp_copy_edges_fb : fp_copy_edges_fb; + e[dst].push_back(src); + e[src].push_back(dst); + } + } + } + std::vector gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE); std::vector fp_alloc(FP_ALLOCATABLE, FP_ALLOCATABLE + FP_NUM_ALLOCATABLE); InterferenceGraph gp_graph, fp_graph; BuildInterferenceForGP(function, block_liveness, gp_alloc, gp_graph); BuildInterferenceForFP(function, block_liveness, fp_alloc, fp_graph); - auto gp_result = ColorGraph(gp_graph, gp_alloc, function); - auto fp_result = ColorGraph(fp_graph, fp_alloc, function); + auto gp_result = ColorGraph(gp_graph, gp_alloc, function, gp_copy_edges_fb); + auto fp_result = ColorGraph(fp_graph, fp_alloc, function, fp_copy_edges_fb); std::set all_spilled = gp_result.spilled; for (int v : fp_result.spilled) all_spilled.insert(v);