我正在研究 Renjin 的字节码编译器(R 代表 JVM),并尝试将中间三地址码 (TAC) 表示形式转换为字节码。我查阅过的所有有关编译器的教科书都讨论了代码生成期间的寄存器分配,但我还没有找到任何用于在基于堆栈的虚拟机(如 JVM)上生成代码的资源。
简单的 TAC 指令很容易翻译成字节码,但当涉及临时指令时我会有点迷失。有没有人有任何描述这一点的资源指针?
这是一个完整的例子:
原始 R 代码如下所示:
x + sqrt(x * y)
TAC IR:
0: _t2 := primitive<*>(x, y)
1: _t3 := primitive<sqrt>(_t2)
2: return primitive<+>(x, _t3)
(暂时忽略我们不能总是在编译时解析对原语的函数调用的事实)
生成的 JVM 字节代码(大致)如下所示:
aload_x
dup
aload_y
invokestatic r/primitives/Ops.multiply(Lr/lang/Vector;Lr/lang/Vector;)
invokestatic r/primitives/Ops.sqrt(Lr/lang/Vector;)
invokestatic r/primitives/Ops.plus(Lr/lang/Vector;Lr/lang/Vector;)
areturn
基本上,在程序的顶部,当我到达 TAC 指令 2 时,我已经需要考虑在堆栈开头需要局部变量 x。我可以手动思考这一点,但我我无法通过算法来正确地思考这一点。有什么指点吗?
将 3 地址表示转换为堆栈比将堆栈一转换为 3 地址更容易。
您的顺序应该如下:
- 形成基本块
- 执行 SSA 转换
- 在基本块内构建表达式树
- 执行寄存器调度(并同时删除 phi),为上一步未消除的寄存器分配局部变量
- 发出 JVM 代码 - 寄存器进入变量,表达式树简单地扩展为堆栈操作
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)