




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第八章 代 码 生 成 本章内容一个简单的代码生成算法涉及存储管理,指令选择,寄存器分配和计算次序选择等基本问题前端代 码 优 化 器中间代码源程序代码生成器中间代码目标程序8.1 代码生成器的设计中的问题8.1.1 目标程序可执行目标模块可重定位目标模块允许程序模块分别编译调用其它先前编译好的程序模块汇编语言程序免去编译器重复汇编器的工作从教学角度,增加可读性8.1 代码生成器的设计中的问题8.1.2 指令的选择目标机器指令系统的性质决定了指令选择的难易程度,指令系统的统一性和完备性是重要的因素指令的速度和机器特点是另一些重要的因素8.1 代码生成器的设计中的问题若不考虑目标程序的效率,指令
2、的选择是直截了当的三地址语句x = y + z(x,y和z都是静态分配)MOVy,R0/ 把y装入寄存器R0 /ADDz,R0 / z加到R0上 /MOVR0,x / 把R0存入x中 /逐个语句地产生代码,常常得到低质量的代码 8.1 代码生成器的设计中的问题语句序列 a = b + c d = a + e的代码如下MOV b,R0ADDc,R0MOVR0,aMOVa,R0ADDe,R0MOVR0,d8.1 代码生成器的设计中的问题语句序列 a = b + c d = a + e的代码如下MOV b,R0ADDc,R0MOVR0,aMOVa,R0- 多余的指令ADDe,R0MOVR0,d8.1
3、 代码生成器的设计中的问题语句序列 a = b + c d = a + e的代码如下MOV b,R0ADDc,R0MOVR0,aMOVa,R0- 多余的指令ADDe,R0- 若a不再使用,第三条也MOVR0,d- 多余8.1 代码生成器的设计中的问题8.1.3 寄存器分配运算对象处于寄存器中的指令通常比运算对象处于内存的指令要短一些,执行也快一些寄存器分配选择驻留在寄存器中的一组变量寄存器指派挑选变量要驻留的具体寄存器8.1 代码生成器的设计中的问题8.1.4 计算次序的选择某种计算次序可能会比其它次序需要较少的寄存器来保存中间结果8.2 目 标 机 器 8.2.1 目标机器的指令系统选择可作
4、为几种微机代表的寄存器机器四字节组成一个字,有n个通用寄存器R0,R1, ,Rn-1。二地址指令 op 源,目的MOV源传到目的ADD源加到目的SUB目的减去源 8.2 目 标 机 器 地址模式和它们的汇编语言形式及附加代价模式 形式地址 附加代价绝对地址 M M 1寄存器 R R 0变址 c(R)c + contents(R) 1间接寄存器 Rcontents(R) 0间接变址 c(R)contents(c + contents(R) 1 直接量 #cc 1 8.2 目 标 机 器 指令实例MOVR0,MMOV4(R0),Mcontents(4 + contents(R0) MOV4(R0)
5、,Mcontents(contents (4 + contents(R0) ) )MOV#1,R08.2 目 标 机 器 8.2.2 指令的代价指令代价取成1加上它的源和目的地址模式的附加代价指令代价MOV R0,R11MOV R5,M 2ADD #1, R32SUB 4(R0), 12(R1) 38.2 目 标 机 器 a = b + c,a、b和c都静态分配内存单元MOV b, R0ADD c, R0代价= 6MOV R0, a8.2 目 标 机 器 a = b + c,a、b和c都静态分配内存单元MOV b, R0ADD c, R0代价= 6MOV R0, aMOV b, aADD c,
6、 a代价= 6 8.2 目 标 机 器 a = b + c,a、b和c都静态分配内存单元若R0,R1和R2分别含a,b和c的地址,则MOV R1, R0ADD R2, R0代价= 28.2 目 标 机 器 a = b + c,a、b和c都静态分配内存单元若R0,R1和R2分别含a,b和c的地址,则MOV R1, R0ADD R2, R0代价= 2若R1和R2分别含b和c的值,并且b的值在这个赋值后不再需要,则ADD R2, R1MOV R1, a代价= 3 8.3 基本块和流图怎样为三地址语句序列生成目标代码? |(1)prod = 0 prod = 0; |(2)i = 1 i = 1; |
7、(3)t1 = 4 i do |(4)t2= at1 prod = prod + ai bi; |(5 )t3 = 4 i i = i +1; |(6 )t4 = bt3 while (i = 20); |(7 )t5 = t2 t4 |(8 )t6 = prod + t5 |(9 )prod = t6 |(10)t7 = i +1 |(11)i = t7 |(12 )if i = 20 goto (3) 8.3 基本块和流图8.3.1 基本块基本块:连续的语句序列,控制流从它的开始进入,并从它的末尾离开再用有向边表示基本块之间的控制流信息,就能得到程序的流图8.3 基本块和流图三地址语句序列
8、的划分基本块首先确定所有的入口语句序列的第一个语句是入口语句能由条件转移语句或无条件转移语句转到的语句是入口语句紧跟在条件转移语句或无条件转移语句后面的语句是入口语句每个入口语句到下一个入口语句之前的语句序列构成一个基本块 8.3 基本块和流图(1)prod = 0 (2)i = 1 (3)t1 = 4 i (4)t2= at1 (5 )t3 = 4 i (6 )t4 = bt3 (7 )t5 = t2 t4 (8 )t6 = prod + t5(9 )prod = t6(10)t7 = i +1(11)i = t7(12 )if i = 20 goto (3) (1)prod = 0(2)
9、i = 1(3) t1 = 4 i(4) t2= at1(5) t3 = 4 i(6) t4 = bt3(7) t5 = t2 t4(8) t6 = prod + t5(9) prod = t6(10) t7 = i +1(11) i = t7(12) if i = 20 goto (3) B1B28.3 基本块和流图8.3.2 基本块的优化三地址语句x = y + z引用y和z并对x定值一个名字的值在基本块的某一点以后还要引用的话,则说这个名字在该点是活跃的基本块的等价两个基本块计算一组同样的表达式这些表达式的值分别代表同样的活跃名字的值有很多等价变换可用于基本块局部变换全局变换8.3 基本
10、块和流图删除局部公共子表达式a = b + c a = b + cb = a db = a dc = b + c c = b + cd = a d d = b删除死代码定值x = y + z以后不再引用,则称x为死变量8.3 基本块和流图交换相邻的独立语句t1 = b + c t2 = x + yt2 = x + y t1 = b + c当且仅当t1和t2不相同,x和y都不是t1, 并且b和c都不是t2 代数变换x = x + 0可以删除x = x 1 可以删除x = y 2 改成x = y y 8.3 基本块和流图8.3.3 流图把控制流信息加到基本块集合,形成一个有向图来表示程序首结点、前
11、驱、后继8.3 基本块和流图什么是循环?所有结点是强连通的唯一的循环入口外循环和内循环prod = 0i = 1t1 = 4 it2= at1t3 = 4 it4 = bt3t5 = t2 t4t6 = prod + t5prod = t6t7 = i +1i = t7if i = 20 goto B2B1B28.3 基本块和流图8.3.4 下次引用信息为每个三地址语句x = y op z决定x、y和z的下次引用信息i:x = y op z . . .没有对x的赋值j: = x . . . 没有对x的赋值k: = x8.3 基本块和流图8.3.4 下次引用信息为每个三地址语句x = y op
12、z决定x、y和z的下次引用信息i:x = y op z . . .没有对x的赋值j: = x . . . 没有对x的赋值k: = x8.3 基本块和流图对每个基本块从最后一个语句反向扫描到第一个语句,可以得到下次引用信息i:x = y op z . . .没有对x的赋值j: = x . . . 没有对x的赋值k: = x8.3 基本块和流图对每个基本块从最后一个语句反向扫描到第一个语句,可以得到下次引用信息i:x = y op z . . .没有对x的赋值j: = x . . . 没有对x的赋值k: = x利用下次引用信息,可以压缩临时变量需要的空间8.4 一个简单的代码生成器依次考虑基本块的
13、每个语句,为其产生代码假定三地址语句的每种算符都有对应的目标机器算符假定计算结果留在寄存器中尽可能长的时间,除非:该寄存器要用于其它计算,或者到基本块结束8.4 一个简单的代码生成器在没有收集全局信息前,暂且以基本块为单位来生成代码prod = 0i = 1t1 = 4 it2= at1t3 = 4 it4 = bt3t5 = t2 t4t6 = prod + t5prod = t6t7 = i +1i = t7if i = 20 goto B2B1B28.4 一个简单的代码生成器8.4.1 寄存器描述和地址描述例:对a = b + c如果寄存器Ri含b,Rj含c,且b此后不再活跃产生ADD
14、Rj, Ri,结果a在Ri中如果Ri含b,但c在内存单元,b仍然不再活跃产生ADD c, Ri,或者MOV c, RjADD Rj, Ri若c的值以后还要用,第二种代码比较有吸引力8.4 一个简单的代码生成器在代码生成过程中,需要跟踪寄存器的内容和名字的地址寄存器描述记住每个寄存器当前存的是什么在任何一点,每个寄存器保存若干个(包括零个)名字的值名字的地址描述记住运行时每个名字的当前值可以在哪个场所找到这个场所可以是寄存器、栈单元、内存地址、甚至是它们的某个集合这些信息可以存于符号表中这两个描述在代码生成过程中是变化的8.4 一个简单的代码生成器8.4.2 代码生成算法对每个三地址语句x =
15、y op z调用函数getreg决定放y op z计算结果的场所L查看y的地址描述,确定y值当前的一个场所y.如果y的值还不在L中,产生指令MOV y,L 产生指令op z,L,其中z是z的当前场所之一如果y和/或z的当前值不再引用,在块的出口也不活跃,并且还在寄存器中,那么修改寄存器描述8.4 一个简单的代码生成器8.4.3 寄存器选择函数函数getreg返回保存x = y op z的x值的场所L如果名字y在R中,这个R不含其它名字的值,并且在执行x = y op z后y不再有下次引用,那么返回这个R作为L否则,返回一个空闲寄存器,如果有的话否则,如果x在块中有下次引用,或者op是必须用寄存
16、器的算符,那么找一个已被占用的寄存器R(可能产生MOV R,M指令,并修改 M的描述 )否则,如果x在基本块中不再引用,或者找不到适当的被占用寄存器,选择x的内存单元作为L 8.4 一个简单的代码生成器赋值语句d = (a b) + (a c) + (a c)编译产生三地址语句序列:t1 = a bt2 = a ct3 = t1 + t2d = t3 + t2 8.4 一个简单的代码生成器语 句 生成的代码 寄存器描述名字地址描述 寄存器空 t1 = a b MOV a, R0SUB b, R0 R0含t1 t1在R0中 t2 = a cMOV a, R1SUB c, R1R0含t1R1含t2
17、t1在R0中t2在R1中t3 = t1+ t2 ADD R1,R0 R0含t3 R1含t2 t3在R0中t2在R1中 d = t3 + t2 ADD R1,R0 R0含dd在R0中 MOV R0, d d在R0和内存中 8.4 一个简单的代码生成器前三条指令可以修改,使执行代价降低MOV a, R0MOV a, R0SUB b, R0MOV R0,R1 MOV a, R1SUB b, R0SUB c, R1SUB c, R1. . . . . .8.4 一个简单的代码生成器8.4.4 为变址和指针语句产生代码变址与指针运算的三地址语句的处理和二元算符的处理相同 8.4 一个简单的代码生成器8.
18、4.5 条件语句实现条件转移有两种方式根据寄存器的值是否为下面六个条件之一进行分支:负、零、正、非负、非零和非正用条件码来表示计算的结果或装入寄存器的值是负、零还是正8.4 一个简单的代码生成器根据寄存器的值是否为下面六个条件之一进行分支:负、零、正、非负、非零和非正例如:if x y goto z把x减y的值存入寄存器R如果R的值为负,则跳到z 8.4 一个简单的代码生成器用条件码的例子if x y goto zx = y + w的实现:if x 0 goto zCMP x,y的实现:CJzMOVy,R0ADDw,R0MOVR0,xCJz本 章 要 点代码生成器设计中的主要问题:存储管理、计
19、算次序的选择、寄存器的分配、指令的选择等目标机器几种常用的地址模式和一些常用的指令基本块和程序流图简单的代码生成算法例 题 1在SPARC/SUNOS上,经某编译器编译,程序的结果是120。把第4行的abs(1)改成1的话,则程序结果是1int fact()static int i=5;if(i=0) return(1); else i=i-1; return(i+abs(1) fact();main()printf(factor of 5 = %dn, fact();例 题 2下面的程序在X86/Linux机器上编译后的运行结果是7,而在SPARC/SUNOS机器上编译后的运行结果是6。试分
20、析运行结果不同的原因。main()long i;i = 0;printf(%ldn, (+i)+(+i)+(+i) );例 题 2按一般的代码生成,i = i +1的计算结果保留在寄存器中,因此这三个i = i +1的计算次序不会影响最终的结果。结果应该是6。+=ii+1ii+1ii+1例 题 2按一般的代码生成,i = i +1的计算结果保留在寄存器中,因此这三个i = i +1的计算次序不会影响最终的结果。结果应该是6。结果是7的话,一定是某个i = i +1的结果未保留在寄存器中。上层计算对它的引用落在计算另一个i = i +1的后面 +=ii+1ii+1ii+1例 题 2如果机器有IN
21、C指令的话,编译器极可能产生一条INC指令来完成i = i +1X86/Linux机器上果真是这么做的 +=ii+1ii+1ii+1例 题 2将表达式改成(+i)+(+i)+(+i), 结果会怎样?+=ii+1ii+1ii+1例 题 2将表达式改成(+i)+(+i)+(+i), 结果会怎样?在SPARC/SUNOS机器上的结果仍然是6。在X86/Linux机器上的结果是9。+=ii+1ii+1ii+1例 题 3下面C语言程序如下, 运行时输出105, 为什么?main()long i;i=10;i=(i+5) + (i=i5);printf(%dn,i);例 题 3下面C语言程序如下, 运行时输出105, 为什么?main()long i;i=10;i=(i+5) + (i=i5);printf(%dn,i);二元运算 表达式 表达式 需2个R 需3个R 需几个R 例 题 4下面是一个C语言程序和在X86/Linux机器上编译(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年天津美术考试试题及答案
- 生态文明竞赛试题及答案
- 2025年教师招聘之《幼儿教师招聘》题库带答案详解(完整版)
- 房地产委托代理合同完整版范本3篇
- 冰雪知识竞赛试题及答案
- 安全饮用水知识培训课件
- 2025年教师招聘之《幼儿教师招聘》能力检测试卷附参考答案详解ab卷
- 《机械制图》试题
- 数据库考试试题及答案
- 四下三单元测试题及答案
- 老师孤独症培训课件
- 智慧化税费申报与管理 课件 项目四企业所得税智慧化税费申报与管理
- 电动汽车的储能技术
- 加令岭水库防洪抢险应急预案
- 培训养老护理员的
- 区域创新体系建设
- 2022公务员录用体检操作手册(试行)
- 赤峰市资源型城市经济转型开发试验区总体规划环境影响跟踪评价报告
- 《中小学图书馆(室)规程(修订)》
- 中升集团EAS系统手册
- 《西风的话》的教学反思(5篇)
评论
0/150
提交评论