编译原理6中间代码优化
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3> 基本块的 DAG 构造算法及优化 设 NODE(A)为一查找函数: 若 DAG 中存在值标记或附加 标记为 A 的结点 n ,则返回 n ; 否则 返回 null。 基本块的 DAG 构造算法如下: (1) 令 DAG=null; (2) for 基本块的 每一四元式 do { 若 NODE(A) 非空且未被引用,或有多个附加标记 , 则 删除附加标记 A; //(删除无用赋值) 根据四元式类型,分别转到 T0,T1,T2 处 T0 : //(:=, B, , A) 若NODE(B)= null { 生成值标记为 B 的叶结点 n} 否则 令 n= NODE(B); 把 A 作为n 结点的附加标记, 返回 (2) ;
流图 设四元式程序如下: (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 (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 B1
3
3>强度削弱 由于每次循环 I 都增加 1, 因此, T1递增 4 , 可把 (3) 改为 T1:=T1+4 ,放在(11)之后,并在 循环前对 I 赋初值 T1:=4*I. (12)改为 goto (5). 参见下页四元式表
(1) PROD:=0 (2) I:=1 (4) T2:=addr(A)-4 (7) T5:=addr(B)-4
(1) PROD:=0 (2) I:=1
(3) T1:=4*I (4) T2:=addr(A)-4 (5) T3:=T2[T1] (6) T4:=4*I (7) T5:=addr(B)-4 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (11) I:= I+1 (12) if I<=20 goto(3)
(3) 转移语句转移到的四元式
(5) 条件语句之后的第一条四元式 (8) 转移语句转移到的四元式 由此可以得到四个基本块.(见下页)
11
(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
参见下页四元式表
6
7>删除无用赋值 (2) 和 (6) 两四元式为无用 四元式,可以删除. 最终优化后, 得到下页四元式表
(1) PROD:=0 (2) I:=1 (4) T2:=addr(A)-4 (7) T5:=addr(B)-4 (3) T1:=4 (5) T3:=T2[T1] (6) T4:=T1 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (3’) T1:=T1+4 (12) if T1<=80 goto(5)
2
2>代码外提 (4)与(7)每次循环其值都 不变,称为循环不变量.可以放 到循环前,减少循环中的运算. 参见下页四元式表
(1) PROD:=0 (2) I:=1
(3) T1:=4*I (4) T2:=addr(A)-4 (5) T3:=T2[T1] (6) T4:=T1 (7) T5:=addr(B)-4 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (11) I:= I+1 (12) if I<=20 goto(3)
20
第三节
循环优化
循环是由循环语句,if 及 goto 语句构成. 为了找出中间代码程 序中的所有循环,就要对程序的流程进行分析,流程是以基本块为 单位的,因为基本块内无循环.
一 控制流程图与循环的定义
1>控制流程图的 定义: 控制流程图是具有唯一首结点的有向图,简称为流图.可表 示为三元式: G=( N,E,n0 ) N 为结点集,每 一结点为一基本块; E 为有向边,代表流向; n0为首结点,它包含了程序的第一条语句.
15
T1 : //(op, B, , A) 若 B 为已知量 // 合并已知量 { 执行 op B , 得到一新常数 p, 若NODE(p)= null { 生成值标记为 p 的叶结点 n} 否则 令 n= NODE(p); 把 A 作为n 结点的附加标记, 返回 (2) n } op 否则 若 DAG 中存在型如右式的子图 n1 B {则把 A 添加在 n 结点的右侧; B 返回 (2) } //合并多余运算 否则 {若NODE(B)= null { 生成值标记为 B 的叶结点 n1} 否则 令 n1= NODE(B); 建立一运算为 op ,附加标记为 A 的结点 n, 从 n 连一边到 n1 ,返回(2)}
优化前
优化后
8
第二节
一 基本块
1 > 定义:
局部优化
局部优化是指局限于基本块内的优化.
基本块是一顺序执行的中间代码序列,仅包含一个入口 四元式 和一个出口四元式,第一条四元式为入口四元式,最后 一条四元式为出口四元式.中间部分不含转移四元式. 2 > 基本块的划分
给定一四元式程序,可以通过如下算法,划分基本块:
9
基本块划分算法: 1) 求四元式程序中所有基本入口四元式,包括:
a) 程序的第一条四元式;
b) 转移语句转移到的四元式;
c) 条件语句之后的第一条四元式.
2) 对每一入口四元式,构造一个基本块: 从该入口四元式到下一入口四元式之前的一条四元式, 或到一转移语句,或到一停止语句之间的四元式序列 组成. 3) 凡未纳入这些基本块的四元式,为无用四元式,可以删除.
第七章
内容 :
•局部优化
中间代码优化
循环优化
优化目的: 提高运行速度, 减少存储空间.
第一节
1
优化概述
右面为循环的中间代码: 对该段中间代码,可以进行 如下优化: 1> 删除多余运算 见(3),(6)两四元式的 4*I, (6) 可以改写为: T4:=T1, 从而减少了一次乘法. 参见下页四元式表
(1) PROD:=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) PROD:=PROD+T7 (3’) T1:=T1+4 (12) if T1<=80 goto(5)
n i val op
ni1 B ni2 C
13
2> 四元式的 DAG 表示 考虑下面三种类型的四元式,DAG表示如右所示 0 型: (:=, B, , A)
n
i
B,A
B
1 型: (op, B, , A)
ni op nk B
A
B
2 型: (op,B,C,A)
ni1 B B
ni op
A
ni2 C C
14
5
5>合并已知量 由于(3)中的 I 在 (2)赋值后 仍然为 1,因此可改为: T1:=4 6> 复写 (6)中 T1 复制到 T4,而(6)到 (8)之间没有改变T1 和 T4, 因此 (8) 可以改为: T6:=T5[T1] ,从而 使(6)式无用.
(1) PROD:=0 (2) I:=1 (4) T2:=addr(A)-4 (7) T5:=addr(B)-4 (3) T1:=4*I (5) T3:=T2[T1] (6) T4:=T1 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (3’) T1:=T1+4 (12) if T1<=80 goto(5)
7
(1) PROD:=0 (2) I:=1 (3) T1:=4*I (4) T2:=addr(A)-4 (5) T3:=T2[T1] (6) T4:=4*I (7) T5:=addr(B)-4 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (11) I:= I+1 (12) if I<=20 goto(3)
10
示例:
设四元式程序如下:
(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
基本入口四元式包括:
(1) 程序第一条四元式
16
T2 : //(op, B, C , A) 若 B ,C为已知量 // 合并已知量 { 执行 op B , 得到一新常数 p, 若NODE(p)= null { 生成值标记为 p 的叶结点 n} 否则 令 n= NODE(p); 把 A 添加在 n 结点的右侧; 返回 (2) } n op 否则 若 DAG 中存在型如右式的子图 {则把 A 添加在 n 结点的右侧; n1 B n2 C 返回 (2) } //合并多余运算 B C 否则 {若NODE(B)= null { 生成值标记为 B 的叶结点 n1} 否则 令 n1= NODE(B); 若NODE(C)= null { 生成值标记为 C 的叶结点 n2} 否则 令 n2= NODE(C); 建立一运算为 op ,附加标记为 A 的结点 n, 从 n 分别连边到 n1 , n2 ,返回(2)}
17
4> 示例: 设基本块如下: (1) A:=x+y (2) T0:=3.14 (3) T1:=2*T0 (4) T2:=R+r (5) A:=T1*T2 (6) B:=A (7) T3:=2*T0 (8) T4:=R+r (9) T5:=T3*T4 (10) T6:=R-r (11) B:=T5*T6
(1) PROD:=0 (2) I:=1 (4) T2:=addr(A)-4 (7) T5:=addr(B)-4 (3) T1:=4*I (5) T3:=T2[T1] (6) T4:=T1 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (11) I:= I+1 (3’) T1:=T1+4 (12) if I<=20 goto(5)
18
DAG 如下
11 B
*
9 A,B,T5
*
8 T2,T4 3 + 1 x A 2 y 4 T0 5 T1,T3 + 1 0 T6
6ቤተ መጻሕፍቲ ባይዱ
3.14
6.28
R
7 r
19
生成DAG 后,实质上已经进行了局部优化,再把 DAG 还原得到 如下四元式: (1) T0:=3.14 (2) T1:=6.28 (3) T3:= T1 (4) T2:=R+r (5) T4:= T2 (6) A:=6.28*T2 (7) T5:=A (8) T6:=R-r (9) B:= A *T6
(3) T1:=4*I (5) T3:=T2[T1] (6) T4:=T1 (8) T6:=T5[T4] (9) T7:=T3*T6 (10) PROD:=PROD+T7 (11) I:= I+1 (12) if I<=20 goto(3)
4
4>变换控制条件 由于 I 只用作循环控制, 而 T1=4*I ,因此, 可用 T1 替 换 I , I<=20 等价于 T1<=80, 把(12)改为 if T1<=80 goto(5) 这样, 可以删掉无用的 I . 参见下页四元式表
21
2> 流图的构造方法 (1) 若基本块 j 在程序中的位置紧跟在基本块 i 之后,且 i 的 出口语句非 goto (s), 则: i j
(2)若基本块 i 的出口语句为 goto (s), 或 if.......goto (s),而 ( s ) 是基本块 j 的入口语句,则: i j
示例:
22
B1
B2
B3
B4
12
二 基本块内的优化
基本块内可以进行以下几种优化: 合并已知量, 删除多余运算(公共子表达式) 删除无用赋值 优化手段: DAG 1> DAG 的定义 DAG 是有向无环路图的简称, 结点的基本形式如右图: n i 为结点名, val 为结点的附加标记, op 为结点的运算. B、C为结点的值标记