|
|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
#include "mir/MIR.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <limits>
|
|
|
|
|
#include <queue>
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
@ -606,7 +607,10 @@ namespace mir
|
|
|
|
|
InterferenceGraph &graph,
|
|
|
|
|
const std::vector<int> &allocatable_regs,
|
|
|
|
|
MachineFunction & /*function*/,
|
|
|
|
|
int caller_saved_threshold = 19)
|
|
|
|
|
int caller_saved_threshold,
|
|
|
|
|
const std::unordered_map<int, int> &interval_length,
|
|
|
|
|
const std::unordered_map<int, int> &ref_count,
|
|
|
|
|
const std::set<int> &rematerializable_vregs)
|
|
|
|
|
{
|
|
|
|
|
const int K = static_cast<int>(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<int>::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<int> rematerializable_vregs;
|
|
|
|
|
for (const auto &pair : vreg_def_inst)
|
|
|
|
|
{
|
|
|
|
|
if (pair.second->IsRematerializable())
|
|
|
|
|
rematerializable_vregs.insert(pair.first);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<int> gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE);
|
|
|
|
|
std::vector<int> 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<int> rematerializable_vregs;
|
|
|
|
|
for (const auto &pair : vreg_def_inst)
|
|
|
|
|
{
|
|
|
|
|
if (pair.second->IsRematerializable())
|
|
|
|
|
rematerializable_vregs.insert(pair.first);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<int> gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE);
|
|
|
|
|
std::vector<int> 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<int> all_spilled = gp_result.spilled;
|
|
|
|
|
for (int v : fp_result.spilled)
|
|
|
|
|
all_spilled.insert(v);
|
|
|
|
|
|