|
|
|
|
@ -93,6 +93,36 @@ namespace mir
|
|
|
|
|
s_ops[0].GetReg() != l_ops[0].GetReg();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局变量:StoreGlobal 后紧跟 LoadGlobal 同一符号 → 用 MovReg 替代 LoadGlobal
|
|
|
|
|
static bool IsGlobalFwdStoreLoad(const MachineInstr &a, const MachineInstr &b)
|
|
|
|
|
{
|
|
|
|
|
if (a.GetOpcode() != Opcode::StoreGlobal || b.GetOpcode() != Opcode::LoadGlobal)
|
|
|
|
|
return false;
|
|
|
|
|
const auto &a_ops = a.GetOperands();
|
|
|
|
|
const auto &b_ops = b.GetOperands();
|
|
|
|
|
if (a_ops.size() < 2 || b_ops.size() < 2)
|
|
|
|
|
return false;
|
|
|
|
|
if (a_ops[1].GetKind() != Operand::Kind::Symbol ||
|
|
|
|
|
b_ops[1].GetKind() != Operand::Kind::Symbol)
|
|
|
|
|
return false;
|
|
|
|
|
return a_ops[1].GetSymbol() == b_ops[1].GetSymbol();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局变量:LoadGlobal 后紧跟 LoadGlobal 同一符号 → 用 MovReg 替代第二个
|
|
|
|
|
static bool IsGlobalRedundantLoad(const MachineInstr &a, const MachineInstr &b)
|
|
|
|
|
{
|
|
|
|
|
if (a.GetOpcode() != Opcode::LoadGlobal || b.GetOpcode() != Opcode::LoadGlobal)
|
|
|
|
|
return false;
|
|
|
|
|
const auto &a_ops = a.GetOperands();
|
|
|
|
|
const auto &b_ops = b.GetOperands();
|
|
|
|
|
if (a_ops.size() < 2 || b_ops.size() < 2)
|
|
|
|
|
return false;
|
|
|
|
|
if (a_ops[1].GetKind() != Operand::Kind::Symbol ||
|
|
|
|
|
b_ops[1].GetKind() != Operand::Kind::Symbol)
|
|
|
|
|
return false;
|
|
|
|
|
return a_ops[1].GetSymbol() == b_ops[1].GetSymbol();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool TryMergeZeroStores(MachineInstr &first, MachineInstr &second)
|
|
|
|
|
{
|
|
|
|
|
if (first.GetOpcode() != Opcode::StoreStack ||
|
|
|
|
|
@ -212,6 +242,57 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局变量 StoreGlobal → LoadGlobal 同一符号转发
|
|
|
|
|
if (!changed)
|
|
|
|
|
{
|
|
|
|
|
for (auto it = insts.begin(); it != insts.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it->GetOpcode() == Opcode::StoreGlobal)
|
|
|
|
|
{
|
|
|
|
|
auto next = std::next(it);
|
|
|
|
|
if (next != insts.end() && IsGlobalFwdStoreLoad(*it, *next))
|
|
|
|
|
{
|
|
|
|
|
const auto &s_ops = it->GetOperands();
|
|
|
|
|
const auto &l_ops = next->GetOperands();
|
|
|
|
|
// 若已是同一寄存器则直接删除 load,否则用 MovReg 替代
|
|
|
|
|
if (s_ops[0].GetKind() == l_ops[0].GetKind() &&
|
|
|
|
|
s_ops[0].GetKind() == Operand::Kind::Reg &&
|
|
|
|
|
s_ops[0].GetReg() == l_ops[0].GetReg())
|
|
|
|
|
next = insts.erase(next);
|
|
|
|
|
else
|
|
|
|
|
*next = MachineInstr(Opcode::MovReg, {l_ops[0], s_ops[0]});
|
|
|
|
|
changed = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局变量 LoadGlobal → LoadGlobal 同一符号消除
|
|
|
|
|
if (!changed)
|
|
|
|
|
{
|
|
|
|
|
for (auto it = insts.begin(); it != insts.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it->GetOpcode() == Opcode::LoadGlobal)
|
|
|
|
|
{
|
|
|
|
|
auto next = std::next(it);
|
|
|
|
|
if (next != insts.end() && IsGlobalRedundantLoad(*it, *next))
|
|
|
|
|
{
|
|
|
|
|
const auto &first_ops = it->GetOperands();
|
|
|
|
|
const auto &second_ops = next->GetOperands();
|
|
|
|
|
if (first_ops[0].GetKind() == second_ops[0].GetKind() &&
|
|
|
|
|
first_ops[0].GetKind() == Operand::Kind::Reg &&
|
|
|
|
|
first_ops[0].GetReg() == second_ops[0].GetReg())
|
|
|
|
|
next = insts.erase(next);
|
|
|
|
|
else
|
|
|
|
|
*next = MachineInstr(Opcode::MovReg, {second_ops[0], first_ops[0]});
|
|
|
|
|
changed = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分支 fallthrough: 末尾 Br 的目标是紧邻下一个块 → 删除 Br
|
|
|
|
|
if (!insts.empty())
|
|
|
|
|
{
|
|
|
|
|
|