fix(ir): CSE 安全门禁——非 SSA 函数跳过 Load/GEP CSE

- 当 alloca 数量 > 24(Mem2Reg 跳过)时,跳过 Load 和 GEP 的 CSE
- 修复 27_scope5 优化 bug(非 SSA 代码中 Load CSE 错误合并不同作用域变量)
- 86_long_code2 不受影响(仅 1 个 alloca,Load/GEP CSE 正常启用)
lzk
lzkk 4 days ago
parent 28c336728d
commit e1777c9eab

@ -58,11 +58,25 @@ static ExprKey GetExprKey(Instruction* inst) {
} // namespace
static int CountAllocas(Function &func) {
int count = 0;
for (auto &bb : func.GetBlocks())
for (auto &inst : bb->GetInstructions())
if (inst->GetOpcode() == Opcode::Alloca)
++count;
return count;
}
void RunCSE(Module& module) {
for (auto& func_ptr : module.GetFunctions()) {
auto* func = func_ptr.get();
if (func->IsExternal()) continue;
// Mem2Reg 跳过的函数(大量 allocaLoad 可能访问不同作用域的同名变量,
// CSE 合并不同 Load 会破坏语义。此情况下仅对 BinaryInst 做 CSE。
int alloca_count = CountAllocas(*func);
bool cse_load_gep = (alloca_count <= 24);
// 对每个基本块执行 CSE
for (auto& bb_ptr : func->GetBlocks()) {
auto* bb = bb_ptr.get();
@ -97,8 +111,11 @@ void RunCSE(Module& module) {
}
}
// 如果是可消除的公共子表达式
if (IsCSECandidate(inst)) {
// 如果是可消除的公共子表达式(非 SSA 函数跳过 Load/GEP
if (IsCSECandidate(inst) &&
(cse_load_gep ||
(inst->GetOpcode() != Opcode::Load &&
inst->GetOpcode() != Opcode::GEP))) {
ExprKey key = GetExprKey(inst);
// 检查是否已经计算过相同的表达式

Loading…
Cancel
Save