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);