From 535a3c01229247bc9561f855468c7f7e73a0d8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E7=86=99=E5=93=B2?= Date: Thu, 21 May 2026 00:52:17 +0800 Subject: [PATCH] feat(backend): exclude MovReg use from interference during graph build\n\nWhen building the interference graph, temporarily remove the use\noperand of MovReg instructions from the live set before processing\ndefs. This prevents the source and destination of a move from\ninterfering, enabling them to be assigned the same physical register. --- src/mir/RegAlloc.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index eabae350..653727c2 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -488,6 +488,19 @@ namespace mir { auto du = GetInstDefUse(*it, function); + // MovReg: 暂时从 live 中移除 use 操作数,使 def/use 之间不产生干涉边 + bool is_movreg = (it->GetOpcode() == Opcode::MovReg); + std::vector saved_uses; + if (is_movreg && du.defs.size() == 1 && du.uses.size() == 1) + { + int use_vreg = du.uses[0]; + if (live.count(use_vreg) && IsGPClass(function.GetVRegClass(use_vreg))) + { + live.erase(use_vreg); + saved_uses.push_back(use_vreg); + } + } + for (int d : du.defs) { if (!IsGPClass(function.GetVRegClass(d))) @@ -499,6 +512,9 @@ namespace mir } live.erase(d); } + // 恢复 MovReg 的 use + for (int u : saved_uses) + live.insert(u); for (int u : du.uses) { if (IsGPClass(function.GetVRegClass(u))) @@ -560,6 +576,19 @@ namespace mir { auto du = GetInstDefUse(*it, function); + // MovReg: 暂时从 live 中移除 use 操作数,使 def/use 之间不产生干涉边 + bool is_movreg = (it->GetOpcode() == Opcode::MovReg); + std::vector saved_uses; + if (is_movreg && du.defs.size() == 1 && du.uses.size() == 1) + { + int use_vreg = du.uses[0]; + if (live.count(use_vreg) && function.GetVRegClass(use_vreg) == VRegClass::Float) + { + live.erase(use_vreg); + saved_uses.push_back(use_vreg); + } + } + for (int d : du.defs) { if (function.GetVRegClass(d) != VRegClass::Float) @@ -571,6 +600,9 @@ namespace mir } live.erase(d); } + // 恢复 MovReg 的 use + for (int u : saved_uses) + live.insert(u); for (int u : du.uses) { if (function.GetVRegClass(u) == VRegClass::Float)