编译原理第三版 第十章 代码优化
编译原理优化

v:=a[T1]
B1
i:=i+1
T2:=4*i T3:=a[T2]
B2
if T3<v goto B2
j:=j-1
B3
T4:=4*j
T5:=a[T4]
if T5>v goto B3
if i>=j goto B6 B4
T6:=4*i x:=a[T6] T7:=4*i T8:=4*j T9:=a [T8] a[T7]=T9 T10:= 4*j a[T10]=x goto B2
a[T12]=T14
T15:= T13
a[T15]=x
复写传播后
19
i:=m-1
j:=n
T1:=4*n
v:=a[T1]
B1
i:=i+1
T2:=4*i T3:=a[T2]
B2
if T3<v goto B2
j:=j-1
B3
T4:=4*j
T5:=a[T4]
if T5>v goto B3
if i>=j goto B6 B4
合算原则
应尽可能以较低的代价取得较好的优化效果
6
10.1 概述
优化的三个不同级别
局部优化 循环优化 全局优化
优化的种类
删除多余运算(或称删除公用子表达式) 合并已知量 复写传播 删除无用赋值 代码外提 强度消弱 变换循环控制条件
7
void quicksort (m, n);
T14:=a [T13]
a[T12]=T14
T15:= T13
a[T15]=x
复写传播后
15
i:=m-1
j:=n
T1:=4*n
v:=a[T1]
编译原理chapter9优化

