perf(mir): RegAlloc 偏置着色调和(copy_edges coalescing)

收集 MovReg 两端 vreg 为 copy_edges,逆向着色时优先选源操作数颜色。
减少无意义 MovReg 残留,全用例改善(matmul -3.5%, h-10 -3.5%)。
lzk
lzkk 3 days ago
parent 9095cbe0db
commit d51cbc49f1

@ -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>> &copy_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);

Loading…
Cancel
Save