上一篇文章是Point-to Analysis指针分析(1)
下面介绍一种新的指针分析的算法Steensgaard算法,并将其与上一篇文章介绍的Andersen算法相比较。
Steensgaard算法
不同于Andersen算法,Steensgaard在前者的基础上,再次对问题进行了简化,从而指针分析的速度变快了,但是损失了精度。
那么其究竟是如何的一个过程呢?
约束
前面都和Andersen算法过程及其类似,但是约束变了。
这个是Andersen的约束条件(其实就是上一篇文章中的那个表)。
Steensgaard改成了:
可以看到,区别就在于将子集关系直接换成了等号,从而使得指针分析变得大大简化,从而直接在线性时间分析完毕。(注意:这里的线性时间o(n)中的n是指:指针语句的个数。)
流程
Steensgaard算法的流程十分简单,如下,一看就懂。
假设有如下指针语句:
我们先看红色部分的指针语句,那么和Andersen算法一样,写出约束,然后初始化约束图(下面的约束图没有画出aryA,aryB节点,但是这不要紧)。
继续分析下一句:
写出约束,并完善约束图。
解释:第5个语句的函数调用过程其实是:
p=t1,q=t2
这个是函数的参数传递。所以根据上面两条我们可以写出约束(注意在Steensgaard中这个简单约束是等号):
然后将t1和p放在一起,形成一个集合,另外还要将pts(t1)和pts§放在一起,形成一个集合,但是由于此处p是首次定义,所以pts§为空集。
继续分析下一句:
写出约束,完善约束图:
看过我第一篇文章的话,这很容易理解,照葫芦画瓢而已。
下句tmp2=*q和上面步骤一样。
继续分析下下句
写出约束,完善约束图。(注意下面是等号,以红色为准)。
约束图变成:
解释:此处就完全体现了两次合并集合了,由于pts(PB)=pts(tmp1)
,所以PB和tmp1需要合并,最后成了
上面是第一个合并,第二次合并是pts(PB)
和pts(tmp1)
的合并,即:
分析最后一句,也是同样简单的。
发现即相当于想要pts(PA)=pts(tmp2)
,即想要PA和tmp2合并,以及他们的子集合并,但是已经合并了,所以无需更改。
至此就已经分析完毕了。
比较
从两种方法的约束定义可以看出来,Andersen是子集概念,Steensgaard是相等概念,反应到算法中就是直接粗暴合并。所以效率更高,损失精度。
时间复杂度:
- Steensgaard很快,几乎是线性。虽然有的时候合并会浪费一点时间,如上面的第9条指针语句,但是大多都很快,比如前4条指针语句,最后一条指针语句甚至没有任何改变。所以大概o(n),其中n是指针语句的个数。
- Andersen较慢,对于一条语句就可能是o(n^2)了,由于有n条指针语句,所以复杂度是
O
(
n
3
)
O(n^3)
O(n3)。
例子:
如果是Steensgaard怎么做呢?其不会指向d,e,f。而是将y与a,b,c和并,复杂度为1,而前者是9(3*3)。
以上就是指针分析的两个常用算法了,注意以上都是属于流不敏感的算法哦。
(ps:提供Steensgaard的论文给感兴趣的人阅读:Points-to analysis in almost linear time,或者自己去找这篇文章也能找到)。