活跃分析

活跃分析

liveness analysis:编译器在分析程序的中间表示时,需要确定哪些临时变量同时被使用。如果一个变量的值将来还需要使用,那么这变量就是live的。

为了对程序进行分析,我们可以看这样的控制流图:

img

因此可以得出:a的活跃范围是[1->2, 4->5->2],b的活跃范围是[2->3,3->4],至于变量c,在进入这段程序时就是活跃的,它有可能是一个形参。如果c是局部变量,活跃分析就可以发现它未初始化,从而给出warning。

数据流方程的解

活跃性:一个变量在一条边上的活跃是指,如果存在一条从这条边指向该变量的一个use的有向路径,并且路径不经过该变量的任何def。

活跃性计算

入口和出口活跃信息:

  • 如果一个变量属于use[n],那么它在结点n是入口活跃的;
  • 如果一个变量在结点n是入口活跃,那么它在所有属于pred[n]的结点m中都是出口活跃的;
  • 如果一个变量在结点n是出口活跃的,而且不属于def[n],那么该变量在结点n是入口活跃的;

为了加快迭代速度,我们可以沿着箭头的反方向追踪

集合的表现

表示数据流方程的集合至少有两种较好的方法:位数组或有序变量表。

集合稀疏的可以用有序表;集合密集的话,应该用位数组。

时间复杂度

实际的算法运行时间在\(O(N)-O(N^2)\)之间

最小不动点

数据流方程的任何一个解都只是保守的近似解,它提供的是报收信息,虽然不够准确可以得到非最优的方程,但绝不会是错误的程序。

静态活跃性与动态活跃性

动态活跃:如果程序的某个执行从结点n到a的一个使用之间没有经过a的任何定义,那么变量a在结点n是动态活跃;

静态活跃:如果存在一条从n到a的某个使用的控制流路径,且此路径上没有a的任何定义,则是静态活跃的;

冲突图

阻止将变量a和b分配到同一个寄存器的条件就叫冲突(interference)。冲突可以用无向图表示,图中的结点表示变量,每条边连接相冲突的两个变量。

添加冲突边的方法:

  • 对于任何对变量a定义的非传送指令,以及在该指令处是出口活跃的变量\(b_1,...,b_j\),添加冲突边\((a, b_1),...,(a, b_n)\)
  • 对于传送指令a<-c,如果变量\(b_1,...,b_j\)在该指令处是出口活跃的,为每一个不同于c的\(b_i\)添加冲突边\((a, b_1),...,(a, b_j)\)