From 32ea24df560b8811f91007a12c53461c4a2b73b9 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sun, 3 Aug 2025 00:51:49 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E4=BF=AE=E5=A4=8DentryBB=E5=92=8CfuncB?= =?UTF-8?q?odyEntry=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=EF=BC=8CDom?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=BC=95=E8=BF=9B=E9=80=86=E5=90=8E=E7=BB=AD?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E5=92=8CLT=E7=AE=97=E6=B3=95=EF=BC=8CPass?= =?UTF-8?q?=E5=85=88=E9=BB=98=E8=AE=A4=E5=85=B3=E6=8E=89CFGOpt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/Pass/Analysis/Dom.h | 68 +++- src/midend/Pass/Analysis/Dom.cpp | 409 ++++++++++++++++++------- src/midend/Pass/Pass.cpp | 16 +- src/midend/SysYIRGenerator.cpp | 1 + 4 files changed, 368 insertions(+), 126 deletions(-) diff --git a/src/include/midend/Pass/Analysis/Dom.h b/src/include/midend/Pass/Analysis/Dom.h index 80e0883..5ad5fe3 100644 --- a/src/include/midend/Pass/Analysis/Dom.h +++ b/src/include/midend/Pass/Analysis/Dom.h @@ -6,30 +6,82 @@ #include #include #include +#include namespace sysy { -// 支配树分析结果类 (保持不变) +// 支配树分析结果类 class DominatorTree : public AnalysisResultBase { public: DominatorTree(Function* F); + // 获取指定基本块的所有支配者 const std::set* getDominators(BasicBlock* BB) const; - BasicBlock* getImmediateDominator(BasicBlock* BB) const; - const std::set* getDominanceFrontier(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); - void computeIDoms(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; + 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); }; diff --git a/src/midend/Pass/Analysis/Dom.cpp b/src/midend/Pass/Analysis/Dom.cpp index 77b2bba..b4054c9 100644 --- a/src/midend/Pass/Analysis/Dom.cpp +++ b/src/midend/Pass/Analysis/Dom.cpp @@ -1,21 +1,30 @@ #include "Dom.h" -#include // for std::set_intersection, std::set_difference, std::set_union +#include // for std::set_intersection, std::reverse #include // for debug output #include // for std::numeric_limits #include +#include // for std::function +#include +#include +#include namespace sysy { -// 初始化 支配树静态 ID +// ============================================================== +// DominatorTreeAnalysisPass 的静态ID +// ============================================================== void *DominatorTreeAnalysisPass::ID = (void *)&DominatorTreeAnalysisPass::ID; + // ============================================================== // DominatorTree 结果类的实现 // ============================================================== +// 构造函数:初始化关联函数,但不进行计算 DominatorTree::DominatorTree(Function *F) : AssociatedFunction(F) { - // 构造时可以不计算,在分析遍运行里计算并填充 + // 构造时不需要计算,在分析遍运行里计算并填充 } +// Getter 方法 (保持不变) const std::set *DominatorTree::getDominators(BasicBlock *BB) const { auto it = Dominators.find(BB); if (it != Dominators.end()) { @@ -48,7 +57,7 @@ const std::set *DominatorTree::getDominatorTreeChildren(BasicBlock return nullptr; } -// 辅助函数:打印 BasicBlock 集合 +// 辅助函数:打印 BasicBlock 集合 (保持不变) void printBBSet(const std::string &prefix, const std::set &s) { if (!DEBUG) return; @@ -63,24 +72,52 @@ void printBBSet(const std::string &prefix, const std::set &s) { std::cout << "}" << std::endl; } +// 辅助函数:计算逆后序遍历 (RPO) - 保持不变 +std::vector DominatorTree::computeReversePostOrder(Function* F) { + std::vector postOrder; + std::set visited; + + std::function dfs_rpo = + [&](BasicBlock* bb) { + visited.insert(bb); + for (BasicBlock* succ : bb->getSuccessors()) { + if (visited.find(succ) == visited.end()) { + dfs_rpo(succ); + } + } + postOrder.push_back(bb); + }; + + dfs_rpo(F->getEntryBlock()); + std::reverse(postOrder.begin(), postOrder.end()); + + if (DEBUG) { + std::cout << "--- Computed RPO: "; + for (BasicBlock* bb : postOrder) { + std::cout << bb->getName() << " "; + } + std::cout << "---" << std::endl; + } + return postOrder; +} + +// computeDominators 方法 (保持不变,因为它它是独立于IDom算法的) void DominatorTree::computeDominators(Function *F) { if (DEBUG) std::cout << "--- Computing Dominators ---" << std::endl; BasicBlock *entryBlock = F->getEntryBlock(); - std::vector bbs_in_order; // 用于确定遍历顺序,如果需要的话 + std::vector bbs_rpo = computeReversePostOrder(F); - // 初始化:入口块只被自己支配,其他块被所有块支配 - for (const auto &bb_ptr : F->getBasicBlocks()) { - BasicBlock *bb = bb_ptr.get(); - bbs_in_order.push_back(bb); // 收集所有块 + for (BasicBlock *bb : bbs_rpo) { if (bb == entryBlock) { + Dominators[bb].clear(); Dominators[bb].insert(bb); - if (DEBUG) - std::cout << "Init Dominators[" << bb->getName() << "]: {" << bb->getName() << "}" << std::endl; + if (DEBUG) std::cout << "Init Dominators[" << bb->getName() << "]: {" << bb->getName() << "}" << std::endl; } else { - for (const auto &all_bb_ptr : F->getBasicBlocks()) { - Dominators[bb].insert(all_bb_ptr.get()); + Dominators[bb].clear(); + for (BasicBlock *all_bb : bbs_rpo) { + Dominators[bb].insert(all_bb); } if (DEBUG) { std::cout << "Init Dominators[" << bb->getName() << "]: "; @@ -94,35 +131,29 @@ void DominatorTree::computeDominators(Function *F) { while (changed) { changed = false; iteration++; - if (DEBUG) - std::cout << "Iteration " << iteration << std::endl; + if (DEBUG) std::cout << "Iteration " << iteration << std::endl; - // 确保遍历顺序一致性,例如可以按照DFS或BFS顺序,或者简单的迭代器顺序 - // 如果Function::getBasicBlocks()返回的迭代器顺序稳定,则无需bbs_in_order - for (const auto &bb_ptr : F->getBasicBlocks()) { // 假设这个迭代器顺序稳定 - BasicBlock *bb = bb_ptr.get(); - if (bb == entryBlock) - continue; + for (BasicBlock *bb : bbs_rpo) { + if (bb == entryBlock) continue; - // 计算所有前驱的支配者集合的交集 std::set newDom; bool firstPredProcessed = false; for (BasicBlock *pred : bb->getPredecessors()) { - // 确保前驱的支配者集合已经计算过 - if (Dominators.count(pred)) { - if (!firstPredProcessed) { - newDom = Dominators[pred]; - firstPredProcessed = true; - } else { - std::set intersection; - std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(), - std::inserter(intersection, intersection.begin())); - newDom = intersection; - } + if(DEBUG){ + std::cout << " Processing predecessor: " << pred->getName() << std::endl; } + if (!firstPredProcessed) { + newDom = Dominators[pred]; + firstPredProcessed = true; + } else { + std::set intersection; + std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(), + std::inserter(intersection, intersection.begin())); + newDom = intersection; + } } - newDom.insert(bb); // BB 永远支配自己 + newDom.insert(bb); if (newDom != Dominators[bb]) { if (DEBUG) { @@ -140,78 +171,242 @@ void DominatorTree::computeDominators(Function *F) { std::cout << "--- Dominators Computation Finished ---" << std::endl; } -void DominatorTree::computeIDoms(Function *F) { - if (DEBUG) - std::cout << "--- Computing Immediate Dominators (IDoms) ---" << std::endl; +// ============================================================== +// Lengauer-Tarjan 算法辅助数据结构和函数 (私有成员) +// ============================================================== - BasicBlock *entryBlock = F->getEntryBlock(); - IDoms[entryBlock] = nullptr; // 入口块没有即时支配者 - - // 遍历所有非入口块 - for (const auto &bb_ptr : F->getBasicBlocks()) { - BasicBlock *bb = bb_ptr.get(); - if (bb == entryBlock) - continue; - - BasicBlock *currentIDom = nullptr; - const std::set *domsOfBB = getDominators(bb); - if (!domsOfBB) { - if (DEBUG) - std::cerr << "Warning: Dominators for " << bb->getName() << " not found!" << std::endl; - continue; +// DFS 遍历,填充 dfnum_map, vertex_vec, parent_map +// 对应用户代码的 dfs 函数 +void DominatorTree::dfs_lt_helper(BasicBlock* u) { + dfnum_map[u] = df_counter; + if (df_counter >= vertex_vec.size()) { // 动态调整大小 + vertex_vec.resize(df_counter + 1); } + vertex_vec[df_counter] = u; + if (DEBUG) std::cout << " DFS: Visiting " << u->getName() << ", dfnum = " << df_counter << std::endl; + df_counter++; - // 遍历bb的所有严格支配者 D (即 bb 的支配者中除了 bb 自身) - for (BasicBlock *D_candidate : *domsOfBB) { - if (D_candidate == bb) - continue; // 跳过bb自身 - - bool D_candidate_is_IDom = true; - // 检查是否存在另一个块 X,使得 D_candidate 严格支配 X 且 X 严格支配 bb - // 或者更直接的,检查 D_candidate 是否被 bb 的所有其他严格支配者所支配 - for (BasicBlock *X_other_dom : *domsOfBB) { - if (X_other_dom == bb || X_other_dom == D_candidate) - continue; // 跳过bb自身和D_candidate - - // 如果 X_other_dom 严格支配 bb (它在 domsOfBB 中且不是bb自身) - // 并且 X_other_dom 不被 D_candidate 支配,那么 D_candidate 就不是 IDom - const std::set *domsOfX_other_dom = getDominators(X_other_dom); - if (domsOfX_other_dom && domsOfX_other_dom->count(D_candidate)) { // X_other_dom 支配 D_candidate - // D_candidate 被另一个支配者 X_other_dom 支配 - // 这说明 D_candidate 位于 X_other_dom 的“下方”,X_other_dom 更接近 bb - // 因此 D_candidate 不是 IDom - D_candidate_is_IDom = false; - break; + for (BasicBlock* v : u->getSuccessors()) { + if (dfnum_map.find(v) == dfnum_map.end()) { // 如果 v 未访问过 + parent_map[v] = u; + if (DEBUG) std::cout << " DFS: Setting parent[" << v->getName() << "] = " << u->getName() << std::endl; + dfs_lt_helper(v); } - } - if (D_candidate_is_IDom) { - currentIDom = D_candidate; - break; // 找到即时支配者,可以退出循环,因为它是唯一的 - } } - IDoms[bb] = currentIDom; - if (DEBUG) { - std::cout << " IDom[" << bb->getName() << "] = " << (currentIDom ? currentIDom->getName() : "nullptr") - << std::endl; - } - } - if (DEBUG) - std::cout << "--- Immediate Dominators Computation Finished ---" << std::endl; } -/* -for each node n in a postorder traversal of the dominator tree: - df[n] = empty set - // compute DF_local(n) - for each child y of n in the CFG: - if idom[y] != n: - df[n] = df[n] U {y} - // compute DF_up(n) - for each child c of n in the dominator tree: - for each element w in df[c]: - if idom[w] != n: - df[n] = df[n] U {w} -*/ +// 并查集:找到集合的代表,并进行路径压缩 +// 同时更新 label,确保 label[i] 总是指向其祖先链中 sdom_map 最小的节点 +// 对应用户代码的 find 函数,也包含了 eval 的逻辑 +BasicBlock* DominatorTree::evalAndCompress_lt_helper(BasicBlock* i) { + if (DEBUG) std::cout << " Eval: Processing " << i->getName() << std::endl; + // 如果 i 是根 (ancestor_map[i] == nullptr) + if (ancestor_map.find(i) == ancestor_map.end() || ancestor_map[i] == nullptr) { + if (DEBUG) std::cout << " Eval: " << i->getName() << " is root, returning itself." << std::endl; + return i; // 根节点自身就是路径上sdom最小的,因为它没有祖先 + } + + // 如果 i 的祖先不是根,则递归查找并进行路径压缩 + BasicBlock* root_ancestor = evalAndCompress_lt_helper(ancestor_map[i]); + + // 路径压缩时,根据 sdom_map 比较并更新 label_map + // 确保 label_map[i] 存储的是 i 到 root_ancestor 路径上 sdom_map 最小的节点 + // 注意:这里的 ancestor_map[i] 已经被递归调用压缩过一次了,所以是root_ancestor的旧路径 + // 应该比较的是 label_map[ancestor_map[i]] 和 label_map[i] + if (sdom_map.count(label_map[ancestor_map[i]]) && // 确保 label_map[ancestor_map[i]] 存在 sdom + sdom_map.count(label_map[i]) && // 确保 label_map[i] 存在 sdom + dfnum_map[sdom_map[label_map[ancestor_map[i]]]] < dfnum_map[sdom_map[label_map[i]]]) { + if (DEBUG) std::cout << " Eval: Updating label for " << i->getName() << " from " + << label_map[i]->getName() << " to " << label_map[ancestor_map[i]]->getName() << std::endl; + label_map[i] = label_map[ancestor_map[i]]; + } + + ancestor_map[i] = root_ancestor; // 执行路径压缩:将 i 直接指向其所属集合的根 + if (DEBUG) std::cout << " Eval: Path compression for " << i->getName() << ", new ancestor = " + << (root_ancestor ? root_ancestor->getName() : "nullptr") << std::endl; + + return label_map[i]; // <-- **将这里改为返回 label_map[i]** +} + +// Link 函数:将 v 加入 u 的 DFS 树子树中 (实际上是并查集操作) +// 对应用户代码的 fa[u] = fth[u]; +void DominatorTree::link_lt_helper(BasicBlock* u_parent, BasicBlock* v_child) { + ancestor_map[v_child] = u_parent; // 设置并查集父节点 + label_map[v_child] = v_child; // 初始化 label 为自身 + if (DEBUG) std::cout << " Link: " << v_child->getName() << " linked to " << u_parent->getName() << std::endl; +} + +// ============================================================== +// Lengauer-Tarjan 算法实现 computeIDoms +// ============================================================== +void DominatorTree::computeIDoms(Function *F) { + if (DEBUG) std::cout << "--- Computing Immediate Dominators (IDoms) using Lengauer-Tarjan ---" << std::endl; + + BasicBlock *entryBlock = F->getEntryBlock(); + + // 1. 初始化所有 LT 相关的数据结构 + dfnum_map.clear(); + vertex_vec.clear(); + parent_map.clear(); + sdom_map.clear(); + idom_map.clear(); + bucket_map.clear(); + ancestor_map.clear(); + label_map.clear(); + df_counter = 0; // DFS 计数器从 0 开始 + + // 预分配 vertex_vec 的大小,避免频繁resize + vertex_vec.resize(F->getBasicBlocks().size() + 1); + // 在 DFS 遍历之前,先为所有基本块初始化 sdom 和 label + // 这是 Lengauer-Tarjan 算法的要求,确保所有节点在 Phase 2 开始前都在 map 中 + for (auto &bb_ptr : F->getBasicBlocks()) { + BasicBlock* bb = bb_ptr.get(); + sdom_map[bb] = bb; // sdom(bb) 初始化为 bb 自身 + label_map[bb] = bb; // label(bb) 初始化为 bb 自身 (用于 Union-Find 的路径压缩) + } + // 确保入口块也被正确初始化(如果它不在 F->getBasicBlocks() 的正常迭代中) + sdom_map[entryBlock] = entryBlock; + label_map[entryBlock] = entryBlock; + // Phase 1: DFS 遍历并预处理 + // 对应用户代码的 dfs(st) + dfs_lt_helper(entryBlock); + idom_map[entryBlock] = nullptr; // 入口块没有即时支配者 + if (DEBUG) std::cout << " IDom[" << entryBlock->getName() << "] = nullptr" << std::endl; + + if (DEBUG) std::cout << " Sdom[" << entryBlock->getName() << "] = " << entryBlock->getName() << std::endl; + + // 初始化并查集的祖先和 label + for (auto const& [bb_key, dfn_val] : dfnum_map) { + ancestor_map[bb_key] = nullptr; // 初始为独立集合的根 + label_map[bb_key] = bb_key; // 初始 label 为自身 + } + + if (DEBUG) { + std::cout << " --- DFS Phase Complete ---" << std::endl; + std::cout << " dfnum_map:" << std::endl; + for (auto const& [bb, dfn] : dfnum_map) { + std::cout << " " << bb->getName() << " -> " << dfn << std::endl; + } + std::cout << " vertex_vec (by dfnum):" << std::endl; + for (size_t k = 0; k < df_counter; ++k) { + if (vertex_vec[k]) std::cout << " [" << k << "] -> " << vertex_vec[k]->getName() << std::endl; + } + std::cout << " parent_map:" << std::endl; + for (auto const& [child, parent] : parent_map) { + std::cout << " " << child->getName() << " -> " << (parent ? parent->getName() : "nullptr") << std::endl; + } + std::cout << " ------------------------" << std::endl; + } + + + // Phase 2: 计算半支配者 (sdom) + // 对应用户代码的 for (int i = dfc; i >= 2; --i) 循环的上半部分 + // 按照 DFS 编号递减的顺序遍历所有节点 (除了 entryBlock,它的 DFS 编号是 0) + if (DEBUG) std::cout << "--- Phase 2: Computing Semi-Dominators (sdom) ---" << std::endl; + for (int i = df_counter - 1; i >= 1; --i) { // 从 DFS 编号最大的节点开始,到 1 + BasicBlock* w = vertex_vec[i]; // 当前处理的节点 + if (DEBUG) std::cout << " Processing node w: " << w->getName() << " (dfnum=" << i << ")" << std::endl; + + + // 对于 w 的每个前驱 v + for (BasicBlock* v : w->getPredecessors()) { + if (DEBUG) std::cout << " Considering predecessor v: " << v->getName() << std::endl; + // 如果前驱 v 未被 DFS 访问过 (即不在 dfnum_map 中),则跳过 + if (dfnum_map.find(v) == dfnum_map.end()) { + if (DEBUG) std::cout << " Predecessor " << v->getName() << " not in DFS tree, skipping." << std::endl; + continue; + } + + // 调用 evalAndCompress 来找到 v 在其 DFS 树祖先链上具有最小 sdom 的节点 + BasicBlock* u_with_min_sdom_on_path = evalAndCompress_lt_helper(v); + if (DEBUG) std::cout << " Eval(" << v->getName() << ") returned " + << u_with_min_sdom_on_path->getName() << std::endl; + if (DEBUG && sdom_map.count(u_with_min_sdom_on_path) && sdom_map.count(w)) { + std::cout << " Comparing sdom: dfnum[" << sdom_map[u_with_min_sdom_on_path]->getName() << "] (" << dfnum_map[sdom_map[u_with_min_sdom_on_path]] + << ") vs dfnum[" << sdom_map[w]->getName() << "] (" << dfnum_map[sdom_map[w]] << ")" << std::endl; + } + // 比较 sdom(u) 和 sdom(w) + if (sdom_map.count(u_with_min_sdom_on_path) && sdom_map.count(w) && + dfnum_map[sdom_map[u_with_min_sdom_on_path]] < dfnum_map[sdom_map[w]]) { + if (DEBUG) std::cout << " Updating sdom[" << w->getName() << "] from " + << sdom_map[w]->getName() << " to " + << sdom_map[u_with_min_sdom_on_path]->getName() << std::endl; + sdom_map[w] = sdom_map[u_with_min_sdom_on_path]; // 更新 sdom(w) + if (DEBUG) std::cout << " Sdom update applied. New sdom[" << w->getName() << "] = " << sdom_map[w]->getName() << std::endl; + } + } + + // 将 w 加入 sdom(w) 对应的桶中 + bucket_map[sdom_map[w]].push_back(w); + if (DEBUG) std::cout << " Adding " << w->getName() << " to bucket of sdom(" << w->getName() << "): " + << sdom_map[w]->getName() << std::endl; + + // 将 w 的父节点加入并查集 (link 操作) + if (parent_map.count(w) && parent_map[w] != nullptr) { + link_lt_helper(parent_map[w], w); + } + + // Phase 3-part 1: 处理 parent[w] 的桶中所有节点,确定部分 idom + if (parent_map.count(w) && parent_map[w] != nullptr) { + BasicBlock* p = parent_map[w]; // p 是 w 的父节点 + if (DEBUG) std::cout << " Processing bucket for parent " << p->getName() << std::endl; + + // 注意:这里需要复制桶的内容,因为原始桶在循环中会被clear + std::vector nodes_in_p_bucket_copy = bucket_map[p]; + for (BasicBlock* y : nodes_in_p_bucket_copy) { + if (DEBUG) std::cout << " Processing node y from bucket: " << y->getName() << std::endl; + // 找到 y 在其 DFS 树祖先链上具有最小 sdom 的节点 + BasicBlock* u = evalAndCompress_lt_helper(y); + if (DEBUG) std::cout << " Eval(" << y->getName() << ") returned " << u->getName() << std::endl; + + // 确定 idom(y) + // if sdom(eval(y)) == sdom(parent(w)), then idom(y) = parent(w) + // else idom(y) = eval(y) + if (sdom_map.count(u) && sdom_map.count(p) && + dfnum_map[sdom_map[u]] < dfnum_map[sdom_map[p]]) { + idom_map[y] = u; // 确定的 idom + if (DEBUG) std::cout << " IDom[" << y->getName() << "] set to " << u->getName() << std::endl; + } else { + idom_map[y] = p; // p 是 y 的 idom + if (DEBUG) std::cout << " IDom[" << y->getName() << "] set to " << p->getName() << std::endl; + } + } + bucket_map[p].clear(); // 清空桶,防止重复处理 + if (DEBUG) std::cout << " Cleared bucket for parent " << p->getName() << std::endl; + } + } + + // Phase 3-part 2: 最终确定 idom (处理那些 idom != sdom 的节点) + if (DEBUG) std::cout << "--- Phase 3: Finalizing Immediate Dominators (idom) ---" << std::endl; + for (int i = 1; i < df_counter; ++i) { // 从 DFS 编号最小的节点 (除了 entryBlock) 开始 + BasicBlock* w = vertex_vec[i]; + if (DEBUG) std::cout << " Finalizing node w: " << w->getName() << std::endl; + if (idom_map.count(w) && sdom_map.count(w) && idom_map[w] != sdom_map[w]) { + // idom[w] 的 idom 是其真正的 idom + if (DEBUG) std::cout << " idom[" << w->getName() << "] (" << idom_map[w]->getName() + << ") != sdom[" << w->getName() << "] (" << sdom_map[w]->getName() << ")" << std::endl; + if (idom_map.count(idom_map[w])) { + idom_map[w] = idom_map[idom_map[w]]; + if (DEBUG) std::cout << " Updating idom[" << w->getName() << "] to idom(idom(w)): " + << idom_map[w]->getName() << std::endl; + } else { + if (DEBUG) std::cout << " Warning: idom(idom(" << w->getName() << ")) not found, leaving idom[" << w->getName() << "] as is." << std::endl; + } + } + if (DEBUG) { + std::cout << " Final IDom[" << w->getName() << "] = " << (idom_map[w] ? idom_map[w]->getName() : "nullptr") << std::endl; + } + } + + // 将计算结果从 idom_map 存储到 DominatorTree 的成员变量 IDoms 中 + IDoms = idom_map; + + if (DEBUG) std::cout << "--- Immediate Dominators Computation Finished ---" << std::endl; +} + +// ============================================================== +// computeDominanceFrontiers 和 computeDominatorTreeChildren (保持不变) +// ============================================================== void DominatorTree::computeDominanceFrontiers(Function *F) { if (DEBUG) @@ -221,21 +416,17 @@ void DominatorTree::computeDominanceFrontiers(Function *F) { BasicBlock *X = bb_ptr_X.get(); DominanceFrontiers[X].clear(); - // 遍历所有可能的 Z (X支配Z,或者Z就是X) for (const auto &bb_ptr_Z : F->getBasicBlocks()) { BasicBlock *Z = bb_ptr_Z.get(); const std::set *domsOfZ = getDominators(Z); - // 如果 X 不支配 Z,则 Z 与 DF(X) 无关 - if (!domsOfZ || domsOfZ->find(X) == domsOfZ->end()) { + if (!domsOfZ || domsOfZ->find(X) == domsOfZ->end()) { // Z 不被 X 支配 continue; } - // 遍历 Z 的所有后继 Y for (BasicBlock *Y : Z->getSuccessors()) { - // 如果 Y 不被 X 严格支配,则 Y 在 DF(X) 中 - // Y 不被 X 严格支配意味着 (Y不被X支配) 或 (Y就是X) const std::set *domsOfY = getDominators(Y); + // 如果 Y == X,或者 Y 不被 X 严格支配 (即 Y 不被 X 支配) if (Y == X || (domsOfY && domsOfY->find(X) == domsOfY->end())) { DominanceFrontiers[X].insert(Y); } @@ -274,23 +465,21 @@ void DominatorTree::computeDominatorTreeChildren(Function *F) { } // ============================================================== -// DominatorTreeAnalysisPass 的实现 +// DominatorTreeAnalysisPass 的实现 (保持不变) // ============================================================== bool DominatorTreeAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { // 每次运行时清空旧数据,确保重新计算 CurrentDominatorTree = std::make_unique(F); - // 不需要手动清空map,unique_ptr会创建新的DominatorTree对象,其map是空的 CurrentDominatorTree->computeDominators(F); - CurrentDominatorTree->computeIDoms(F); // 修正后的IDoms算法 + CurrentDominatorTree->computeIDoms(F); // 修正后的LT算法 CurrentDominatorTree->computeDominanceFrontiers(F); CurrentDominatorTree->computeDominatorTreeChildren(F); - return false; // 分析遍通常返回 false,表示不修改 IR + return false; } std::unique_ptr DominatorTreeAnalysisPass::getResult() { - // 返回计算好的 DominatorTree 实例,所有权转移给 AnalysisManager return std::move(CurrentDominatorTree); } diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index f4ec5ab..3c91c00 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -58,14 +58,14 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR if (DEBUG) std::cout << "Applying -O1 optimizations.\n"; if (DEBUG) std::cout << "--- Running custom optimization sequence ---\n"; - this->clearPasses(); - this->addPass(&SysYDelInstAfterBrPass::ID); - this->addPass(&SysYDelNoPreBLockPass::ID); - this->addPass(&SysYBlockMergePass::ID); - this->addPass(&SysYDelEmptyBlockPass::ID); - this->addPass(&SysYCondBr2BrPass::ID); - this->addPass(&SysYAddReturnPass::ID); - this->run(); + // this->clearPasses(); + // this->addPass(&SysYDelInstAfterBrPass::ID); + // this->addPass(&SysYDelNoPreBLockPass::ID); + // this->addPass(&SysYBlockMergePass::ID); + // this->addPass(&SysYDelEmptyBlockPass::ID); + // this->addPass(&SysYCondBr2BrPass::ID); + // this->addPass(&SysYAddReturnPass::ID); + // this->run(); if(DEBUG) { std::cout << "=== IR After CFGOpt Optimizations ===\n"; diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index 97b25b5..16f9423 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -1037,6 +1037,7 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){ // 从 entryBB 无条件跳转到 funcBodyEntry builder.createUncondBrInst(funcBodyEntry); + BasicBlock::conectBlocks(entry, funcBodyEntry); // 连接 entryBB 和 funcBodyEntry builder.setPosition(funcBodyEntry,funcBodyEntry->end()); // 将插入点设置到 funcBodyEntry for (auto item : ctx->blockStmt()->blockItem()) {