diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index 1dcef14d..eabae350 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -1,6 +1,7 @@ #include "mir/MIR.h" #include +#include #include #include #include @@ -606,7 +607,10 @@ namespace mir InterferenceGraph &graph, const std::vector &allocatable_regs, MachineFunction & /*function*/, - int caller_saved_threshold = 19) + int caller_saved_threshold, + const std::unordered_map &interval_length, + const std::unordered_map &ref_count, + const std::set &rematerializable_vregs) { const int K = static_cast(allocatable_regs.size()); GraphColoringResult result; @@ -687,13 +691,32 @@ namespace mir if (!remaining.empty()) { + // spill cost: len(活跃指令数)*5 + ref(def+use总次数)*15 - degree(干涉度数)*25 + // cost 越小越优先 spill —— 短区间、少引用、高冲突的变量更适合溢出 + // 权重基于经验调节:degree 项主导,len/ref 项作为 tiebreaker + auto GetSpillCost = [&](int v) -> int { + int len = 0; + auto lit = interval_length.find(v); + if (lit != interval_length.end()) len = lit->second; + int ref = 0; + auto rit = ref_count.find(v); + if (rit != ref_count.end()) ref = rit->second; + int d = degree[v]; + // 可再物化变量(MovImm 常量)大幅降权,优先 spill + int cost = len * 5 + ref * 15 - d * 25; + if (rematerializable_vregs.count(v)) + cost -= 100000; + return cost; + }; + int spill_candidate = -1; - int max_degree = -1; + int min_cost = std::numeric_limits::max(); for (int v : remaining) { - if (degree[v] > max_degree) + int cost = GetSpillCost(v); + if (cost < min_cost) { - max_degree = degree[v]; + min_cost = cost; spill_candidate = v; } } @@ -1041,6 +1064,14 @@ namespace mir auto liveness = ComputeBlockLiveness(function); + // 构建可再物化 vreg 集合(MovImm 常量) + std::set rematerializable_vregs; + for (const auto &pair : vreg_def_inst) + { + if (pair.second->IsRematerializable()) + rematerializable_vregs.insert(pair.first); + } + std::vector gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE); std::vector fp_alloc(FP_ALLOCATABLE, FP_ALLOCATABLE + FP_NUM_ALLOCATABLE); @@ -1048,8 +1079,12 @@ namespace mir BuildInterferenceForGP(function, liveness.block_liveness, gp_alloc, gp_graph); BuildInterferenceForFP(function, liveness.block_liveness, fp_alloc, fp_graph); - auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19); - auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16); + auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19, + liveness.interval_length, liveness.ref_count, + rematerializable_vregs); + auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16, + liveness.interval_length, liveness.ref_count, + rematerializable_vregs); if (gp_result.spilled.empty() && fp_result.spilled.empty()) { @@ -1179,13 +1214,26 @@ namespace mir } auto liveness = ComputeBlockLiveness(function); + + // 构建可再物化 vreg 集合 + std::set rematerializable_vregs; + for (const auto &pair : vreg_def_inst) + { + if (pair.second->IsRematerializable()) + rematerializable_vregs.insert(pair.first); + } + 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, liveness.block_liveness, gp_alloc, gp_graph); BuildInterferenceForFP(function, liveness.block_liveness, fp_alloc, fp_graph); - auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19); - auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16); + auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19, + liveness.interval_length, liveness.ref_count, + rematerializable_vregs); + auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16, + liveness.interval_length, liveness.ref_count, + rematerializable_vregs); std::set all_spilled = gp_result.spilled; for (int v : fp_result.spilled) all_spilled.insert(v);