编译算法:SSA上的条件常数传播

来源:互联网 发布:开淘宝店卖土特产 编辑:程序博客网 时间:2024/06/02 03:44



背景: 

SSA有phi语句,有def-use边。CFG以每条语句(普通语句或phi语句)作为节点。


算法思想:


在CFG的流边上进行符号执行:从entry开始执行,记录每个变量的lattice值(初始值top,常数,非常数bottom)。处理完当前节点(语句),则将其后继节点放入流边的worklist。

1. 符号执行:在处理分支节点时,如果能确定分支条件为常数值,则仅仅将确定的分支放入流边的worklist;反之,无法确定哪个分支会执行,则所有后继节点都放入流边的worklist。

2. 流边都初始化为不可执行,处理之后则标记为可执行(表示程序可以执行到这里)。每条流边仅处理一次(其目的就是标记该边可执行)。


在SSA的def-use边上进行常数传播,前提是当前节点的前驱节点已经被流边处理过(表示当前节点是可执行的)。

1. SSA边可以反复处理,直到SSA的worklist空了为止。


【总结:流边负责标记CFG中哪些语句是可执行的(可达的),也做一部分常数传播的工作。SSA负责将进行快速的常数传播(如果CFG存在循环,则会在CFG上进行多次迭代,直到变量的常数值稳定为止)。】


技巧:

流边worklist初始化为{entry->node}。

SSa worklist初始化为{}。

所有的流边初始化为不可执行(不可达),被访问过一次之后,则标记为可执行(可达)。

所有变量的lattice值初始化为top(init值)。


meet(lattice_val, top) = lattice_val   // 这条规则保证,在路径的汇合处,未执行的路径(其lattice值为top)不会影响常数的传播。

meet(lattice_val, bottom) = bottom

meet(lattice_val1, lattice_val2) = val  //  lattice_val1 == lattice_val2 == val。否则就是bottom。