diff --git a/furc/src/front/ssa.cpp b/furc/src/front/ssa.cpp index 91c817d..155f1fd 100644 --- a/furc/src/front/ssa.cpp +++ b/furc/src/front/ssa.cpp @@ -61,6 +61,29 @@ void ssa::optimize(const std::unique_ptr& func) { } } + std::unordered_set globalRegs; + for (furlang::ir::block_index i = 0; i < func->blocks().size(); ++i) { + const auto& block = func->blocks()[i]; + for (const auto& instr : block->instructions()) { + for (const auto& operand : instr->sources()) { + if (operand->type() == furlang::ir::operand_t::Register) { + auto reg = operand->reg(); + if (regSites[reg].find(i) == regSites[reg].end()) { + globalRegs.insert(reg); + } + } + } + } + for (const auto& operand : block->exit()->sources()) { + if (operand->type() == furlang::ir::operand_t::Register) { + auto reg = operand->reg(); + if (regSites[reg].find(i) == regSites[reg].end()) { + globalRegs.insert(reg); + } + } + } + } + std::unordered_set visited; std::vector rpoOrder; dfs_rpo(0, successors, visited, rpoOrder); @@ -83,6 +106,7 @@ void ssa::optimize(const std::unique_ptr& func) { return block1; }; + if (rpoOrder.empty()) return; auto entry = rpoOrder.front(); idoms[entry] = entry; @@ -132,8 +156,9 @@ void ssa::optimize(const std::unique_ptr& func) { std::unordered_map> phis; for (const auto& [reg, blocks] : regSites) { - std::vector worklist(blocks.begin(), blocks.end()); + if (globalRegs.find(reg) == globalRegs.end()) continue; + std::vector worklist(blocks.begin(), blocks.end()); std::unordered_set added; while (!worklist.empty()) { auto block = worklist.back();