// IR Pass 管理:按顺序执行优化遍,支持迭代至不动点 #include "ir/IR.h" #include #include namespace ir { // 前向声明(定义在各 pass 文件中) extern bool RunMem2Reg(Function& func, Context& ctx); extern bool RunConstFold(Function& func, Context& ctx); extern bool RunConstProp(Function& func, Context& ctx); extern bool RunDCE(Function& func); extern bool RunCFGSimplify(Function& func, Context& ctx); extern bool RunCSE(Function& func); // 清理 PHI 节点:修复无效的 incoming 值/块引用,补齐缺失的前驱条目 static void SanitizePhis(Function& func, Context& ctx) { func.RebuildCFG(); auto* entry = func.GetEntry(); if (!entry) return; for (auto& bb : func.GetBlocks()) { // 收集 PHI 节点 std::vector phis; for (auto& inst : bb->GetInstructions()) { if (auto* phi = dynamic_cast(inst.get())) phis.push_back(phi); } if (phis.empty()) continue; auto& preds = bb->GetPredecessors(); Value* undef_val = ctx.GetConstInt(0); for (auto* phi : phis) { // 收集已有的 incoming 块 std::unordered_set existing; for (size_t i = 0; i < phi->GetNumIncoming(); ++i) { existing.insert(phi->GetIncomingBlock(i)); } // 为每个前驱补齐缺失的 incoming(LLVM 要求 PHI 覆盖所有前驱) for (auto* pred : preds) { if (!existing.count(pred)) { phi->AddIncoming(undef_val, pred); } } // 修复无效的 incoming for (size_t i = 0; i < phi->GetNumIncoming(); ++i) { auto* inc_val = phi->GetIncomingValue(i); auto* inc_bb = phi->GetIncomingBlock(i); if (!inc_val || !inc_bb) { phi->SetOperand(i * 2, undef_val); phi->SetOperand(i * 2 + 1, entry); } } } } } void RunPasses(Module& module) { Context& ctx = module.GetContext(); bool changed = true; int iteration = 0; const int kMaxIterations = 10; for (auto& func : module.GetFunctions()) { RunMem2Reg(*func, ctx); } while (changed && iteration < kMaxIterations) { changed = false; ++iteration; for (auto& func : module.GetFunctions()) { changed |= RunConstFold(*func, ctx); changed |= RunConstProp(*func, ctx); changed |= RunCSE(*func); // CFGSimplify 在处理 PHI 节点较多的 CFG 时会导致悬空指针 // 其功能(空块合并 + 不可达块删除)由后续 DCE + SanitizePhis 部分承担 changed |= RunDCE(*func); SanitizePhis(*func, ctx); } } } } // namespace ir