compilation - 从三地址代码到 JVM 字节码的代码生成

标签 compilation bytecode jvm-languages

我正在为 Renjin(R 代表 JVM)开发字节码编译器,并尝试将中间三地址码 (TAC) 表示形式转换为字节码。我查阅过的所有有关编译器的教科书都讨论了代码生成过程中的寄存器分配,但我还没有找到任何用于在基于堆栈的虚拟机(如 JVM)上生成代码的资源。

简单的 TAC 指令很容易翻译成字节码,但当涉及临时指令时我会有点迷失。有没有人有任何描述这一点的资源指针?

这是一个完整的示例:

原始 R 代码如下所示:

x + sqrt(x * y)

TAC 红外:

 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 地址更容易。

您的顺序应如下:

  1. 形成基本 block
  2. 执行 SSA 转换
  3. 在基本 block 内构建表达式树
  4. 执行寄存器调度(同时进行 phi 删除),为上一步未消除的寄存器分配局部变量
  5. 发出 JVM 代码 - 寄存器进入变量,表达式树简单地扩展到堆栈操作

关于compilation - 从三地址代码到 JVM 字节码的代码生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8427888/

相关文章:

C++成员初始化、复制初始化和默认初始化

Java:编辑并重新编译.jar?

optimization - 具有快速初始化功能的 JVM 脚本语言

asio - 如何确定哪个 channel 是左、右等?

android - 在 android studio 4.1.1 中创建 android 库模块时如何设置 byteCode 级别?

java - JVM 会被扩展以处理泛型吗?

java - 如何在命令提示符下运行 Java 程序

c++ - 尝试在 mac osx 上编译 tcpxtract 会给出未找到的 i386 符号

java - 哪些 Scala 语句或代码可以生成无法转换为 Java 的字节码?

java - 如何将方法调用注入(inject)android中的另一个方法