Control Flow:OUT[B] = US a_successor_of_BIN[S]
OUT[B]: 基本块B的出口存活变量集合,即基本块B执行完毕后,接下来的执行仍然需要使用的变量集合
IN[a]: 基本块a的入口存活变量集合,即执行到基本块a时,需要使用的变量集合
US: 并集运算符,表示取所有后继基本块的入口存活变量集合的并集
a_successor_of_B: 表示基本块B的所有后继基本块
BB1:
t1 = a + b
if (c > 0) goto BB2 else goto BB3
BB2:
t2 = t1 * 2
...
BB3:
t3 = t1 - 1
...
在这个例子中,BB1有两个后继:BB2和BB3。
-
假设经过分析,我们知道在进入BB2时,变量t1和c是活的(因为t1在BB2中被使用,c用于条件跳转)。
-
同样,我们知道在进入BB3时,变量t1也是活的。
那么,对于BB1的出口存活变量集合OUT[BB1],我们会有:
OUT[BB1] = IN[BB2] ∪ IN[BB3]
= {t1, c} ∪ {t1}
= {t1, c}
这里,我们取了BB2和BB3的入口存活变量集合的并集,得到BB1的出口存活变量集合为t1和c
Transfer Function:IN[B] = useB U (OUT[B] - defB)
IN[B]: 进入基本块B的活跃变量集合
OUT[B]: 这是离开基本块B的活跃变量
useB: 这是在基本块B中使用的变量集合
defB: 这是在基本块B中定义(即赋值)的变量集合
转移函数的含义:
IN[B] = useB U (OUT[B] - defB) : 基本块B的输入活跃集合(IN[B]) 等于在基本块B中使用的变量(useB) 和不在基本块B中定义的输出活跃变量(OUT[B] - defB)的并集
例子:
B1:
x = a + b
y = c + d
if (condition) goto B2 else goto B3
B2:
print x
x = e + f
B3:
print y
在进行活跃变量分析时,假设condition可能为真或假,因为需要考虑两个路径
对于基本块B2, 我们有:
-
useB2 = {x, e, f} (因为变量x,e, f在B2中被使用)
-
defB2 = {x} (因为变量x在B2中被重新定义)
如果我们在进入B2之前知道OUT[B1],那么:
- OUT[B1] = {x, y} (因为x和y在if条件之后可能被使用)
根据转移函数,我们计算IN[B2]:
-
IN[B2] = useB2 U (OUT[B1] - defB2)
-
IN[B2] = {x, e, f} U ({x, y} - {x})
-
iN[B2] = {x, e, f, y}
这意味着在进入B2时,变量x,e,f和y是活跃的。即使x在B2中被重新定义,它仍然是活跃的,因为它在B2中被使用了