第八章代码生成.pptVIP

  • 3
  • 0
  • 约5.39千字
  • 约 50页
  • 2022-05-04 发布于广东
  • 举报
8.3 基本块和流图 对每个基本块从最后一个语句反向扫描到第一个语句,可以得到下次引用信息 i: x := y op z . . . ??没有对x的赋值 j: … := x … . . . ??没有对x的赋值 k: … := … x 8.3 基本块和流图 对每个基本块从最后一个语句反向扫描到第一个语句,可以得到下次引用信息 i: x := y op z . . . ??没有对x的赋值 j: … := x … . . . ??没有对x的赋值 k: … := … x 利用下次引用信息,可以压缩临时变量需要的空间 8.4 一个简单的代码生成器 依次考虑基本块的每个语句,为其产生代码 假定三地址语句的每种算符都有对应的目标机器算符 假定计算结果留在寄存器中尽可能长的时间, 除非: 该寄存器要用于其它计算,或者 到基本块结束 8.4 一个简单的代码生成器 在没有收集全局信息 前,暂且以基本块为 单位来生成代码 prod := 0 i := 1 t1 := 4* i t2:= a[t1] t3 := 4* I t4 := b[t3] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i +1 i := t7 if i = 20 goto B2 B1 B2 8.4 一个简单的代码生成器 8.4.1 寄存器描述和地址描述 例:对a := b + c 如果寄存器Ri含b,Rj含c,且b此后不再活跃 产生ADD Rj, Ri,结果a在Ri中 如果Ri含b,但c在内存单元,b仍然不再活跃 产生ADD c, Ri,或者 MOV c, Rj ADD Rj, Ri 若c的值以后还要用,第二种代码比较有吸引力 8.4 一个简单的代码生成器 在代码生成过程中,需要跟踪寄存器的内容和 名字的地址 寄存器描述记住每个寄存器当前存的是什么 在任何一点,每个寄存器保存若干个(包括零个)名字的值 名字的地址描述记住运行时每个名字的当前值可以在哪个场所找到 这个场所可以是寄存器、栈单元、内存地址、甚至是它们的某个集合 这些信息可以存于符号表中 这两个描述在代码生成过程中是变化的。 8.4 一个简单的代码生成器 代码生成算法 对每个三地址语句x := y op z 调用函数getreg决定放y op z计算结果的场所L 查看y的地址描述,确定y值当前的一个场所y?.如果y的值还不在L中,产生指令MOV y?,L 产生指令op z?,L,其中z?是z的当前场所之一 如果y和/或z的当前值不再引用,在块的出口也不活跃,并且还在寄存器中,那么修改寄存器描述 第八章代码生成 8.1 代码生成器的设计中的问题 目标程序 可执行目标模块 可重定位目标模块 允许程序模块分别编译 调用其它先前编译好的程序模块 汇编语言程序 免去编译器重复汇编器的工作 从教学角度,增加可读性 8.1 代码生成器的设计中的问题 指令的选择 目标机器指令系统的性质决定了指令选择的难易程度,指令系统的统一性和完备性是重要的因素 指令的速度和机器特点是另一些重要的因素 8.1 代码生成器的设计中的问题 若不考虑目标程序的效率,指令的选择是直截了当的。 三地址语句x := y + z(x,y和z都是静态分配) MOV y, R0 /* 把y装入寄存器R0 */ ADD z, R0 /* z加到R0上 */ MOV R0, x /* 把R0存入x中 */ 逐个语句地产生代码,常常得到低质量的代码 8.1 代码生成器的设计中的问题 语句序列 a := b + c d := a + e 的代码如下 MOV b, R0 ADD c, R0 MOV R0, a MOV a, R0 ADD e, R0 MOV R0, d 8.1 代码生成器的设计中的问题 语句序列 a := b + c d := a + e 的代码如下 MOV b, R0 ADD c, R0 MOV R0, a MOV a, R0 -- 多余的指令 ADD e, R0 MOV R0, d 8.1 代码生成器的设计中的问题 语句序列 a := b + c d := a + e 的代码如下 MOV b, R0 ADD c, R0 MOV R0, a MOV a, R0 -- 多余的指令 ADD e, R0 -- 若a不再使用,第三条也 MOV R0, d -- 多余 8.1 代码生成器的设计中的问题 8.1.3 寄存器分配 运算对象处于寄存器中的指令通常比运算对象处于内存的指令要短一些,执行也快一些 寄存器分配

文档评论(0)

1亿VIP精品文档

相关文档