编译原理 第九章 代码优化

  • 格式:ppt
  • 大小:831.00 KB
  • 文档页数:31

下载文档原格式

  / 31
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第9章 代码优化
9.1 代码优化概述
9.2 局部优化
9.3 控制流程分析和循环优化
9.4 数据流分析
9.1 代码优化概述

代码优化 代码优化的层次


代码优化的评价
代码优化实例
代码优化:时空
寄存器、多处理器、 特殊指令优化等
代码优化的层次

窥孔优化:目标代码级别,滑动窗口 局部优化:中间代码级别,以基本块为单位 循环优化:目标代码级别,针对循环 全局优化:中间代码级别,过程内
*(8) write Y
(9) halt
循环的查找
循环优化 => 寻找循环 => 循环定义 入口---唯一性 直观上循环的构成 返回到入口的反向边---回边 结点互通 直观上,入口结点是循环中其它结点的必经结点。
在程序流图中,对任意两个结点m和n,如果从流图的首结点出 发,到达n的任意通路都要经过m,则称m是n的必经结点,记 为m DOM n (a,a DOM a) 结点n的所有必经结点的集合,称为结点n的必经结点集D(n).
6
A, B
(7) T4=R+r +
n6 A, B * (6) A= 6.28*T2 (2) A=6.28*T2 n5 T2 (7) T T 5=A + 1, T3 6= R−r n(3) n3 n4 n2 1 T0 T T6=R R−r r 3.14 (8) 6.28
TT1 0=3.14 n 5 T 2 若(1) T0、 、… 、 T6 + (2) T 1=6.28 T0 n2 T1 n n1 在基本快后面不 n4 3 (3) 6.28 T3=6.28 3.14 R r 被引用,则: T2:= R + r (4) (3) T2=R+r (1) T2=R+r (5) T4=T2
i j
①基本块 j 在程序的位置紧跟在 i 后,且 i 的出口语句不是转 移或停语句 ②i 的出口是 goto(S)或 if goto(S),而(S)是 j 的入口语句
例如,考察下面求最大 公因子的三地址代码 程序: *(1) read X (2) read Y *(3) R=X % Y (4) if(R==0) goto(8)
DAG(Directed Acyclic Graph): 无环有向图
基本块的DAG是在结点上带有标记的DAG:
结点形式:
ni X
标记
编号
变量A,…具 有所代表的值
A,B,…
运算符(OP)---内部结点 标识符 常数 叶结点
一个基本块=>一个DAG(体现基本块内各语句的联系)

利用DAG进行基本块优化的基本思想是:
前置结点
入口结点
入口结点
¡
循环L
循环L
图5–8 给循环建立前置结点
¡
9.3 代码优化示例
通过一个快速排序子程序来了 解代码优化的全过程。 do j=j−1; while(a[j]>v); void quicksort (int m, int n) if(i>=j) break; {int i, j, v, x; x=a[i]; a[i]=a[j]; a[j]=x; if(n<=m) return; } /*fragment begins here*/ x=a[i]; a[i]=a[n]; a[n]=x; i=m−1; /*fragment ends here*/ j=n; quicksort(m, j); v=a[n]; while(1) quicksort(i+1,n); {do i=i+1; while(a[i]<v); }
常数传播
_tmp3 = 0 ; f0 = _tmp3 ; f0 = 0 ;
代数化简
削弱运算强度
a) i*2 = 2*i = i+i = i<<2 x+0 = x 0+x = x b) i/2 = (int)(i*0.5) x*1 = x c) f*2 = 2.0 * f = f + f 1*x = x 0/x = 0 复写传播 x-0 = x tmp2 = tmp1 ; b && true = b tmp3 = tmp2 * tmp1; b && false = false tmp5 = tmp3 * tmp2 ; b || true = true b || false = b tmp3 = tmp1 * tmp1 ; tmp5 = tmp3 * tmp1 ;
复写传播
删除多余运算 循环不变代码外提 变换循环控制条件 删除无用赋值
常数合并
a = 10 * 5 - b; _tmp0 = 10 ; _tmp1 = 5 ; _tmp2 = _tmp0 * _tmp1 ; _tmp3 = _tmp2 – b; a = _tmp3 ; _tmp0 = 56 ; _tmp1 = _tmp0 – b ; a = _tmp1 ;
n1 T0 n2 n3 3.14 6.28 R (9) T6:=R-r
T1, T3
n1 T0 n 1 3n3 n4 2 3.14 6.28 R r ( 10 ) B:=T5*T6
T ,T
9.3 控制流分析和循环优化
一个控制流程图(简称流图)就是具有惟一首结点的有向图。 所谓首结点,就是从它开始到控制流程图中任何一个结 点都有一条通路的结点。 有向边
代码优化的理论基础

相关的描述工具:
中间表示:四元式
DAG图
控制流图 数据流方程

问题复杂度:往往是NP 完全或NP难
简化,小规模问题

优化算法

代码优化的基本过程


代码的描述
数据流分析(data-flow analysis)


