如何获得的LLVM控制流图(CFG)的强连通分量(SCC)的拓扑排序(topological order)

来源:互联网 发布:淘宝店铺店名 编辑:程序博客网 时间:2024/05/30 07:12

一、思路

使用llvm/ADT/SCCIterator.h中定义的scc_iterator迭代器获得。

但是scc_iterator获得是逆拓扑排序的。它的注释如下:

// The SCC iterator has the important property that if a node in SCC S1 has an
// edge to a node in SCC S2, then it visits S1 *after* S2.


/// scc_iterator - Enumerate the SCCs of a directed graph, in
/// reverse topological order of the SCC DAG

所以我们使用栈进行获得SCC正序的拓扑排序(因为scc_iterator不支持自减)

二、获得SCC拓扑排序的代码:

代码如下,其中F是Function*类型的,是待分析的函数

132     std::stack<scc_iterator<Function*> > sccs;133     for(scc_iterator<Function*> SCCI=scc_begin(F),SCCE=scc_end(F);SCCI!=SCCE;++SCCI)134         sccs.push(SCCI);135 136     //按照顺序遍历强连通分量(SCC)137     unsigned sccNum=0;138     while(!sccs.empty()){139         scc_iterator<Function*> SCCI=sccs.top();140         sccs.pop();141         std::vector<BasicBlock*> & nextSCC=*SCCI;142         errs()<<"\n SCC#"<<++sccNum<<":";143         //遍历SCC中的块(DFS顺序 )144         std::vector<BasicBlock*>::const_iterator I=nextSCC.begin(),E=nextSCC.end();145         for(--E,--I;E!=I;--E){146             errs()<<(*E)->getName()<<",";147         }148      }

需要特别指出的,我们打印出SCC内部的基本块(Basic Block)是按照DFS(深度优先)打印出的。


三、参考代码

本代码参考LLVM的

tools/opt/PrintSCC.cpp

include/llvm/ADT/SCCIterator.h

四、参考

http://stackoverflow.com/questions/18650999/topological-sorting-of-basic-blocks-in-llvm


0 0
原创粉丝点击