文章目录
三、
格理论
函数不动点
函数不动点用初等数学可以这么理解:连续映射 f 的定义域包含值域,则存在一个 x 使得 f(x) = x 。其中点 (x , f(x))为函数的不动点。
下面对前面三个示例采用的迭代算法进行分析,以前向分析 & may analysis 为例:
假设给定一个 CFG,节点数量为 k ,抽象域容量为 V。k 是程序中的基本块数量,V 在 RDA 中是程序中的 definition 数量。一次迭代需要更新 k 个 V,描述为集合(V1 × V2 … × Vk),表示为Vk(V 的 k 次方)。Vk是一个 k 元组,里面的每一个元素都是一个抽象域。
所以每一轮迭代可以看做是应用转换函数和控制流处理之后,从旧的Vk到新的Vk之间的转换,这里用函数 F:Vk → Vk 来表示。算法的停止条件是旧的 Vk 和新的 Vk 相同的时候。对应于当所有的 OUT 不发生变化时。
假设第 i 次迭代之后的结果为 Xi,并且有 Xi+1 = F(Xi)。如果 Xi+1 = Xi ,那么表示在第 i+1 次迭代时算法停止(所有 OUT 不发生变化了),做一个简单的代换可以得到:Xi = F(Xi) 。那么按照函数不动点的定义,认为此时达到了迭代算法的不动点(fixed point)。
在数据流分析中,通过采用迭代算法产生了一个解决方案。所以产生了三个问题:
问题1:算法能够保证一定会停止吗或者一定能够达到不动点吗?即迭代算法真的能产生一个解决方案吗?
问题2:如果问题1的回答是肯定的话,那是否只有一个不动点或一个解决方案?如果解决方案多于一个的话,迭代算法得到的会是最优的吗?
问题3:什么时候迭代算法能够达到不动点,即什么时候能够得到解决方案?
偏序(Partial Order)
We define poset as a pair (P, ⊑) where ⊑ is a binary relation that defines a partial ordering over P, and ⊑ has the following properties:
(1) ∀x ∈ P, x ⊑ x (Reflexivity)
(2) ∀x, y ∈ P, x ⊑ y ∧ y ⊑ x ⟹ x = y (Antisymmetry)
(3) ∀x, y, z ∈ P, x ⊑ y ∧ y ⊑ z ⟹ x ⊑ z (Transitivity)
⊑ 是集合 P 上的一个二元关系 ,并且满足上面三个属性:自反、反对称和传递,称 ⊑ 定义了在 P 上的偏序关系,(P, ⊑) 是一个偏序集。
例如:
1,当 P 为整数集合,⊑ 为小于等于关系时。(P, ⊑) 是一个偏序集。
2,当 P 为整数集合,⊑ 为小于关系时。(P, ⊑) 不是一个偏序集。因为不满足自反性。
3,当 P 为英文单词集合,⊑ 为一个单词是另一个单词的子串关系时(比如 a ⊑ b ,意味着单词 a 是单词 b 的子串)。(P, ⊑) 是一个偏序集。
偏序集中的偏序指的是什么意思呢?
在上图中,下方的英文单词集合便是一个偏序集。偏序指的是允许集合中的任意两个元素不存在可比性,比如单词 pin 和 sin 之间不存在子串关系。也就是说:没有必要让集合中的任意两个元素满足 ⊑。
4,当 P 为集合 {a ,b ,c} 的幂集,⊑ 为一个集合是另一个集合的子集关系时。(P, ⊑) 是一个偏序集。
上界和下界
定义如下:Given a poset (P, ⊑) and its subset S that S ⊆ P, we say that
u ∈ P is an upper bound of S, if ∀x ∈ S, x ⊑ u. Similarly,
l ∈ P is an lower bound of S, if ∀x ∈ S, l ⊑ x.
注意:这里上界和下界针对的是偏序集 P 的子集 S。
最小上界和最大下界
定义如下:We define the least upper bound (lub or join) of S, written ⊔S,if for every upper bound of S, say u, ⊔S ⊑ u.
We define the greatest lower bound (glb, or meet) of S, written ⊓S, if for every lower bound of S, say l, l ⊑ ⊓S.
下图以幂集为例来说明这几个概念之间的区别:
Usually, if S contains only two elements a and b (S = {a, b}), then
⊔S can be written a ⊔ b (the join of a and b)
⊓S can be written a ⊓ b (the meet of a and b)
glb 和 lub的属性
一共有两个属性,见下图:
格(lattice)、半格、完备格、乘积格
格的定义:Given a poset (P, ⊑), ∀a, b ∈ P, if a ⊔ b and a ⊓ b exist, then (P, ⊑) is called a lattice .
也就是说:对于一个偏序集,如果任意两个元素对存在 lub 和 glb,它就是一个格。
例如:
1,当 P 为整数集合,⊑ 为小于等于关系时。(P, ⊑) 是一个格。
2,当 P 为英文单词集合,⊑ 为一个单词是另一个单词的子串关系时(比如 a ⊑ b ,意味着单词 a 是单词 b 的子串)参见上图。(P, ⊑) 不是一个格。 因为对于单词 pin 和 sin ,它们的 lub 在 P 中不存在。
3,当 P 为集合 {a ,b ,c} 的幂集,⊑ 为一个集合是另一个集合的子集关系时。(P, ⊑) 是一个格。
半格的定义:Given a poset (P, ⊑), ∀a, b ∈ P,
if only a ⊔ b exists, then (P, ⊑) is called a join semilattice
if only a ⊓ b exists, then (P, ⊑) is called a meet semilattice
完备格的定义:Given a lattice (P, ⊑), for arbitrary subset S of P, if ⊔S and ⊓S exist, then (P, ⊑) is called a complete lattice.
例如:
1,当 P 为整数集合,⊑ 为小于等于关系时。(P, ⊑) 不是一个完备格。因为对于所有正整数构成的子集,它不存在上界,也就不存在 ⊔S。
2,当 P 为集合 {a ,b ,c} 的幂集,⊑ 为一个集合是另一个集合的子集关系时。(P, ⊑) 是一个完备格。
乘积格的定义:Given lattices L1 = (P1, ⊑1), L2 = (P2, ⊑2), …, Ln = (Pn, ⊑n), if for all i, (Pi , ⊑i) has ⊔i (least upper bound) and ⊓i (greatest lower bound), then we can have a product lattice Ln = (P, ⊑) that is defined by:
• P = P1 × … × Pn
• (x1, …, xn) ⊑ (y1, …, yn) ⟺ (x1 ⊑ y1) ∧ … ∧ (xn ⊑ yn) (乘积格中两个元素满足偏序关系,等价于对应于每一个格中的两个元素满足偏序关系的交集)
• (x1, …, xn) ⊔ (y1, …, yn) = (x1 ⊔1 y1, …, xn ⊔n yn)(乘积格中两个元素的 lub,等价于对应于每一个格中的两个元素的 lub 的集合)
• (x1, …, xn) ⊓ (y1, …, yn) = (x1 ⊓1 y1, …, xn ⊓n yn)(乘积格中两个元素的 glb,等价于对应于每一个格中的两个元素的 glb 的集合)
并且有:乘积格是一个格。 如果一个乘积格是完备格的乘积,那么这个乘积格也是一个完备格。
数据流分析框架
见图:
对上图的说明:
其中 L 是包含抽象域 V 的一个格,并且具有一个 meet ⊓ o或者 join ⊔ 操作,在数据流分析中,一般取 lub 和 glb 中的一个,比如在 may analysis 中,采用 join ⊔,取 lub;在 must analysis 中,采用 meet ⊓,取 glb。
左下方采用 RDA 来说明,右下方为一个格,其中的每一个元素都是一个抽象域 V 。可以看到对 OUT[s1] 的值 {a} 和 OUT[s3] 的值 {b} 取 ⊔得到的结果为 {a,b},在 s2 上的转换函数令 IN[s2] = {a,b} 变为 OUT[s2] = {a,b,c},当然 OUT[s2] 也可以为 {a,b}。结合右下方的格来看,may analysis 的初始化为空,即 bottom,通过采用 join ⊔ 操作,不断地往 top 方向上靠拢。
单调性和不动点原理
在格上函数的单调性定义:A function f: L → L (L is a lattice) is monotonic if ∀x, y ∈ L, x ⊑ y ⟹ f(x) ⊑ f(y) 。
不动点原理(定理):Given a complete lattice (L, ⊑), if
(1) f: L → L is monotonic and (2) L is finite, then
the least fixed point of f can be found by iterating
f(⊥), f(f(⊥)), …, fk(⊥) until a fixed point is reached
the greatest fixed point of f can be found by iterating
f(T), f(f(T)), …, fk(T) until a fixed point is reached
这里简单提一句:对于 may analysis ,它是从 bottom 向 top 变化的,不动点原理告诉我们从 ⊥ 出发不断的迭代函数 f ,最后得到的不动点是最小不动点,也就是最优的一个不动点。对于 may analysis ,它一定存在一个最大的不动点 T,在前面的示例中为 11111…111。must analysis 刚好相反,它一定存在一个最小的不动点 ⊥,在前面的示例中为 0000…000。
关于不动点原理的证明,一是要证明不动点原理的存在,二是要证明所得的不动点为最优的一个。下面仅证明从 ⊥ 出发的红色语句。
最小不动点的证明中:因为通过不动点原理假设在 k 次迭代得到的不动点小于任意存在的一个不动点( fFix = fk(⊥) ⊑ x ),所以得证。
对前面问题的回答
问题1:算法能够保证一定会停止吗或者一定能够达到不动点吗?即迭代算法真的能产生一个解决方案吗?
可以,回忆之前提到的 OUT 的增长是单调的,总会存在一个极限。 may 最大为 T, must 最小为 ⊥。
问题2:如果问题1的回答是肯定的话,那是否只有一个不动点或一个解决方案?如果解决方案多于一个的话,迭代算法得到的会是最优的吗?
对于一个函数来讲,只要满足 x = f(x) 即可称 x 为不动点,所以不动点并不唯一。目前我们知道的是根据不动点原理得到的不动点是最优的,而迭代算法是单调的,并且抽象域的大小是有限的,它满足不动点原理的应用条件,所以迭代算法得到的结果是最优的。
问题3:什么时候迭代算法能够达到不动点,即什么时候能够得到解决方案?
上面得到的结论是迭代次数的最大值,即最多迭代 i 次就可以达到不动点。其中节点数量 k 很好理解,而格的高度 h 在数据流分析指的是抽象域的大小,上图中幂集格对应的就是抽象域的大小为 3 的数据流分析。
从格的角度来看 may 、must analysis
宝藏图片如下,这个图片详细介绍了两种数据流分析的特点:
右边的 may analysis 是 reach definition analysis,最下方为初始化值 ⊥ ,表示在每一个程序点没有一个 definition 能够达到,这是一个不安全的结论(或者说是错误的结论);最上方为 T ,表示在每一个程序点每一个 definition 都可能达到,这是一个安全但是无用的结论(正确但无用)。而迭代算法需要从 unsafe → safe,在 safe 中有多个不动点,其中最小不动点处精度最高,而迭代算法到达的便是最小不动点。 must analysis 类似。
另一种角度来解释最小、最大不动点。以 may 的最小不动点为例,算法迭代意味着一次次地执行控制流处理和转换函数,其中,转换函数是比较固定的,因为每一个基本块的 genB 和 killB 是不变的。而控制流处理在 may 中采用的 join U ,执行结果为两个元素的最小上界。例如:000 U 001 = 001, 010 U 100 =110 … 而不会一下子就得到 111 。因为在迭代中,我们每次取的都是最小的一步,所以最后达到的不动点必然是最小不动点。
MOP 和迭代算法的精度
Meet-Over-All-Paths Solution (MOP)指的是分别在 entry 到 exit 之间的每一条路径上执行转换函数,然后将每一条路径的最终结果进行控制流处理。在某些路径不执行的情况下仍进行控制流处理是不精确的,在碰到循环时无法确定边界,在大型程序中路径的数量很多的,不可枚举,所以它不太实用。见下图:
在下面的例子上看看迭代算法和 MOP 的差别:
证明如下:
采用比特位向量或者用 与和或 来代替 join和meet的 Gen/Kill 问题,是可分配的(distributive)。
工作集算法(Worklist Algorithm)
工作集算法是对迭代算法的优化,在迭代算法的一次迭代中,可以发现,如果某个 OUT[B] 在上一次迭代之后没有变化,那么在下一次迭代中仍然会重复计算 OUT[B]。为了减少这种不必要的运算,引入了工作集算法,算法的思路比较简单,就不谈了。算法如下:
总结
本文主要介绍了格理论的相关知识,并应用到了数据流分析的迭代算法中,从理论上证明了迭代算法的一些优良特性。从格的视角总结了 may、must analysis的差异性,并对迭代算法的进一步优化产生了工作集算法。后面会单独介绍常量传播分析(Constant Propagation Analysis),这会是一个在格上进行数据流分析的不错的练习。未完待续~
分享一首小阿七的歌曲《酒家》:https://www.bilibili.com/medialist/play/ml1297618174/BV1Z5411b7YX