BCF模块
BCF的主要流程是:
- split
- clone
- 畸变clone
- 插入不透明谓词
- 调整start orig altered三者关系
其中split和clone是出问题的重灾区
unmatched subprogram
clone时,会统计原始块的信息,然后对变量remap,将变量的引用改为当前块的。此时会出现unmatched subprogram between llvm.dbg.value and !dbg
void @llvm.dbg.value(metadata, i64, metadata, metadata)
这个函数当local variable被set new value时会被调用。
参数1:被metadata包装的new value
参数2:local value 中的offset
参数3:local variable
参数4:complex expression
其中参数3是DILocalVariable类型 表示源码中的局部变量,内部有几个字段
name: 源码中这个变量的名字
arg:如果不是0,则表示他是一个子程序subprogram的参数,他会在DISubprogram的variables字段中
line:行号
type.scope.file…
DISubprogram表示源码中的方法,他会被使用!dbg attach在方法的define后面
verify机制中,要求llvm.dbg.value的第三个参数和后面的!dbg的subprogram一致。然而,clone-remap后两个subprogram内容一样,但是编号不一样。
解决方法
- clone的时候不去clone
tail call @llvm.dbg.value
- remap的时候不去修改orig中
tail call @llvm.dbg.value
信息
miss dgb loc
这个问题有由于上个问题不当的解决方案导致的。
如果不clone llvm.dbg.value会导致orig和altered指令数量不一样,在处理attach loc的时候会出差错。
landing pad
先看看IR中的invoke指令
12 |
<result> = invoke [cconv] [ret attrs] <ty>|<fnty> <fnptrval>(<function args>) [fn attrs] [operand bundles] to label <normal label> unwind label <exception label> |
最后的 unwind label
The exception label is a landing pad for the exception. As such, exception label is required to have the “landingpad” instruction, which contains the information about the behavior of the program after unwinding happens
在bcf中,会对一个basicblock先split,然后clone后面的内容。
切分的时候,会定位第一个非dbg非phi非lifetime的指令。
但是,对于landing的bb,开始的指令必须是landingpad
解决方法
- split的时候跳过EHPad指令
Opaque Predicate
随机选择多种不透明谓词,如简单的x^2>=0
x采用globalVariable,可以随机取值
但是得注意x乘法运行可能会导致整数溢出,从而导致不透明谓词不再恒真。
优化方向
- 现在经过不透明谓词后,永远是true调用原逻辑,false是假逻辑,可以优化真假选择也是随机的;
- clone部门的逻辑和真逻辑很像,虽然有畸变,但是效果有待加强
fla模块
原逻辑中如果出现了for运行会导致for的body进不去。
for的逻辑处理错误:
分割出Entry后,然后Entry会设置一个init SwtichVar,进入for-switch循环。
但是初始值对应的BB出了问题。
其他
为了使用CloneBasicBlock,而#include "llvm/Transforms/Utils/Cloning.h"
内部会用到Result R(AM.getResult<TargetLibraryAnalysis>(F));
在CryptoUtils里面#define R(x, n) (((x) & 0xFFFFFFFFUL) >> (n))
从而冲突了,因此调整两个include的顺序,保证Cloning.h在CryptoUtils.h的前头,也可以修改define R1(x,n)…
这个问题好像在官方4.0也修复了
原文:大专栏 OLLVM排坑优化篇