|
|
|
|
@ -611,7 +611,8 @@ namespace mir
|
|
|
|
|
static GraphColoringResult ColorGraph(
|
|
|
|
|
InterferenceGraph &graph,
|
|
|
|
|
const std::vector<int> &allocatable_regs,
|
|
|
|
|
MachineFunction & /*function*/)
|
|
|
|
|
MachineFunction & /*function*/,
|
|
|
|
|
const std::unordered_map<int, std::vector<int>> ©_edges = {})
|
|
|
|
|
{
|
|
|
|
|
const int K = static_cast<int>(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<int, std::vector<int>> gp_copy_edges;
|
|
|
|
|
std::unordered_map<int, std::vector<int>> 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<int> gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE);
|
|
|
|
|
std::vector<int> 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<int, std::vector<int>> fp_copy_edges_fb;
|
|
|
|
|
std::unordered_map<int, std::vector<int>> 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<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, 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<int> all_spilled = gp_result.spilled;
|
|
|
|
|
for (int v : fp_result.spilled)
|
|
|
|
|
all_spilled.insert(v);
|
|
|
|
|
|