[midend]修复entryBB和funcBodyEntry的初始化,Dom计算引进逆后续遍历和LT算法,Pass先默认关掉CFGOpt

This commit is contained in:
rain2133
2025-08-03 00:51:49 +08:00
parent f879a0f521
commit 32ea24df56
4 changed files with 368 additions and 126 deletions

View File

@ -6,30 +6,82 @@
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
namespace sysy {
// 支配树分析结果类 (保持不变)
// 支配树分析结果类
class DominatorTree : public AnalysisResultBase {
public:
DominatorTree(Function* F);
// 获取指定基本块的所有支配者
const std::set<BasicBlock*>* getDominators(BasicBlock* BB) const;
BasicBlock* getImmediateDominator(BasicBlock* BB) const;
const std::set<BasicBlock*>* getDominanceFrontier(BasicBlock* BB) const;
// 获取指定基本块的即时支配者 (Immediate Dominator)
BasicBlock* getImmediateDominator(BasicBlock* BB) const;
// 获取指定基本块的支配边界 (Dominance Frontier)
const std::set<BasicBlock*>* getDominanceFrontier(BasicBlock* BB) const;
// 获取指定基本块在支配树中的子节点
const std::set<BasicBlock*>* getDominatorTreeChildren(BasicBlock* BB) const;
// 额外的 Getter获取所有支配者、即时支配者和支配边界的完整映射可选主要用于调试或特定场景
const std::map<BasicBlock*, std::set<BasicBlock*>>& getDominatorsMap() const { return Dominators; }
const std::map<BasicBlock*, BasicBlock*>& getIDomsMap() const { return IDoms; }
const std::map<BasicBlock*, std::set<BasicBlock*>>& getDominanceFrontiersMap() const { return DominanceFrontiers; }
// 计算所有基本块的支配者集合
void computeDominators(Function* F);
void computeIDoms(Function* F);
// 计算所有基本块的即时支配者(内部使用 Lengauer-Tarjan 算法)
void computeIDoms(Function* F);
// 计算所有基本块的支配边界
void computeDominanceFrontiers(Function* F);
// 计算支配树的结构(即每个节点的直接子节点)
void computeDominatorTreeChildren(Function* F);
private:
// 与该支配树关联的函数
Function* AssociatedFunction;
std::map<BasicBlock*, std::set<BasicBlock*>> Dominators;
std::map<BasicBlock*, BasicBlock*> IDoms;
std::map<BasicBlock*, std::set<BasicBlock*>> DominanceFrontiers;
std::map<BasicBlock*, std::set<BasicBlock*>> DominatorTreeChildren;
std::map<BasicBlock*, std::set<BasicBlock*>> Dominators; // 每个基本块的支配者集合
std::map<BasicBlock*, BasicBlock*> IDoms; // 每个基本块的即时支配者
std::map<BasicBlock*, std::set<BasicBlock*>> DominanceFrontiers; // 每个基本块的支配边界
std::map<BasicBlock*, std::set<BasicBlock*>> DominatorTreeChildren; // 支配树中每个基本块的子节点
// ==========================================================
// Lengauer-Tarjan 算法内部所需的数据结构和辅助函数
// 这些成员是私有的,以封装 LT 算法的复杂性并避免命名空间污染
// ==========================================================
// DFS 遍历相关:
std::map<BasicBlock*, int> dfnum_map; // 存储每个基本块的 DFS 编号
std::vector<BasicBlock*> vertex_vec; // 通过 DFS 编号反向查找对应的基本块指针
std::map<BasicBlock*, BasicBlock*> parent_map; // 存储 DFS 树中每个基本块的父节点
int df_counter; // DFS 计数器,也代表 DFS 遍历的总节点数 (N)
// 半支配者 (Semi-dominator) 相关:
std::map<BasicBlock*, BasicBlock*> sdom_map; // 存储每个基本块的半支配者
std::map<BasicBlock*, BasicBlock*> idom_map; // 存储每个基本块的即时支配者 (IDom)
std::map<BasicBlock*, std::vector<BasicBlock*>> bucket_map; // 桶结构,用于存储具有相同半支配者的节点,以延迟 IDom 计算
// 并查集 (Union-Find) 相关(用于 evalAndCompress 函数):
std::map<BasicBlock*, BasicBlock*> ancestor_map; // 并查集中的父节点(用于路径压缩)
std::map<BasicBlock*, BasicBlock*> label_map; // 并查集中,每个集合的代表节点(或其路径上 sdom 最小的节点)
// ==========================================================
// 辅助计算函数 (私有)
// ==========================================================
// 计算基本块的逆后序遍历 (Reverse Post Order, RPO) 顺序
// RPO 用于优化支配者计算和 LT 算法的效率
std::vector<BasicBlock*> 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);
};