llvm提供了强大的c++ api帮助我们查看llvm的内存表示并操作它
llvm ir 的层次结构
对应到代码
Iterating different IR units
扫描整个代码找到我们需要的部分,迭代是处理ir的基础
(1)迭代指令
可以遍历在这个基本块上的所有指令
可以现在遍历指令之前遍历整个函数的基本块
这里则是遍历这个函数所有的指令
有时候我们需要对不同类型的指令做出不同的处理
这里通过getOperator方法可以得到一个唯一的令牌
更好的方法是使用llvm提供的类
这里写回调函数逻辑,然后自动帮你遍历F里面的指令,遇到就执行回调函数
迭代基本块
? ? ? ? 之前的方式是随意的,我们现在需要用有意义的方式迭代基本块
?opt -dot-cfg -disable-output foo.ll这个命令可以让我们得到一个.dot文件,然后这个文件存了控制流图,后缀改为PNG我们就能得到控制图
?dot -Tpng foo.cfg.dot > foo.cfg.png
Topological order traversal(拓扑顺序遍历)
Depth-first and breadth-first traversal(深度优先遍历和宽度优先遍历)
深度优先的遍历顺序
宽度优先的顺序
SSC遍历
这说明%4和%2在一个图里
迭代调用图
? ? ? ? 这是反应函数调用关系的图
有关于图,我们都是实例化一个GraphTraits,然后实现相应的接口,这只是关于图的特征的一些接口。
如果要实现算法,我们会使用模板函数
第一个参数传入我们要用的图类型,第二个参数默认给我们构造图特征,然后我们调用定义好的接口可以拿到一些共有的图特征
值与指令
主要是首先使用IRBuilder<>绑定所有的Mul,然后把构建好的指令替换上去
这里的问题是,我们迭代的时候不能同时修改指令,所以要按照下面的方法延迟修改