一个表达式如果在其值改变之前肯定会再次被评估,则称为“非常繁忙”。为了近似这个属性,我们可以使用与可用表达式分析相同的格和辅助函数。对于每一个CFG中的节点$v$,用$[\![v]\!]$表示程序在该节点之前一定繁忙的表达式的集合。
一个表达式如果是繁忙的,那么一定是在当前节点或者之后的某条执行轨迹上被计算,除非表达式中值被修改。因此,$JOIN$函数的定义如下(当前节点的结果需要考虑之后节点的结果的交集合):
$$ JOIN(v) = \bigcap_{w\in~succ(v)}~[\![w]\!] $$
用如下约束规则建模赋值 语句:
在推出节点,没有表达式满足繁忙属性:
对于其他类型的节点,包括分支语句的条件表达式和输出语句,约束规则如下(与可用表达式分析一致):
对于如下示例程序:
var x,a,b;
x = input;
a = x-1;
b = x-2;
while (x>0) {
output a*b-x;
x = x-1;
}
output a*b;
分析结果显示,表达式“a*b”在循环内部满足繁忙属性。因此编译器可以进行代码提升(code hoisting)优化,并将繁忙的表达式移动到最开始的程序点。这样可以将程序转化为一种更加高效的版本:
var x,a,b,atimesb;
x = input;
a = x-1;
b = x-2;
atimesb = a*b;
while (x>0) {
output atimesb-x;
x = x-1;
}
output atimesb;