控制流分析(control-flow analysis)
D(1)={1} D(2)={1,2}
1
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}
2
{2,3,4,5,6,7}
4
3
{4,5,6,7}
6
{6}
7
5
回边: a 入口 。 d a→b是流图中的一条有向边,如果b DOM d---回边:6 ->6、7->4、4->2 回边: n k d 循环L n 循环:回边a→b组成的循环是由结点b、a以及有通路到达 a而该通 k k * n 不经d 路不经过 n b的所有结点组成,并且b是该循环的唯一入口结点。
①删除多余运算
(3’) T1:= T1+4
(1) P:=0 (4) T2:=addr(A)-4 (7) T5:=addr(B)-4 (3) T1:=4
(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)
n6 A * n5 T2 + n1 T0 n2 T1 n3 n4 3.14 6.28 R r (4) A:=T1*T2 n6 A, B * n5 T2, T4 + T1, T3 n1 T0 n2 n4 n3 r 3.14 6.28 R (7) T4:= R + r n8 B * n6 A, T5 * T2, T4 n7 T6 n5 +
变换 (transformations)
9.2 局部优化:基本块内的优化
基本块:是指程序中一顺序执行的语句序列,其中只有一个 入口语句和一个出口语句。 入口语句: 程序的第一个语句;或者, 条件转移语句或无条件转移语句的转移目标语句;或者 紧跟在条件转移语句后面的语句。 划分基本块的算法: 求出四元式程序之中各个基本块的入口语句。 对每一入口语句,构造其所属的基本块。它是由该语句到 下一入口语句(不包括),或到一转移语句(包括),或 到一停语句(包括)之间的语句序列组成的。 凡未被纳入某一基本块的语句,把它们删除。
(4) B=A*T 60 (6) T3:=2*T (9) B=A*T 6
n6 A, B, T5 * T2, T4 n7 T6 n5 + n4 r
(10) B=T5*T6
n6 A, B, T5 * n5 T2, T4 +
T ,T n1 T0 n2 1 3n n4 3 3.14 6.28 R r (8) T5:=T3*T4
(1)
read (C)
(2)
(3)
A:= 0
B:= 1
(4) L1: A:=A + B
(5)
(6) (7) (9)
if B>= C goto L2
B:=B+1 goto L1 halt 基本块内实行的优化: 合并已知量 删除多余运算 删除无用赋值
(8) L2: write (A)
基本块的DAG表示及其应用
n3 A op n1 n2 B C (3) A=B op C n4
[]=
n3 =[] n1 B (4) A=B[C] n2 C
n1 B (5) if B rop C
n2 C goto S
n1 D
n2 C (6) D[C]=B
n3 B
n1 (S)
(7) goto S
图5–1 四元式与DAG结点
(1) T0=3.14 (2) T 1=2*T0 T
n1 n2 T1 n1 0 (3) T2=R+r 3.14 6.28 3.14 (1) T0 A=T :=3.14 (2) T1 :=2*T0 (4) 1*T2
(5) B=A n
* (6) T3=2*T0 n5 T2 T n1 T0 n2 1 n3 n4 (8) T5=T3*T4 r 3.14 6.28 R (5) :=A (9) T 6= B R−r
优化技术实例: P:=0 for I:=1 to 20 do P:=P+A[I]*B[I]
②代码外提 ⑤复写传播
(1) P:=0 (2) I:=1 P:=0 (4) (1) T2:=addr(A)-4 I:=1 (7) (2) T5:=addr(B)-4
(3) T1:=4
③强度削弱
⑥删除无用赋值
④变换循环控ቤተ መጻሕፍቲ ባይዱ条件
(3) T1:=4*I (4) T2:=addr(A)-4 (5) T3:=T2[T1] (6) T4:=4*I T4:=T1 (6) (7) T5:=addr(B)-4 (8) (8) T6:=T5[T4] T6:= T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (12) if T1<=80 goto(5) (12) I<=20 goto(3)
代码优化评价

优化效率:
优化前后代码性能的提高
基准测试程序,相同运行环境

优化开销:
优化所花费的代价:时间、存储空间等

不同方法对不同程序的优化效果不同
取决于程序本身的算法

不同优化方法同时使用可能有副作用
基本优化技术

合并已知量 常数传播 代数化简 强度削弱


(1) read X (2) read Y
B1
(3) R=X % Y B2 (4) if (R==0) goto(8)
(5) X=Y B3 (6) Y=R (7) goto(3)
1 2 3 4
(8) write Y (9) halt
B4
*(5) X=Y
(6) Y=R (7) goto(3)
图5–21给出了程序中两个注解行之间的语句翻译成中间代 码序列后所对应的程序流图,其代码优化如下。
1.删除公共子表达式

在B5中分别把公共子表达式4*i和4*j的值赋给T7和T10,因 此这种重复计算可以消除,即B5中的代码变换成: B5:T6=4*i 可以在更大范围内来考虑删除公共子 x=a[T6] 表达式的问题,即利用 B3 中的四元式 T7=T6 T4= 4*j 可以把 B5 中的代码 T8= 4*j 替换 T8=4*j 为T8= T4。 T9=a[T8] 同样,可以把 B5 中的代码 T6= 4*i 替换 a[T7]=T9 为 T6=T2 。对于 B6 也可以同样考虑, T10=T8 最后,删除公共子表达式后的程序流 a[T10]=x goto B2 图如图5–22所示。
四元式序列 => DAG => 四元式序列 四类四元式:
0型四元式:后继结点个数为0,如图 (1)所示; 1型四元式:有一个后继结点,如图(2)所示;

2型四元式:有两个后继结点,如图(3)(4)(5)
3型四元式:有三个后继结点,如图(6)所示。
n1 A B (1) A=B
n2 A op n1 B (2)A=op B n3 (S) rop