2020-编译原理-IR3-回填技术

IR3-回填技术

  1. B 还不知道S.next的指令地址,如何跳转?
  2. 再扫描一遍中间代码,将标号替换成指令(相对) 地址
  3. 可否在生成中间代码的时候就填入指令地址?

子节点挖坑、祖先节点填坑

  1. 目前的方法是通过一边扫描得到包含Label的中间代码,然后我们可以通过再次扫描一遍中间代码来生成每一个Label的指令地址,我们的目标是一次扫描完成了上述的两部分工作。
  2. 比如if (B) S:这时候我们得到的是L: goto B.false,我们替换为指令地址,则为100: goto ___,并且放入B.false中,然后向上传递,直到一个有父节点指导目标位置,然后填充进去即可。

1. 针对布尔表达式的回填技术

M的作用是得到B2B_2这段代码的第一条指令地址。

  1. 综合属性B.truelist 保存需要跳转到B.true 的指令地址

  1. 综合属性B.f alselist 保存需要跳转到B.f alse 的指令地址
  2. 是个数组

100:if E1 rel E2 goto _101:goto _\begin{aligned} &100: if\ E_1\ rel\ E_2\ goto\ \_ \\ &101:\qquad goto\ \_ \\ \end{aligned}

注意100和101指令对应nextinstr

  1. 回填:backpatchbackpatch函数,M.instrM.instr代表的是M的第一个地址,也就是我们要将B1.truelistB_1.truelist中的所有的坑都填为M.instrM.instr
  2. nextinstrnextinstr代表的是计数器+1

2. 例子

x < 100 || x > 200 && x != y


3. 具体语句使用填坑技术的生成式

3.1. if/else控制流语句翻译


3.2. while控制流语句翻译

注意N的跳转位置和next属性
nextinstr:是生成的过程中的地址的计数器,表示的是gen(“goto _”)的地址

3.3. 不包含跳转的语句翻译

3.4. switch语句翻译


switch-case先把标签生成好



2020-编译原理-IR3-回填技术
https://spricoder.github.io/2021/01/16/2020-Compilation-Principle/2020-Compilation-Principle-IR3-%E5%9B%9E%E5%A1%AB%E6%8A%80%E6%9C%AF/
作者
SpriCoder
发布于
2021年1月16日
许可协议