#pragma once #include "Pass.h" // 包含 Pass 框架 #include "IR.h" // 包含 IR 定义 #include #include #include #include #include namespace sysy { // 支配树分析结果类 class DominatorTree : public AnalysisResultBase { public: DominatorTree(Function* F); // 获取指定基本块的所有支配者 const std::set* getDominators(BasicBlock* BB) const; // 获取指定基本块的即时支配者 (Immediate Dominator) BasicBlock* getImmediateDominator(BasicBlock* BB) const; // 获取指定基本块的支配边界 (Dominance Frontier) const std::set* getDominanceFrontier(BasicBlock* BB) const; // 获取指定基本块在支配树中的子节点 const std::set* getDominatorTreeChildren(BasicBlock* BB) const; // 额外的 Getter:获取所有支配者、即时支配者和支配边界的完整映射(可选,主要用于调试或特定场景) const std::map>& getDominatorsMap() const { return Dominators; } const std::map& getIDomsMap() const { return IDoms; } const std::map>& getDominanceFrontiersMap() const { return DominanceFrontiers; } // 计算所有基本块的支配者集合 void computeDominators(Function* F); // 计算所有基本块的即时支配者(内部使用 Lengauer-Tarjan 算法) void computeIDoms(Function* F); // 计算所有基本块的支配边界 void computeDominanceFrontiers(Function* F); // 计算支配树的结构(即每个节点的直接子节点) void computeDominatorTreeChildren(Function* F); private: // 与该支配树关联的函数 Function* AssociatedFunction; std::map> Dominators; // 每个基本块的支配者集合 std::map IDoms; // 每个基本块的即时支配者 std::map> DominanceFrontiers; // 每个基本块的支配边界 std::map> DominatorTreeChildren; // 支配树中每个基本块的子节点 // ========================================================== // Lengauer-Tarjan 算法内部所需的数据结构和辅助函数 // 这些成员是私有的,以封装 LT 算法的复杂性并避免命名空间污染 // ========================================================== // DFS 遍历相关: std::map dfnum_map; // 存储每个基本块的 DFS 编号 std::vector vertex_vec; // 通过 DFS 编号反向查找对应的基本块指针 std::map parent_map; // 存储 DFS 树中每个基本块的父节点 int df_counter; // DFS 计数器,也代表 DFS 遍历的总节点数 (N) // 半支配者 (Semi-dominator) 相关: std::map sdom_map; // 存储每个基本块的半支配者 std::map idom_map; // 存储每个基本块的即时支配者 (IDom) std::map> bucket_map; // 桶结构,用于存储具有相同半支配者的节点,以延迟 IDom 计算 // 并查集 (Union-Find) 相关(用于 evalAndCompress 函数): std::map ancestor_map; // 并查集中的父节点(用于路径压缩) std::map label_map; // 并查集中,每个集合的代表节点(或其路径上 sdom 最小的节点) // ========================================================== // 辅助计算函数 (私有) // ========================================================== // 计算基本块的逆后序遍历 (Reverse Post Order, RPO) 顺序 // RPO 用于优化支配者计算和 LT 算法的效率 std::vector computeReversePostOrder(Function* F); // Lengauer-Tarjan 算法特定的辅助 DFS 函数 // 用于初始化 dfnum_map, vertex_vec, parent_map void dfs_lt_helper(BasicBlock* u); // 结合了并查集的 Find 操作和 LT 算法的 Eval 操作 // 用于在路径压缩时更新 label,找到路径上 sdom 最小的节点 BasicBlock* evalAndCompress_lt_helper(BasicBlock* i); // 并查集的 Link 操作 // 将 v_child 挂载到 u_parent 的并查集树下 void link_lt_helper(BasicBlock* u_parent, BasicBlock* v_child); }; // 支配树分析遍 class DominatorTreeAnalysisPass : public AnalysisPass { public: // 唯一的 Pass ID static void *ID; DominatorTreeAnalysisPass() : AnalysisPass("DominatorTreeAnalysis", Pass::Granularity::Function) {} // 实现 getPassID void* getPassID() const override { return &ID; } bool runOnFunction(Function* F, AnalysisManager &AM) override; std::unique_ptr getResult() override; private: std::unique_ptr CurrentDominatorTree; }; } // namespace sysy