You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM Pass中排除含unreachable指令基本块计算后支配树的方法

LLVM Pass中处理含unreachable基本块的后支配树问题

问题根源

removeUnreachableBlocks()只负责移除从函数入口不可达的基本块,但那些能被入口到达、最终仅包含unreachable指令的块(比如分支跳转进去的死块),并不会被这个函数处理。这类块的存在会导致返回块无法后支配所有有效基本块,干扰后支配树的正确性。

正确处理流程

1. 先清理入口不可达块

先调用标准函数移除入口不可达的块,这是基础步骤:

bool hasChanged = removeUnreachableBlocks(F);

这里F是你的Function&实例,返回值hasChanged会告诉你是否有块被移除。

2. 手动清理可达但仅含unreachable的块

对于入口可达但只有unreachable指令的块,需要手动遍历收集并删除:

std::vector<BasicBlock*> blocksToDelete;
for (BasicBlock& bb : F) {
    // 检查块是否仅含一条unreachable指令,且不是入口块
    if (bb.size() == 1 && isa<UnreachableInst>(bb.front()) && &bb != &F.getEntryBlock()) {
        blocksToDelete.push_back(&bb);
    }
}

// 先清理前驱分支,再删除块
for (BasicBlock* bb : blocksToDelete) {
    bb->removePredecessors(); // 移除所有指向该块的跳转
    bb->eraseFromParent();    // 从函数中删除块
}
  • 必须先收集所有目标块再批量删除,不能边遍历函数边删除,否则会破坏迭代器导致遍历异常。
  • removePredecessors()会自动处理前驱块的分支指令(比如把条件跳转改成无条件跳转,或者直接删除无用分支),避免留下悬空引用。

3. 重新构建后支配树

完成上述清理后,重新初始化或更新你的后支配树实例,此时返回块就能正确后支配所有有效可达的基本块了。

额外提示

  • 如果你的Pass依赖支配树,调用removeUnreachableBlocks()时可以传入已有的DominatorTree指针,让函数同步更新支配树:
removeUnreachableBlocks(F, &domTree); // domTree是DominatorTree&实例
  • 处理完这些块后,如果后续需要SSA形式,记得调用PHIElimination或SSAUpdater相关工具修复IR结构。

内容的提问来源于stack exchange,提问作者Lesterth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:02:39