You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Peephole.cpp - 保守优化版(仅启用安全规则)
#include "mir/MIR.h"
#include <algorithm>
#include <vector>
#include <cstdint>
namespace mir {
namespace {
// 判断两个地址操作数是否指向同一内存位置(考虑栈槽和物理寄存器)
bool SameAddr(const Operand& a, const Operand& b) {
if (a.GetKind() != b.GetKind()) return false;
if (a.GetKind() == Operand::Kind::PhysReg)
return a.GetPhysReg() == b.GetPhysReg();
if (a.GetKind() == Operand::Kind::FrameIndex)
return a.GetFrameIndex() == b.GetFrameIndex();
return false;
}
// 规则2消除死存储连续两次存储到同一地址删除第一次
// 例如: sw t0, addr; sw t1, addr -> 仅保留第二次存储
bool EliminateDeadStore(std::vector<MachineInstr>& instrs) {
bool changed = false;
for (size_t i = 0; i + 1 < instrs.size(); ) {
auto& inst1 = instrs[i];
auto& inst2 = instrs[i+1];
Opcode op1 = inst1.GetOpcode();
Opcode op2 = inst2.GetOpcode();
bool is_store1 = (op1 == Opcode::Store || op1 == Opcode::StoreFloat);
bool is_store2 = (op2 == Opcode::Store || op2 == Opcode::StoreFloat);
if (is_store1 && is_store2) {
const auto& ops1 = inst1.GetOperands();
const auto& ops2 = inst2.GetOperands();
// 两个存储操作数至少都有两个操作数 [value, addr]
if (ops1.size() >= 2 && ops2.size() >= 2 &&
SameAddr(ops1[1], ops2[1])) {
// 第一次存储被第二次覆盖,删除第一次
instrs.erase(instrs.begin() + i);
changed = true;
continue; // 重新检查当前位置
}
}
++i;
}
return changed;
}
} // anonymous namespace
void RunPeepholeOptimization(MachineFunction& function) {
bool overallChanged = true;
while (overallChanged) {
overallChanged = false;
for (auto& blockPtr : function.GetBlocks()) {
auto& instrs = blockPtr->GetInstructions();
bool changed = false;
// 启用死存储消除
changed |= EliminateDeadStore(instrs);
// changed |= EliminateRedundantStoreLoad(instrs);
if (changed)
overallChanged = true;
}
}
}
} // namespace mir