t11 := 4 * i x := a[t11] t12 := 4 * i t13 := 4 * n t14 := a[t13] a[t12] := t14 t15 := 4 * n a[t15] := x
10.2.2 公共子表达式删除
如果表达式E先前已计算,并且从先前的计算到E的再次出现,E中变量的 值没有改变,那么E的这个再次出现称为公共子表达式
(2) j := n
do i = i +1; while(a[i]<v); (3) t1 := 4 * n
do j =j 1;while (a[j]>v); (4) v := a[t1]
if (i >= j) break;
(5) i := i + 1
x=a[i]; a[i]=a[j]; a[j]=x; (6) t2 := 4 * i
}
(7) t3 := a[t2]
10.2 优化的主要种类
本节所用的例子
i = m 1; j = n; v = a[n]; (9) j := j 1
while (1) {
(10) t4 := 4 * j
do i = i +1; while(a[i]<v); (11) t5 := a[t4]
do j =j 1;while (a[j]>v); (12) if t5>v goto (9)
10.2.2 公共子表达式删除
B5 x=a[i]; a[i]=a[j]; a[j]=x;
t6 := 4 * i x := a[t6] t7 := 4 * i t8 := 4 * j t9 := a[t8] a[t7] := t9 t10 := 4 * j a[t10] := x
编译原理中的目标代码生成与优化

编译原理中的目标代码生成与优化编译原理是计算机科学中的一门重要课程,它研究的是将高级程序语言转化为机器语言的过程。
目标代码生成与优化是编译过程中的两个关键环节,本文将就这两个方面展开讨论。
一、目标代码生成目标代码生成是编译过程中的最后一步,它的任务是将中间代码转化为能够在目标机器上执行的机器代码。
目标代码生成的质量直接影响程序的执行效率和占用的存储空间。
1. 寄存器分配在进行目标代码生成之前,我们需要进行寄存器分配。
寄存器分配的目的是将中间代码中的临时变量分配到机器寄存器中,减少内存读写操作,提高程序的运行速度。
常用的寄存器分配算法有线性扫描算法和图着色法。
2. 目标代码生成技术目标代码生成的技术有很多,下面列举几种常见的技术:(1) 直接生成代码:直接将中间代码翻译为目标机器的指令序列。
这种方法简单直接,但生成的目标代码质量一般较低。
(2) 间接生成代码:先将中间代码翻译为一个中间形式,再将中间形式转化为目标机器的指令序列。
这种方法可以进行一些优化,生成的目标代码质量较高。
(3) 使用代码模板:事先定义一些目标机器的指令模板,并根据中间代码的特征选择合适的指令模板来生成目标代码。
这种方法可以充分利用目标机器的特性,生成的目标代码效率较高。
二、目标代码优化目标代码优化是指对生成的目标代码进行一系列的优化,以提高程序的运行效率和减少代码的空间占用。
1. 基本块优化基本块是由顺序执行的指令组成的,没有前驱指令和后继指令的指令序列。
基本块优化的目的是对基本块中的指令进行优化,以减少执行时间和空间开销。
常见的基本块优化技术有死代码删除、常量传播等。
2. 寄存器优化寄存器是计算机中的一块高速存储器,能够提供快速的数据访问速度。
寄存器优化的目的是将变量尽可能地存放在寄存器中,以减少内存读写操作,提高程序的执行效率。
常用的寄存器优化技术有寄存器分配、寄存器重命名等。
3. 循环优化循环是程序中的重要结构之一,对循环进行优化可以显著提高程序的执行效率。
编译原理总结10_优化及目标代码生成

7.1 编译程序考虑的因素
控制结构
一个程序设计语言的控制结构是该语言
在程序运行期间用于改变控制流的语言特征
集合。
5
7.2 运行时的存储分配
编译程序需要为源程序中的数据分配执行时的存储
空间,编译程序从操作系统中申请编译程序计算出的所
需的内存,或编译程序生成在运行时需申请内存的指令。 (1) 确定用来表示某一数据项的内存大小; (2) 使用适当的内存分配策略,实现具体数据的作用 域和生存期;
1.外提不变式:将循环中的不变运算提到循环前面 ,不变运算是指其运算结果不受循环影响的表达式。
2.强度削弱:把程序中执行时间较长的运算替换为 执行时间较短的运算 。 3.删除基本归纳变量:如果循环中对变量I只有唯一 的形如:I = I ± C的赋值,且C为循环不变量,则 称I为循环中的基本归纳变量;删除归纳变量在强度 削弱后进行。
10
7.3 代码优化
优化的基本方法
• 去处冗余
• 削减强度
• 使用更快的指令
11
7.3.1
局部优化
在一个基本块上进行的优化
基本块:程序中一个顺序执行的语句序列, 即一个程序段,它只有一个入口和一个出 口,入口是第一条语句,出口是最后一条 语句。
12
基本块划分方法
(1)确定各个基本块的的入口语句(基本块的第一个语句) ① 语句序列的第一个语句是入口语句; ② 能由条件转移语句或无条件转移语句转到的语句是入口语 句; ③ 紧跟在条件转移语句或无条件转移语句后面的语句是入口 语句。
2
7.1 编译程序考虑的因素
数据结构
一个程序设计语言如允许使用的数组、记录、字符串、表、
栈等形式的数据结构,在编译程序中应为它们提供相应的翻译。
编译原理 第10章(清华大学)

∶ ∶
(a) (a) 到 达 标 号 B1处 ;
BB 的 内 情 向 量 ZZ
BB11 的 TT OO P DISPLAY
形式单元 m,n 2
连接数据 A的TOP
∶ ∶ (b) (b)进 入 分 程 序 B1;
31
数 组B
B的 内 情 向 量 z
B1 的 T O P D I S P LAY
20
用Display表的方案
(1)主程序--->(2)P--->(3)Q--->(4)R
top
P的
display sp 活动记录
d[1]
主程序的
d[0]
活动记录
top display
主程序的
d[0]
sp 活动记录
(2)
(1)
21
用Display表的方案
• 主程序--->P--->Q--->R
d[2]displatyopsp
endmainmainqrmainqqtopr的活动记录q的活动记录spq的活动记录q的活动记录主程序全局主程序全局数据区数据区top临时工作单元局部简单变量局部数组的内情向量保存运行过程前的状态返回地址寄存器值??实参形式单元和参数个数sp控制链老sptop的数组区sp的活动记录q的活动记录主程序全局数据区嵌套过程语言的栈式分配方案l主要特点语言一个过程可以引用包围它的任一外层过程所定义的标识符如变量数组或过程等
地址 3 参数个数 4 形式单元
. . . d D ISP L A Y . 简单变量 . 数组内情向量 . 临时变量
• 当过程的层次为n, 它的 display为n+1个 值。 • 一个过程被调用时, 从调用过程的 DISPLAY表中自下向 上抄录n个SP值,再加 上本层的SP值。 •全局DISPLAY地址
程序设计语言编译原理第三版第10章

§10.2 局部优化
举例:考察下面的三地址代码程序
(1)Read X
(2)Read Y
B1
(3)R:=X mod Y (4)if R=0 goto (8) B2
(5)X:=Y
(6)Y:=R
B3
(7)goto(3)
(8)write Y B4
(9)halt
B1
B2
B3
B4
§10.2 局部优化
3.流图及其生成
标识符(包括常数)-结点 NODE(A)-描述上述对应关系的函数,其值或者是一个结点的编号,
或者无定义
(2)中间代码的三种形式:A:=B A:=op B A:=B op C 或 A:=B[C]
(3)构造算法: ①开始,DAG为空 ②对基本块中每一条中间代码式,依次执行以下步骤:
§10.2 局部优化
步骤: 1.如果NODE(B)无定义,则构造一标记为B的叶结点并定义
NODE(B)为这个结点 如果当前代码是0型,则记NODE(B)的值为n,转4 如果当前代码是1型,则转2(1) 如果当前代码是2型,则(ⅰ)如果NODE(C)无定义,则构造一标 记
为C的叶结点并定义NODE(C)为这个结点;(ⅱ)转2(2)
(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
(4)代数变换
§10.2 局部优化
二、基本块的DAG表示及其应用
1.基本块的DAG:
一种结点带有下述标记或附加信息的DAG
(1)图的叶结点以一标识符(变量名)或常数作为标记,表示该 结点代表该变量或常数的值。
编译原理课件-代码优化

Wensheng Li BUPT @ 2008
常數合併的實現
在符號表中增加兩個資訊域
–標誌域:指示當前是否存在與該變數相關的常數。 –常數域:如果常數存在,則該域存放的即是與該變數相
應的當前常數值。
常數合併時,注意事項:
–不能將結合律與交換律用於浮點運算式,因為浮點運算 的精度有限,這兩條定律並非是恒真的。
PI:=3.14; D-to-R:= 30P.I01/4117/814084.00;.0
i:=0 10: i:=i+1
... if i<10 goto 10
i:=0 10: i:=0+1
... if i<10 goto 10
... a[i]:=9.0 ... a[j]:=3.0 b:=a[i]
?
7/62
– 所謂等價,指不改變程式的運行結果 – 所謂有效,指目標代碼運行時間短、佔用空間少
基本塊的dag是一種結點上有標記的有向非迴圈圖
– 葉結點由變數名字或常量標記。 – 根據作用到名字上的算符,決定需要名字的左值還是右
值。大多數葉結點代表右值。 – 葉結點代表名字的初值,通常為識別字加上腳標0。 – 內部結點由運算符號標記,代表計算出來的值。 – 圖中各結點可能附加一個或多個識別字,表示這些識別
10.1 優化概述
代碼優化程式的任務
–將前端產生的中間代碼轉換為等價的目標代碼
代碼優化程式的要求
–等價變換 –提高目標代碼的執行速度 –減少目標代碼佔用的空間
代碼優化程式的地位
–目標代碼生成之前的中間代碼優化 –目標代碼生成之後的目標代碼優化
3/62
Wensheng Li BUPT @ 2008
代碼優化程式的位置
编译原理 第10章 代码优化

3、冗余子表达式的消除:在值不发生变化的情 况下,对同一个表达式只需计算一次,再次出现时 直接使用它的值。
例(P199) 有如下 程序段: ① a=b+c; 因为语句2和4之间a 和d没有变化,故应 优化为:
① a=b+c;
② b=a-d; ③ c=b+c; ④ d=b;
10.1 局部优化
基本块的DAG构造算法(续):
(4)若NODE(A)=null,则把A附加到结点n,并令 NODE(A)=n,转(4);否则,先从NODE(A)的附加标识 集中将A删去(注意,若NODE(A)有前驱或NODE(A)是 叶结点,则不能将A删去),然后再把A附加到新的结点 n,并令NODE(A)=n。
10.1 局部优化
基本块的优化技术: 1、常数合并:常数合并是将能在编译时计算出值 的表达式用其相应的值替代。 例(P199)
x=3.14*2
y=2*5*a; z=x+1; 转换成四元 式为: (*,3.14,2,t1) (=,t1,_,x) (*,2,5,t2) (*,t2,a,t3) (=,t3,_,y) (+,x,1,t4) (=,t4,_,z) 常数合并后 的代码如下: (=,6.28,_,x)
例(P212)
优化后
小 结
1、代码优化种类(按优化范围划分): 局部优化、循环优化和全局优化 2、基本块的划分、优化技术(常数合并、 删除无用赋值和冗余子表达式的消除) 和DAG表示 3、循环优化技术:外提循环中的不变表 达式、强度削弱和删除归纳变量
习 题
1. 对下列基本块应用 DAG进行优化: 1. (=,3,,B) 2. (+,A,C,D) 3. (*,A,C,E) 4. (+,D,E,F) 5. (*,B,F,G) 6. (+,A,C,H) 7. (*,A,C,I) 8. (+,H,I,J) 9. (*,B,5,K) 10.(+,K,J,L) 11.(=,L,,M) 2. 对下面程序段画出程 序流图,并进行循环优 化。 I=1; J=10; K=5; L1:X=K*I; Y=J*I; Z=X*Y; I=I+1 if I<100 goto L1;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(1) P:=0 (2) I:=1
B1
(1) P:=0
ห้องสมุดไป่ตู้
③删除无用代码 ④外提循环不变 式:(4)、(7)为循环
不变式,可外提至 B1中
(2) I:=1 B1 (4) T2:=addr(A) - 4 (7) T5:=addr(B) - 4
(3)T1:=4* I B2 (4) T2:=addr(A) - 4 (5) T3:=T2[T1] (6) T4:= T1 (7) T5:=addr(B) - 4 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (12) if I≤20 goto (3)
• 检查公共子表达式:若四元式为公共子表达式,
则把已有的结点作为它的结点(即加右标记); • 检查无用赋值: 若NODE[A]已是某结点的右标记, 则从该右标记集合中删除后再建立新结点。
算法框图:
初始化
取下一条四元式 (0)A:=B、(1)A:=opB、(2)A:=BopC N
NODE(B)定义? Y
⑥变换循环控制条件 (1) P:=0 删除归纳变量
(12) if I≤20 goto (5) 分析I的作用: •计算 T1:=4*I •循环控制条件 I≤20 •递归赋值: I:=I+1 变换控制条件: •计数法: I≤20 •比较法: T1≤80 删除(11)
B1
(4) T2:=addr(A) - 4 (7) T5:=addr(B) - 4 (3) T1:=4
⑦合并已知量
(5) T3:=T2[T1] B2 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (3’) T1:=T1+4 (12) if T1≤80 goto (5)
图4. 运算强度削弱
B1中(2) I:=1 (3)T1:=4*I (3) 可改为: (3) T1:=4 图5. 变换循环控制条件与合并 删除(2) 已知量
结点集N为基本块集; 首结点n0为含有第一个语句的基本块;
有向边集E的构成规则:
i
j
基本块j紧跟在基本块 i 之后, 且基本块 i 的出口语句不是无条件转移语句或停语句; 基本块i 的出口语句是 goto (s) 或 if . . . goto (s) 且 (s) 是基本块j 的入口语句 ;
(4) if R=0 goto (8)
(5) X:= Y (6) Y:=R B3 (7) goto (3)
(8) write Y (9) halt
B4
程 序 流 图
4.基本块内的优化
[例]对以下求向量内积的PASCAL程序段的中间代码进行优化: P := 0; (设low=1,w=4) for I := 1 to 20 do (A[I]地址:I*w+(base-low*w) P:= P + A[I] * B[I] (1) P:=0
计算P=op B
计算P=Bop C
删除刚生成 的新结B和C
DAG中有以B、 C为后继且标记 为op的结点?
NODE(A)定义? N 将A标记在结点n上
Y
将A 从原 结删除
有,设为n 构造新结点 n标为P,令 N NODE(P)定义? Y B、C为其 生成新结n标为P 找到结点设n 左右后继
[例] 试构造以下基本块的DAG (1) T0:=3.14 (2) T1:=2*T0 (3) T2:=R+S (4) A:=T1*T2 构造DAG n6 (5) B:=A * (6) T3:=2*T0 (7) T4:=R+S n2 (8) T5:=T3*T4 2 T3 (9) T6:=R - S n1 T0 n2 T1 (10) B:=T5*T6 3.14 6.28
图3 删除无用代码和代码外提
图4 运算强度削弱
(1) P:=0
(2) I:=1 B1 (4) T2:=addr(A) - 4 (7) T5:=addr(B) - 4 (3) T1:=4*I (5) T3:=T2[T1] B2 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (3’) T1:=T1+4 (12) if I≤20 goto (5)
第十章
本章要点
阶段: 编译的第四阶段
代码优化
源程序 词法分析 表 语法分析 格 错
出
任务:对程序进行各种 等价变换,使得从变换后 的程序出发,能生成更有 效的目标代码。 重点: 局部优化 循环优化
中间代码生成
管 优 理 目标代码生成 目标程序 化 处 理
10.1 优化概述
1. 问题的提出 (1) 编译程序的作用 使计算机的使用方式从用机器语言编程发展到用 高级语言编程。是计算机发展史上的一次飞跃。 (2) 早期编译程序的不足 占用的空间大 目标程序质量差 运行的时间长 2. 解决的方法: 代码优化:即对程序进行各种等价变换,使得从变 换后的程序出发能生成更有效的目标代码。 优化原则:等价、有效、合算
[小结]
局部优化: ①删除公共子表达式
⑤合并已知量 ⑥复写传播 ⑦删除无用赋值 循环优化: ②外提循环不变式 ③运算强度削弱 ④变换循环控制条件 优化前后比较: 循环B2 四元式个数 乘法个数 优化前 10 3 优化后 6 1
以上优化方法均可用算法实现
基本块内还可进行以下几种变换 临时变量改名.
优化不是目的,只是手段
3. 优化方法 按优化所涉及的程序范围分: 局部优化: 在基本块上进行的优化 • 合并已知量
• 删除无用赋值(无用代码) • 删除多余运算(公共子表达式)
方法:DAG; 特点: 简单、成熟。 循环优化:在循环块上进行的优化 • 代码外提
• 运算强度削弱 • 删除归纳变量
交换语句的位置. 代数变换.
说明:
无用赋值的判定:
• 对A赋值后, A不被引用 (全局数据流分析)
• 对A赋值后, 引用前又重新赋值 ( 容易判定) • A仅在递归赋值(A:=A+C)中被引用(全局数据 流分析)
#
10.2.2. 基本块的DAG表示及其应用
1. 无环路有向图DAG (Directed Acyclic Graph) (1) 定义: 若有向图中所有通路均非环路, 则称其为DAG (2) 基本块的DAG(用于描述计算过程): a:=b*-c+b*-c的 := 是为结点附加了信息的DAG。 DAG(中间代 a + 码的图形表 叶结点: 示) •下标记: 常数或标识符 * •右标记: 标识符 @ 内结点: b •下标记: 运算符 c • 右标记: 标识符 (2) A:= op B (3) A:=B op C (3) 结点形式 n3 A n2 A (1) A:=B op op n1 A n1 n2 n1 B B C B 0型
方法:循环查找算法、数据流分析;复杂、高效。 全局优化:在整个程序上的优化 方法:全局控制流分析、全局数据流分析; 特点:代价大、高效。
10.2 局部优化
问题: 什么是基本块? 怎样划分基本块? 在基本块中可以进行哪些优化? 怎样进行局部优化? 10.2.1 基本块和流图 对一给定的程序,将其划分为若干个基本块, 在各个基本块中分别进行优化即称为局部优化。
(1) P:=0 (2) I:=1
B1
①删除公共子表达式
(3)、(6)为公共子式 可将(6)改为T4:=T1
(2) I:=1
B1
(3)T1:=4*I B2 (4) T2:=addr(A) - 4 (3) T1:=4*I ②进行复写传播 (5) T3:=T2[T1] (4) T2:=addr(A) - 4 T4:=T1 (5) T3:=T2[T1] B2 B2中(6)T6:=T5[T4] (6) T4:= T1 (8) (7) T5:=addr(B) - 4 (6) T4:=4*I T4:=T1 可改为(8)T6:=T5[T1] (8) T6:=T5[T1] (7) T5:=addr(B) - 4 (9) T7:=T3*T6 (8) T6:=T5[T4] T6:=T5[T1] (10) P:=P+T7 (9) T7:=T3*T6 (11) I:=I+1 (10) P:=P+T7 (12) if I≤20 goto (3) (11) I:=I+1 (12) if I≤20 goto (3) 图1 优化前的四元式 图2 删除公共子表达式和复写传播
(3)T1:=4*I (5) T3:=T2[T1] B2 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (12) if I≤20 goto (3)
图2 删除公共子表达式和 复写传播
图3删除无用代码和代码外 提
(1) P:=0
(2) I:=1 B1 (4) T2:=addr(A) - 4 ⑤运算强度削弱 (7) T5:=addr(B) - 4 由(3) T1:=4*I (11) I:=I+1 (3)T1:=4*I 可改为: 将(3)外提至B1 (5) T3:=T2[T1] B2 (11)后增加(3‘) (8) T6:=T5[T1] (3’) T1:=T1+4 (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (12) if I≤20 goto (3)
(1) P:=0
(2) I:=1 B1 (4) T2:=addr(A) - 4 (7) T5:=addr(B) - 4 (3) T1:=4*I
(5) T3:=T2[T1] B2 (8) T6:=T5[T1] (9) T7:=T3*T6 (10) P:=P+T7 (11) I:=I+1 (3‘) T1:=T1+4 (12) if I≤20 goto (5)