feat(backend): exclude MovReg use from interference during graph build\n\nWhen building the interference graph, temporarily remove the use\noperand of MovReg instructions from the live set before processing\ndefs. This prevents the source and destination of a move from\ninterfering, enabling them to be assigned the same physical register.

master
黄熙哲 1 week ago
parent 4fad027da8
commit 535a3c0122

@ -488,6 +488,19 @@ namespace mir
{
auto du = GetInstDefUse(*it, function);
// MovReg: 暂时从 live 中移除 use 操作数,使 def/use 之间不产生干涉边
bool is_movreg = (it->GetOpcode() == Opcode::MovReg);
std::vector<int> saved_uses;
if (is_movreg && du.defs.size() == 1 && du.uses.size() == 1)
{
int use_vreg = du.uses[0];
if (live.count(use_vreg) && IsGPClass(function.GetVRegClass(use_vreg)))
{
live.erase(use_vreg);
saved_uses.push_back(use_vreg);
}
}
for (int d : du.defs)
{
if (!IsGPClass(function.GetVRegClass(d)))
@ -499,6 +512,9 @@ namespace mir
}
live.erase(d);
}
// 恢复 MovReg 的 use
for (int u : saved_uses)
live.insert(u);
for (int u : du.uses)
{
if (IsGPClass(function.GetVRegClass(u)))
@ -560,6 +576,19 @@ namespace mir
{
auto du = GetInstDefUse(*it, function);
// MovReg: 暂时从 live 中移除 use 操作数,使 def/use 之间不产生干涉边
bool is_movreg = (it->GetOpcode() == Opcode::MovReg);
std::vector<int> saved_uses;
if (is_movreg && du.defs.size() == 1 && du.uses.size() == 1)
{
int use_vreg = du.uses[0];
if (live.count(use_vreg) && function.GetVRegClass(use_vreg) == VRegClass::Float)
{
live.erase(use_vreg);
saved_uses.push_back(use_vreg);
}
}
for (int d : du.defs)
{
if (function.GetVRegClass(d) != VRegClass::Float)
@ -571,6 +600,9 @@ namespace mir
}
live.erase(d);
}
// 恢复 MovReg 的 use
for (int u : saved_uses)
live.insert(u);
for (int u : du.uses)
{
if (function.GetVRegClass(u) == VRegClass::Float)

Loading…
Cancel
Save