#ifndef FURC_MIDDLE_SSA_HPP #define FURC_MIDDLE_SSA_HPP #include "furc/middle/ir.hpp" #include #include #include #include #include namespace furc { class ssa { public: struct cfg_block { std::unordered_set preds; std::unordered_set sucs; }; struct ssa_block { std::size_t order = 0; std::uint64_t idom = -1; std::unordered_set children; // Children of the block in dominator tree // Dominance Frontiers std::unordered_set df; }; struct register_info { std::unordered_set sites; // Definition Sites }; public: ssa(ir_function& func) { registers.resize(func.regCount); compute_cfg(func.blocks, cfgBlocks); collect_registers(func.blocks, registers, globals); std::vector order; compute_rpo(cfgBlocks, ssaBlocks, order); build_dtree(cfgBlocks, ssaBlocks, order); compute_dfrontiers(cfgBlocks, ssaBlocks); ssaification(func.blocks, cfgBlocks, ssaBlocks, registers, globals); rename(func.blocks, func.regCount, cfgBlocks, ssaBlocks, order); } public: static void compute_cfg(const std::vector& irBlocks, std::vector& cfgBlocks); static void collect_registers(const std::vector& irBlocks, std::vector& registers, std::unordered_set& globals); static void build_dtree(const std::vector& cfgBlocks, std::vector& ssaBlocks, const std::vector& order); static void compute_dfrontiers(const std::vector& cfgBlocks, std::vector& ssaBlocks); static void compute_rpo(std::vector& cfgBlocks, std::vector& ssaBlocks, std::vector& order); static void ssaification(std::vector& irBlocks, const std::vector& cfgBlocks, const std::vector& ssaBlocks, const std::vector& registers, const std::unordered_set& globals); static void rename(std::vector& irBlocks, std::size_t regCount, const std::vector& cfgBlocks, std::vector& ssaBlocks, const std::vector& order); private: static void rename_rec(std::vector& counters, std::vector>& stacks, std::vector& irBlocks, const std::vector& cfgBlocks, const std::vector& ssaBlocks, std::size_t blockIdx); private: static void rpo_dfs(std::unordered_set& visited, std::vector& order, std::size_t block, const std::vector& blocks); static std::size_t intersect(std::vector& m_blocks, std::size_t b1, std::size_t b2); public: std::vector cfgBlocks; std::vector ssaBlocks; std::vector registers; std::unordered_set globals; }; } // namespace furc #endif // FURC_MIDDLE_SSA_HPP