370 likes | 530 Views
第十一章 代码优化. 编译原理. 计算机系 张熠. 11.1 优化技术简介 所谓 优化 ,实质上是对代码进行 等价变换 ,使得变换后的代码 运行结果 与变换前代码运行结果相同,而运行 速度加快 或 占用存储空间减少 ,或两者都有。 一般优化工作可在中间代码生成之后或目标代码生成之后进行。. 中间代码的优化是对中间代码进行等价变换,目标代码的优化时在目标代码生成之后进行的,这很大程度上依赖于具体的机器。. 源代码. 前端. 中间代码. 代码生成. 目标代码. 中间代码优化. 目标代码优化. 编译的优化工作阶段. 例 11.1 程序优化示例.
E N D
第十一章 代码优化 编译原理 计算机系 张熠
11.1 优化技术简介 • 所谓优化,实质上是对代码进行等价变换,使得变换后的代码运行结果与变换前代码运行结果相同,而运行速度加快或占用存储空间减少,或两者都有。 • 一般优化工作可在中间代码生成之后或目标代码生成之后进行。 数学与信息工程学院 计算机系
中间代码的优化是对中间代码进行等价变换,目标代码的优化时在目标代码生成之后进行的,这很大程度上依赖于具体的机器。中间代码的优化是对中间代码进行等价变换,目标代码的优化时在目标代码生成之后进行的,这很大程度上依赖于具体的机器。 源代码 前端 中间代码 代码生成 目标代码 中间代码优化 目标代码优化 编译的优化工作阶段 数学与信息工程学院 计算机系
例11.1程序优化示例 • p = 0 • i = 0 int p, a[20], b[20], i; p = 0; for (i=0; i<20;i++) p = p + a[i] * b[i]; (3) T1 = 4*i (4) T2 = addr(a) (5) T3 = T2[T1] (6) T4 = 4*i (7) T5 = addr(b) (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (12) if i<20 goto (3) 数学与信息工程学院 计算机系
11.1.1 删除多余运算 • 优化的目的在于使目标代码执行速度加快。 • (3)和(6)都有4*i的运算,而且从(3)到(6) i的值没有变,故我们可以把(6)变换成T4 = T1。 • p = 0 • i = 0 (3) T1 = 4*i (4) T2 = addr(a) (5) T3 = T2[T1] (6) T4 = 4*i (7) T5 = addr(b) (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (12) if i<20 goto (3) 数学与信息工程学院 计算机系
11.1.2 代码外提 • 减少循环中代码总数的一个重要方法就是代码外提。 • p = 0 • i = 0 (3) T1 = 4*i (4) T2 = addr(a) (5) T3 = T2[T1] (6) T4 = T1 (7) T5 = addr(b) (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (12) if i<20 goto (3) 数学与信息工程学院 计算机系
p = 0 • i = 0 • T1 = 4*i • (4) T2 = addr(a) • (7) T5 = addr(b) • 11.1.3 强度削弱 • 强度削弱的思想是把强大的运算换算成强度小的运算。如把乘法运算转化成加法运算或移位运算等。 (5) T3 = T2[T1] (6) T4 = T1 (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (3’) T1 = T1+4 (12) if i<20 goto (5) 数学与信息工程学院 计算机系
p = 0 • i = 0 • T1 = 4*i • (4) T2 = addr(a) • (7) T5 = addr(b) • 11.1.4 变换循环条件 • 由于i和T1始终保持4倍的线性关系,故可以用T1<80来替换i<20,从而删除i变量。 (5) T3 = T2[T1] (6) T4 = T1 (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (3’) T1 = T1+4 (12) if i<20 goto (5) 数学与信息工程学院 计算机系
p = 0 • i = 0 • T1 = 4*i • (4) T2 = addr(a) • (7) T5 = addr(b) • 11.1.5 合并已知量与复写传播 • 由于i=0,故一开始T1的值是确定的,即在编译时就能确定它们的值。 • (6)中把T1的值复制给T4,而从(6)到(8)T1的值没有改变,故将T1替换T4。 (5) T3 = T2[T1] (6) T4 = T1 (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (3’) T1 = T1+4 (12) if T1<80 goto (5) 数学与信息工程学院 计算机系
p = 0 • i = 0 • T1 = 0 • (4) T2 = addr(a) • (7) T5 = addr(b) • 11.1.6 删除无用赋值 • (6)对T4赋值,(2),(11)对i赋值,但程序的其他地方未引用T4和i,称之为无用赋值,可从程序中删除。 (5) T3 = T2[T1] (6) T4 = T1 (8) T6 = T5[T1] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (3’) T1 = T1+4 (12) if T1<80 goto (5) 数学与信息工程学院 计算机系
p = 0 • T1 = 0 • (4) T2 = addr(a) • (7) T5 = addr(b) • p = 0 • i = 0 (3) T1 = 4*i (4) T2 = addr(a) (5) T3 = T2[T1] (6) T4 = 4*i (7) T5 = addr(b) (8) T6 = T5[T4] (9) T7 = T3 * T6 (10) p = p+T7 (11) i = i+1 (12) if i<20 goto (3) (5) T3 = T2[T1] (8) T6 = T5[T1] (9) T7 = T3 * T6 (10) p = p+T7 (3’) T1 = T1+4 (12) if T1<80 goto (5) 数学与信息工程学院 计算机系
11.2 局部优化 • 局部优化是指基本块内的优化。所谓基本块是指程序中一个程序执行的语句序列,其中只有一个入口语句和一个出口语句。执行时只能从其入口语句进入,从其出口语句退出。 数学与信息工程学院 计算机系
11.2.1 基本块的划分 • 判定入口语句的规则: • 1、程序的第1个语句; • 2、条件转移语句或无条件转移语句的转移目标语句; • 3、紧跟在条件转移语句后面的语句。 数学与信息工程学院 计算机系
有了入口语句的概念之后,即可划分基本块: 有了入口语句的概念之后,即可划分基本块: • 1、求出各个基本块的入口语句; • 2、对每一个入口语句,构造基本块,即从该入口语句到下一个入口语句; • 3、未被纳入某一个基本块的语句,为程序控制流程无法到达的语句,应予以删除。 数学与信息工程学院 计算机系
例11.2 划分下列程序基本块 可划分成四个基本块 (1)read (C) (2) A:= 0 (3) B:= 1 (4) L1: A:=A + B (5) if B>= C goto L2 (6) B:=B+1 (7) goto L1 (8) L2: write (A) (9) halt (1) (2) (3) B1 B2 (4) (5) (6) (7) B3 (8) (9) B4 数学与信息工程学院 计算机系
11.2.2 基本块的变换 • 很多变换可作用于基本块而不改变它计算的表达式集合。有两种重要的局部等价变换,分别为保结构变换和代数变换。 数学与信息工程学院 计算机系
保结构变换 • 1、删除公共子表达式 • 2、删除无用代码 • 3、重新命名临时变量 • 如:t = b+c 变换成 u = b+c • 4、交换语句次序 • 如:a = x+y b = m+n • 变换成:b = x+y a = m+n 数学与信息工程学院 计算机系
代数变换 • 将较复杂的运算变换成较简单的运算,或者将一些函数调用转换成等价运算。 • 如:y = pow(x,3) 变换成 y = x*x*x 数学与信息工程学院 计算机系
11.2.3 基本块的有向图DAG表示 • 有向边: ni→nj • 前驱:ni为nj的前驱(父结点) • 后继:nj为ni的后继(子结点) • 环路:有一个有向图序列n1→n2→n3… →nk,若n1=nk,则称其为环路。 • DAG:如果有向图中任意一条通路都不是环路,则称该有向图为无环有向图,简称DAG。 数学与信息工程学院 计算机系
n1 n1 n2 n2 n3 n4 n3 n4 数学与信息工程学院 计算机系
11.2.4 四元式与DAG结点 • (0) A = B (=, B, -, A) • (1) A = op B (op, B, -, A) • (2) A = B op C (op, B, C, A) • (3) A = B[C] (=[], B[C], -, A) • (4) if B rop C goto(s) (jrop, B, C, (s)) • (5) D[C] = B ([]=, B, -, D[C]) • (6) goto(s) (j, -, -, (s)) n1 n1 A B n2 A n2 op n1 n1 B A n3 op n2 n1 n2 n1 B C 数学与信息工程学院 计算机系
例11.3构造以下基本块的DAG (1) T0 = 3.14 (2) T1 = 2 * T0 (3) T2 = R+r (4) A = T1*T2 (5) B = A (6) T3 = 2 * T0 (7) T4 = R+r (8) T5 = T3*T4 (9) T6 = R-r (10) B = T5*T6 (11) if B<10 goto (1) B n8 * A T5 n6 * n5 n7 T2 T4 T6 + - T1 T3 n1 n2 n3 n4 T0 3.14 6.28 R r 数学与信息工程学院 计算机系
11.2.5 DAG的应用 • 将四元式表示成相应的DAG后,可以利用DAG来进行优化。 数学与信息工程学院 计算机系
将例11.3中的DAG重新写成四元式 B n8 (1) T0 = 3.14 (2) T1 = 6.28 (3) T3 = 6.28 (4) T2 = R+r (5) T4 = T2 (6) A = 6.28 * T2 (7) T5 = A (8) T6 = R-r (9) B = A*T6 * A T5 n6 * n5 n7 T2 T4 T6 + - T1 T3 n1 n2 n3 n4 T0 3.14 6.28 R r 数学与信息工程学院 计算机系
G’与G相比: • G中的(2)和(6)的已知量已合并; • G中(5)的无用赋值已被删除; • G中(3)和(7)的公共子表达式R+r只被计算一次。 G (1) T0 = 3.14 (2) T1 = 2 * T0 (3) T2 = R+r (4) A = T1*T2 (5) B = A (6) T3 = 2 * T0 (7) T4 = R+r (8) T5 = T3*T4 (9) T6 = R-r (10) B = T5*T6 (11) if B<10 goto (1) G’ (1) T0 = 3.14 (2) T1 = 6.28 (3) T3 = 6.28 (4) T2 = R+r (5) T4 = T2 (6) A = 6.28 * T2 (7) T5 = A (8) T6 = R-r (9) B = A*T6 (10) if B<10 goto (1) 数学与信息工程学院 计算机系
在例11.2中假设T0,T1,…,T6在基本块后没有被引用,则根据DAG重写为如下代码序列: G’ (1) S1 = R+r (2) A = 6.28 * S1 (3) S2 = R-r (4) B = A*S2 数学与信息工程学院 计算机系
11.3 控制流分析和循环优化 • 在一个程序流程中,循环是必不可少的一种控制结构。所谓循环就是程序中可能反复执行的代码序列。 • 因为循环中的代码要反复执行,因而为了提高目标代码的效率必须着重考虑循环的代码优化。 数学与信息工程学院 计算机系
11.3.1 程序流图 • 一个控制流程图就是具有唯一首结点的有向图,所谓首结点就是从它开始到控制流程图中任何结点都有一条通路的结点。 • 控制流程图可表示成一个三元组G=(N, E, n0),其中N代表图中所有结点集,E代表图中所有有向边集, n0代表首结点。 数学与信息工程学院 计算机系
假设结点i和结点j分别对应于程序的基本块i和基本块j,当下述条件: • 1、基本块j在程序中的位置紧跟在基本块i之后,并且基本块i的出口语句不是无条件转移语句或停语句; • 2、基本块i的出口语句是goto(s)或if…goto(s),并且(s)是基本块j的入口语句。 • 有一个成立时,从结点i有一有向边引向结点j。 数学与信息工程学院 计算机系
例11.4构造以下程序的流图 (1) read x (2) read y (3) r = x mod y (4) if r=0 goto (8) (5) x = y (6) y = r (7) goto (3) (8) write y (9) halt 数学与信息工程学院 计算机系
11.3.2 循环的查找 • 为了找出控制流图中的循环,需要分析流图中结点的控制关系。为此,我们引入必经结点和必经结点集。 • 对于任意两个结点m和n而言,如果从流图的首结点出发,到达n的任意一条通路都经过m,则称m为n的必经结点,记为m DOM n。流图中结点n的所有必经结点的集合,称为结点n的必经结点集,记为D(n)。 • 对流图的任意结点a,有a DOM a。 数学与信息工程学院 计算机系
右图各结点的D(n)如下: • D(1) = {1} • D(2) = {1, 2} • D(3) = {1, 2, 3} • D(4) = {1, 2, 4} • D(5) = {1, 2, 4, 5} • D(6) = {1, 2, 4, 6} • D(7) = {1, 2, 4, 7} 1 2 3 4 5 6 7 数学与信息工程学院 计算机系
应用必经结点集可求出流图中的回边,利用回边即可找出循环。 • 所谓回边,即假设a→b是流图中的一条有向边,如果b DOM a,则称a→b是流图中的一条回边。 • 从流图中可以看出,有向边6→6、7→4、4→2是回边。 • 如果已知有向边a→b是回边,那么就可以求出由它组成的循环。该循环由结点b、结点a以及有通路到达a而该通路不经过b的所有结点组成,并且b是该循环唯一入口。 数学与信息工程学院 计算机系
例11.5找出例11.4的循环 (1) (2) B1 (1) read x (2) read y (3) r = x mod y (4) if r=0 goto (8) (5) x = y (6) y = r (7) goto (3) (8) write y (9) halt B2 (3) (4) B3 B4 (5) (6) (7) (8) (9) 数学与信息工程学院 计算机系
11.3.3 循环优化 • 代码外提 • 强度削弱 • 删除归纳变量 数学与信息工程学院 计算机系