mem2reg整体流程

2 阅读2分钟
  1. LLVM假设程序中所有的局部变量都在栈上,并且通过Alloca指令在函数的Entry BB 进行声明,并且只出现在Entry BB里。

  2. 对步骤1中声明的每个ALLOC指令,LLVM都会检查它是否为promotable(是否可以转化成SSA形式,从而删除这个Alloca)。如果满足下面的2个条件,就是可promotable:

  3. 这个ALLOC出来的临时变量不在任何volatile指定中使用

  4. 这个变量是直接通过LOAD或者STORE进行访问的,比如,不会被取址

  5. 对于步骤2中选出来的可promotable的那些局部变量,扫描一次当前函数,看下哪些基本块在使用这些ALLOC,哪些基本块定义了这个ALLOC(这里的使用是指LOAD,定义是通过STORE语句)

  6. 在这个过程中,可以执行一些基本的优化,比如:

  7. 未使用的ALLOC变量,比如声明或定义的但没有使用变量

  8. 如果只有一个定义基本块(只有一个STORE语句,且只存在一个基本块中),那么被这个定义基本块所支配的所有LOAD都要被替换为STORE语句中的那个右值

  9. 如果某个ALLOC出来的局部变量的读或者写都只存在一个基本块中,那么我们就没必要去遍历所有的CFG的,因为这个store语句支配了这些LOAD,所以可以用STORE的右值直接替换使用LOAD指令的那些值

  10. 构建支配者树

  11. 利用支配信息,来插入PHI节点,具体做法是:

  12. 对于每个经过上述步骤筛选后的ALLOC临时变量,找到一组基本块,这些基本块只使用了这个临时变量,而没有定义它,这组基本块也可能不存在

  13. 通过一种线性时间复杂度的算法来求得PHI节点的插入点

  14. 将PHI节点插入到上一步找到的那些插入点,且插在这些BB的开头

  15. 一旦所有的PHI节点都插入到为后,就开始重命名PASS