LLVM Pass框架是LLVM系统的重要组成部分,因为LLVM Pass负责LLVM编译器绝大部分的工作。 构成编译器的Pass执行各种转换和优化,在转换中使用的前边Pass的分析结果。所有的类实现都必须继承至Pass基类,一般来说可供使用的Pass类型一般包括 ModulePass , CallGraphSCCPass, FunctionPass , or LoopPass, or RegionPass 这几个类。Function/Module/Loop/Region这几个Pass都不难理解,主要是 CallGraphSCCPass这个,CallGraph顾名思义,SCC(Strongly-Connected-Component)是强联通分量,这个从llvm/ADT/SCCIterator.h中定义的scc_iterator定义中可以得到,是一个DFS遍历顺序。
下边介绍了一段对CallGraphSCC中的runOnFunction进行遍历的代码:
1 std::stack<scc_iterator<Function*> > sccs; 2 for(scc_iterator<Function*> SCCI=scc_begin(F),SCCE=scc_end(F);SCCI!=SCCE;++SCCI) 3 sccs.push(SCCI); 4 5 //按照顺序遍历强连通分量(SCC) 6 unsigned sccNum=0; 7 while(!sccs.empty()){ 8 scc_iterator<Function*> SCCI=sccs.top(); 9 sccs.pop(); 10 std::vector<BasicBlock*> & nextSCC=*SCCI; 11 errs()<<"\n SCC#"<<++sccNum<<":"; 12 //遍历SCC中的块(DFS顺序 ) 13 std::vector<BasicBlock*>::const_iterator I=nextSCC.begin(),E=nextSCC.end(); 14 for(--E,--I;E!=I;--E){ 15 errs()<<(*E)->getName()<<","; 16 } 17 }