目标代码生成

  • 目标代码生成
  • 11.1 基本问题
  • 11.2 目标机器模型
  • 11.3 一个简单的代码生成器
  • 11.3.1 待用信息
  • 11.3.2 寄存器描述何地址描述
  • 寄存器信息
  • 变量信息
  • 11.3.3 代码生成算法
  • 各中间代码对应的目标代码
  • 11.4 寄存器分配
  • 执行代价
  • 11.5 DAG 的目标代码优化
  • DAG节点计算顺序
  • 11.6 窥孔优化


目标代码生成

以中间代码为输入,产生等价的目标程序为输出;目标代码三种形式:

  • 能立即执行的机器语言代码,地址已定位
  • 待装配的机器语言模块
  • 汇编语言代码

着重考虑的问题

  • 如何使生成的目标代码较短
  • 如何充分利用寄存器,减少目标代码访问存储单元的次数

生成目标模式mysql_生成目标模式mysql

11.1 基本问题

代码生成器的输入;

  • 中间语言: 三地址码
  • 符号表

目标程序: 汇编语言

指令选择

寄存器分配

计算顺序的选择

11.2 目标机器模型

生成目标模式mysql_寄存器分配_02

11.3 一个简单的代码生成器

11.3.1 待用信息

一个基本块范围内考虑如何充分利用寄存器

  • 当生成计算某变量值的目标代码时,尽可能的将该变量的值保存在寄存器中,直到该寄存器必须用来存放别的变量值,或达到基本块的出口;
  • 后续的目标代码尽可能的引用保存在寄存器的值,而不访问主存。

具体做法

  • 把还要引用的变量值金科嗯那个保存在寄存器中
  • 把基本块内不再被引用的变量所占用的寄存器尽早释放

活跃信息: 变量是否还会在基本块内被引用
待用信息: 在那些中代码中被引用

生成目标模式mysql_目标代码生成_03


生成目标模式mysql_DAG优化_04


当变量作为左值的时候,由于会对变量进行赋值,不用向内存中再去取值,变量可以使不活跃的,在寄存器中被任意丢弃,不会对性能产生影响。

生成目标模式mysql_DAG优化_05

11.3.2 寄存器描述何地址描述

寄存器信息

寄存器描述数组 Rvalue 记录了寄存器分配给某几个变量,几个变量。 执行A=B,寄存器R可能分配给A、B等多个变量。

变量信息

变量地址描述数组: Avalue ,记录当前变量的值存放的位置,寄存器中,主存中,还是既在寄存器中又在主存中。
A = A+ B,执行完后,变量值只在寄存器中,还没来的即写回主存。

11.3.3 代码生成算法

getR(i) 过程不考

生成目标模式mysql_目标代码生成_06


生成目标模式mysql_目标代码生成_07

各中间代码对应的目标代码

生成目标模式mysql_DAG优化_08


生成目标模式mysql_目标代码生成_09


生成目标模式mysql_生成目标模式mysql_10


生成目标模式mysql_DAG优化_11


生成目标模式mysql_窥孔优化_12


生成目标模式mysql_目标代码生成_13


在基本块内,活跃变量在最后一次赋值后才存到内存中。

使用简化的方法: 算一次结果就存到内存中

11.4 寄存器分配

在循环中,寄存器不是平均分配,而是从可用寄存器中分出几个,固定分配给几个变量单独使用

执行代价

每条指令的执行代价 = 每条指令访问主存单元的次数 + 1

生成目标模式mysql_寄存器分配_14


计算如果将某个固定的寄存器分配给该变量,执行代价能节省多少。

根据计算结果,把可用的几个寄存器,固定分配给节省执行代价多的几个变量

  • 当变量被定值时(赋值),值才被放到寄存器中。定值前,引用一次,就要访问主存。因此,固定分配寄存器后,该变量被定值前,每引用一次,就减少一次主存访问,执行代价减少1
  • 在基本块中,被定值,且基本块出口之后是活跃的,那么出基本块九阳储存到主存中。 固定分配后,出基本块时,无需转存,代价节省2

生成目标模式mysql_生成目标模式mysql_15


生成目标模式mysql_生成目标模式mysql_16


生成目标模式mysql_窥孔优化_17


生成目标模式mysql_窥孔优化_18


生成目标模式mysql_目标代码生成_19


生成目标模式mysql_DAG优化_20


生成目标模式mysql_寄存器分配_21

11.5 DAG 的目标代码优化

计算A = B op C,如果计算完B紧接着计算A,就可以及时利用寄存器中的信息

  • 考虑先算DAG的右子树,再算左子树,最后算父节点

生成目标模式mysql_寄存器分配_22

生成目标模式mysql_寄存器分配_23

DAG节点计算顺序

设DAG有N个内部节点,线性表T[N] 记录计算顺序,初始为空值。

生成目标模式mysql_窥孔优化_24

  • 最后T[1],T[2], …,T[N] 即为节点计算顺序

生成目标模式mysql_DAG优化_25

11.6 窥孔优化

通过考察一小段目标指令(称为窥孔),把这些指令替换为更短和更快的一段指令,从而提高目标代码质量