如何获取从指定BasicBlock(基本块A)出发可达的所有基本块
LLVM 获取指定基本块可达基本块实现方案
你提供的参考代码是遍历指定基本块前驱节点的用法,要获取当前基本块能到达的所有基本块,只需配合LLVM内置的后继节点遍历接口,做控制流图的广度/深度优先遍历即可,实现逻辑如下:
实现说明
- 核心依赖头文件为
llvm/IR/CFG.h,和你参考代码的引入一致 - 推荐使用广度优先搜索(BFS)实现,避免递归深度过高导致栈溢出,适配存在复杂循环、嵌套分支的CFG场景
- 需要额外用集合存储已访问的基本块,避免CFG中存在回边时出现无限遍历的问题
示例代码
#include "llvm/IR/CFG.h" #include "llvm/IR/BasicBlock.h" #include <set> #include <queue> using namespace llvm; std::set<BasicBlock*> getReachableBlocks(BasicBlock *StartBB) { std::set<BasicBlock*> reachableBlocks; std::queue<BasicBlock*> workList; // 初始块本身属于可达范围,先加入工作队列和已访问集合 workList.push(StartBB); reachableBlocks.insert(StartBB); while (!workList.empty()) { BasicBlock *curr = workList.front(); workList.pop(); // 遍历当前块的所有直接后继块 for (BasicBlock *succ : successors(curr)) { if (reachableBlocks.count(succ) == 0) { reachableBlocks.insert(succ); workList.push(succ); } } } return reachableBlocks; }
补充说明
如果你确认当前处理的CFG不存在循环,或者不需要保留去重能力,可以把存储可达块的
std::set替换为llvm::SmallVector,遍历性能会更高。
如果你要获取的是「所有能到达指定基本块的节点」,也就是反向可达集合,只需要把代码中的successors替换为你示例里的predecessors即可,遍历逻辑完全相同。
内容的提问来源于stack exchange,提问作者haohao
相关产品推荐
相关产品推荐

