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

一、思路

使用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

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/dreammeard/article/details/19492145
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