首页 理论教育 编译原理与实践:快速删除无用代码

编译原理与实践:快速删除无用代码

时间:2023-11-17 理论教育 版权反馈
【摘要】:比如,在例8.2的基本块L3中,变量T3、T4、T5在程序中不再使用,可将其赋值语句全部删除,这对程序的计算结果来说没有任何影响。经过优化,可以得到如下的L3代码序列:T0:=3.14 B:=AT1:=2*T0 T6:=R-rT2:=R+r B:=A*T6A:=T1*T2删除无用代码,包括删除不可到达代码和删除死代码两种技术。二者是不同的,其区别在于被删除的代码是否有机会被执行。

编译原理与实践:快速删除无用代码

进行了复写传播优化变量在程序中不再使用,因此,可以将其删除掉。比如,在例8.2的基本块L3中,变量T3、T4、T5在程序中不再使用,可将其赋值语句全部删除,这对程序的计算结果来说没有任何影响。经过优化,可以得到如下的L3代码序列:

(5)T0:=3.14 (9)B:=A

(6)T1:=2*T0 (10)T6:=R-r

(7)T2:=R+r (11)B:=A*T6

(8)A:=T1*T2

删除无用代码,包括删除不可到达代码和删除死代码两种技术。二者是不同的,其区别在于被删除的代码是否有机会被执行。下面对这两种技术分别进行介绍。

1.删除不可到达代码

所谓不可到达的代码,是指无论输入任何数据均不可能被执行的代码。删除这些代码对程序的执行速度没有直接影响,但会节约程序所占用的存储空间。

若要删除不可到达的代码,首先必须能够识别出它们。正确的做法是:设计一个基本块表,用它来记录程序所有的基本块,并且明确记录各个基本块的前驱和后继集合;然后,对基本块表进行迭代,从中找出那些无法从程序的入口基本块到达的基本块,即,从入口基本块到达这些基本块的路径集合为空;最后,删除这些基本块,并对其前驱和后继进行相应的调整。算法实现的具体代码如下:

2.删除死代码(www.xing528.com)

所谓死代码,是指那些可执行的、但对要执行的结果不起作用的代码。死变量指的是,仅对该变量进行了定值,而定值之后却从来没有使用过它。因此,对该变量的定值代码就是死代码。但是有些代码含有隐含的副作用,如根据计算机配置,算术溢出或者算数除零导致的异常,删除这样的代码会改变计算的结果。这样的删除虽然是有利的,但是对优化器而言,改变了程序的行为,这是不允许的。

与删除不可到达的代码一样,若要删除死代码,首先必须能够识别出它们。正确的做法是:先确定那些有必要去处理的值,包括程序的输出值和返回值,以及在过程外能够影响某个存储单元的值;然后,通过迭代标示出所有对该必要值(必要值指的是过程一定要输出或者返回的值,或者是对过程之外访问内存单元有影响的值)的计算起作用的代码;最后,删除那些没有被标示的代码,即死代码。

具体实现时,使用工作表、UD链和DU链来识别死代码。假设在程序中的某点U引用了变量A的值,则把能到达U的关于A的所有定值点的全体,称为A在引用点U的UD链(引用-定值链);而将变量A的定值点D能够到达的对A的引用点的全体,称为A的定值点D的DU链(定值-引用链)。算法描述如下:

(1)用必要指令的基本块索引偶对(形如<a,b>,其中a表示基本块编号,b表示该指令在此基本块中的位置)集合初始化工作表。

(2)从工作表中删除一个偶对<i,j>,对在这条指令中使用的每一个变量V,标识它的UD链UD(V,<i,j>)中的每条指令,并将该指令的基本块索引偶对加入工作表中。

(3)若指令为赋值语句,则对于其DU链DU(V,<i,j>)中的每一个指令位置<k,l>,如果指令<k,l>是一个条件指令if,则标识它并将其加入工作表中。

(4)重复(2)和(3),直至工作表为空。

(5)删除未标识的指令及空的基本块。

算法实现的具体代码是:

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