IR3-回填技术
- B 还不知道S.next的指令地址,如何跳转?
- 再扫描一遍中间代码,将标号替换成指令(相对) 地址
- 可否在生成中间代码的时候就填入指令地址?
子节点挖坑、祖先节点填坑
- 目前的方法是通过一边扫描得到包含Label的中间代码,然后我们可以通过再次扫描一遍中间代码来生成每一个Label的指令地址,我们的目标是一次扫描完成了上述的两部分工作。
- 比如
if (B) S
:这时候我们得到的是L: goto B.false
,我们替换为指令地址,则为100: goto ___
,并且放入B.false
中,然后向上传递,直到一个有父节点指导目标位置,然后填充进去即可。
1. 针对布尔表达式的回填技术
M的作用是得到 B 2 B_2 B2这段代码的第一条指令地址。
- 综合属性B.truelist 保存需要跳转到B.true 的指令地址
- 综合属性B.f alselist 保存需要跳转到B.f alse 的指令地址
- 是个数组
100 : i f E 1 r e l E 2 g o t o _ 101 : g o t o _ \begin{aligned} &100: if\ E_1\ rel\ E_2\ goto\ \_ \\ &101:\qquad goto\ \_ \\ \end{aligned} 100:if E1 rel E2 goto _101:goto _
注意100和101指令对应nextinstr
- 回填: b a c k p a t c h backpatch backpatch函数, M . i n s t r M.instr M.instr代表的是M的第一个地址,也就是我们要将 B 1 . t r u e l i s t B_1.truelist B1.truelist中的所有的坑都填为 M . i n s t r M.instr M.instr
- n e x t i n s t r nextinstr nextinstr代表的是计数器+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先把标签生成好