« 上一篇下一篇 »

活跃变量分析

有些代码改进转换所依赖信息是按照程序控制流的相反方向进行计算的,我们现在将要研究这样的一个例子。在活跃变量分析(live-variable analysis)中,我们希望知道对于变量x和程 序点P, *在点上的值是否会在流图中的某条从点P出发的路径中使用。如果是,我们就说x在 p上活跃,否则就说*在p上是死的。

活跃变量信息的重要用途之一是为基本块进行寄存器分配。这个问题的某些方面,在一个值被计算并保存到一个寄存器中后,它很可能会在基本块中使用。如果它在基本块的结尾处是死的,就不必在结尾处保存这个值。另外,在所有寄存器都被占用时,如果我们还需要申请一个寄存器的话,那么应该考虑使用一个存放了已死亡的值的寄存器,因为这个值不需要保存到内存。

这里我们直接以IN[B]和OUT[B]的方式定义数据流方程。IN[B]和OUT[B]分别表示在紧靠基本块B之前和紧随B之后的点上的活跃变量集合。这些方程可以通过以下的方法得到:首先定义各个语句的传递函数,然后再把它们组合起来得到一个基本块的传递函数。我们给出下面的定义:

1)defb是指如下变量的集合,这些变量在中的定值(即被明确地赋值)先于任何对它们的使用。

2)useB是指如下变量的集合,它们的值可能在S中先于任何对它们的定值被使用。

基本块B2 一定使用了i0除非i和)互为对方的别名,否则会在对j的任何重新定值之前使用假设图9-13中的变量之间没有别名关系,那么useB2 ={i,j}另外, b2显然对i和j定值。假设没有别名问题,因为B2在定值之前使用了i和j,所以defB2 ={ }。

根据这些定义,useB中的任何变量都必然被认为在基本块B的人口处活跃,而defB中的变 量在B的开头一定是死的。实际上,defB中的成员“杀死”了某个变量可能因从B开始的某条路径而成为活跃变量的任何机会。

这样,把def和use与未知的IN和OUT值联系起来的方程定义如下:

IN [EXIT] = 空 且对于所有的不等于EXIT的基本块B来说:

IN[B] =useBU(OUT[B] -defB)

OUT[B] =U  s是b的一个后继 IN[s]

第一个方程描述了边界条件,即在程序的出口处没有变量是活跃的。第二个方程说明一个变量要在进入一个基本块时活跃,必须满足下面两个条件中的一个:要么它在基本块中被重新定值之前就被使用;要么它在离开基本块时活跃且在基本块中没有对它重新定值。第三个方程说一个变量在离开一个基本块时活跃当且仅当它在进入该基本块的某个后继时活跃。

应该注意一下活跃性方程和到达定值方程之间的关系:

两组方程都以并集运算作为交汇运算。其原因是在各个数据流模式中,我们都沿着路径传播信息,并且我们只关心是否存在任何路径具有我们想要的性质,而不是关心某些结。

« 上一篇下一篇 »