编译原理 之 代码生成【VIP专享】

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ADD Rj,Ri 其开销为1,结果在Ri中. ② b存放在Ri中,而c在一个存储单元里,并假
定b不再活跃。 ADD c,Ri 其开销为2 ③ 或者 MOV c,Rj ADD Rj,Ri 其开销为3
4. 指令调度
• 指令调度——确定程序指令的执行顺序
• 对具有流水线限制的体系结构,这个阶段 是必须的。如:RISC体系结构一个通用的 流水线限制为:从内存中取入寄存器中的 值在随后的某几个周期中是不能用的。在 这几个周期期间,调出不依赖于该取入值 的指令来执行是很重要的。
第十二章 代码生成
• 代码生成概述 • 简单代码生成程序
➢一个假想的计算机模型 ➢简单的代码生成算法
• 代码生成器的自动生成技术
12.1 代码生成概述
• 将经过语法分析或优化后的中间代码, 转 换成特定目标机器的机器语言或汇编语言, 这样的转换程序称为代码生成程序.
• 目标代码与具体的计算机体系结构、指令 格式、字长、寄存器的个数和种类等,并 和指令的语义、操作系统、存储管理相关, 增大了代码生成程序的复杂性.
寄存器分配原则
① 生成某变量的目标代码时,尽量让变 量的值或计算结果保留在寄存器中直 到寄存器不够分配为止。这样,访问 变量值时可减少对内存的存取次数, 以提高运行速度;
② 在同一基本块内后边不再被引用的变 量所占用的寄存器应尽早释放,以提 高寄存器的利用率;
寄存器分配原则
③ 当到基本块出口时,将变量的值存 放在内存中,因为一个基本块可能 有多个后继结点或多个前驱结点, 同一变量名在不同前驱结点的基本 块内出口前存放的R可能不同,或没 有定值,所以应在出口前把寄存器 的内容放在内存中,这样从基本块 外入口的变量值都在内存中.
✓ 如果目标机不能支持指令集的所有 类型,那么对每一种例外要做特别 处理.
✓ 多数CPU的指令集合具有冗余性, 也即,同一计算可用两个或多个不 同的指令序列完成。指令选择器选 择其中之一以产生最好的代码.
例:“加1”的两种代码生成方 式
如:中间代码 a:=a+1: 实现1:INC a
实现2:LD R0,a ADD R0, #1 ST R0,a
些运行程序连接起来,转换成能执 行的机器语言代码.
3. 汇编语言代码。尚需经过汇编程序
汇编,转换成可执行的机器语言代
码.
返回
12.1.2 代码生成要考虑的基本问题
✓目标代码与具体的目标机结构、 指令系统、操作系统有关.
✓代码生成要考虑存储管理、寄存 器分配等方面的问题.
✓代码生成要使生成的目标代码较 短
• 必须找一个指令(与被取值无关)在取指 令之后立即执行,如果找不到相应的指令, 这些周期就会被浪费。
指令选择,寄存器分配,指令调度间的关系
• 在代码生成过程中,这三者的关系非常 密切。在进行寄存器分配和指令调度之 时,假定指令选择已经完成;
• 若先进行调度,寄存器趋向于过度分配; 若先进行寄存器分配,对于给定的寄存 器分配,可供调度的指令可能太少,可 能不包含任何好的调度。
3. 寄存器分配
• 寄存器是比较稀少的资源,计算机程 序所需要的寄存器要比可用的寄存器 多。
• 寄存器分配负责确定在程序的哪个点 将哪些值放在寄存器中比较有益。
寄存器分配可以分成分配和指派两个 阶段来考虑
① 在寄存器分配期间,为程序的某一 点选择驻留在寄存器中的一组变量;
② 在随后的寄存器指派阶段,挑出变 量将要驻留的具体寄存器。
代码生成器
目标程序目标程序
符号表
图12.1 代码生成器在编译系统中的位置
代码生成器的输入 ➢中间代码 ➢符号表中的信息
目标代码一般有三种形式:
1. 能够立即执行的机器语言代码,所 有地址均已定位,通常位于固定的 存储区域中,编译后可直接运行.
2. 待装配的机器语言模块。当需要执 行时,由连接装入程序把它们和某
寄存器分配与寄存器赋值
• 寄存器分配 确定在程序的某个点将哪些值放在寄 存器中
• 寄存器赋值 确定分配有寄存器的值应该在哪个寄 存器中。由于一些目标机可能具有不 同类型的寄存器,因此,对寄存器使 用的一致性方面也存在着一定的约束。
例如,a:=b+c
① Ri中存放了b的值,而Rj中存放了c的值, 且b在此语句之后不再活跃。
• 设计一个好的代码生成器,必须 熟习目标机器和它的指令系统
• 假定一种计算机由n个通用寄存 器R0, R1, …, Rn-1
• R既可作累加器也可作变址器 • op表示运算符,M表示内存单元 • C表示常量,*表示间址方式存取
wenku.baidu.com器指令类型
类型
指令形式 意义(op是二目运算符)
• 一个简单的代码生成程序的构造.
• 目标代码的执行效率很大程度依赖寄存器 的使用.
12.1.1 代码生成器(程序)在编译系统中的位置
将经过语法分析或优化后的中间代码,转 换成特定机器的目标代码.完成代码生成这一 过程的程序称为代码生成器,如图所示.
源源程程序序
编译前端
中间 代码
代码优化
中间 代码
指令选择的基本原则
• 减小产生代码的尺寸 • 减小目标代码的执行时间 • 降低目标代码的能耗
3. 寄存器分配
• 通常情况下,指令在寄存器中访问操 作数的开销要比在内存中访问小。
• 许多指令不能直接访问内存。如果操 作数在内存中,需要显式地取入到寄 存器中。
• 将经常使用的操作数保存在寄存器中 是比较有利的。
✓充分利用计算机的寄存器,减少 目标代码中访问存储单元的次数.
1. 代码生成程序的输入
• 中间代码. 线性表示法(后缀 式)、三地址(四元式)等.
• 符号表中的信息. 代码生成根据 符号表中的信息来决定中间代码 中的名字所指示的数据对象的运 行时地址.
• 有时需要作类型检查.
2. 指令选择
✓ 指令选择--寻找一个合适的目标机 指令序列以实现给定的中间表示.
• 选择最优的寄存器分配是困难的,这是 NP完全问题(多项式条件下不可求解)
12.2 一个简单的代码生成器
• 介绍一个简单的代码生成程序 • 以四元式的中间代码作为输入,将
其转换成给定的M计算机的目标 代码
• 讨论一个基本块内如何充分利用 寄存器以提高目标代码的效率
• 给出寄存器分配的一般算法
12.2.1 一个假想的计算机模型
相关文档
最新文档