第8章代码生成.ppt

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 例 题 4 每个函数都有这样的标号.L1,它的作用是什么,为什么本函数没有引用该标号的地方? . . . jmp .L4 .L5: .L3: .L1: leave ret .L1标号定义的入口是返回调用者时该执行的指令,在函数内部有return语句时就会跳转到.L1 习 题 第一次:8.4(只为8.1(e)生成代码) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8.3 基本块和流图 对每个基本块从最后一个语句反向扫描到第一个语句,可以得到下次引用信息 i: x = y op z . . . ??没有对x的赋值 j: … = x … . . . ??没有对x的赋值 k: … = … x 利用下次引用信息,可以压缩临时变量需要的空间 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 一个简单的代码生成器 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 一个简单的代码生成器 在代码生成过程中,需要跟踪寄存器的内容和名字的地址 寄存器描述记住每个寄存器当前存的是什么 在任何一点,每个寄存器保存若干个(包括零个)名字的值 例 // 语句前,R0保存变量a的值 b = a // 不为该语句产生任何指令 // 语句后,R0保存变量a和b的值 8.4 一个简单的代码生成器 在代码生成过程中,需要跟踪寄存器的内容和名字的地址 寄存器描述记住每个寄存器当前存的是什么 在任何一点,每个寄存器保存若干个(包括零个)名字的值 名字(变量)的地址描述记住运行时每个名字的当前值可以在哪个场所找到 这个场所可以是寄存器、栈单元、内存地址、甚至是它们的某个集合 例 产生MOV c, R0后,c的值可在R0和c的存储单元找到 8.4 一个简单的代码生成器 在代码生成过程中,需要跟踪寄存器的内容和名字的地址 寄存器描述记住每个寄存器当前存的是什么 在任何一点,每个寄存器保存若干个(包括零个)名字的值 名字(变量)的地址描述记住运行时每个名字的当前值可以在哪个场所找到 这个场所可以是寄存器、栈单元、内存地址、甚至是它们的某个集合 名字的地址信息存于符号表,另建寄存器描述表 这两个描述在代码生成过程中是变化的 8.4 一个简单的代码生成器 8.4.2 代码生成算法 对每个三地址语句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.4 一个简单的代码生成器 8.4.3 寄存器选择函数 函数getreg返回保存x = y op z的x值的场所L 如果名字y在R中,这个R不含其它名字的值,并且在执行x = y op z后y不再有下次引用,那么返回这个R作为

文档评论(0)

1亿VIP精品文档

相关文档