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

时间:2011-12-08 08:01:20

标签: compilation bytecode jvm-languages

我正在研究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

基本上,在程序的顶部,我已经需要考虑到堆栈开始时我需要本地变量x到达TAC指令2的时候。我可以这样认为手动,但我无法通过算法思考正确地做到这一点。有什么指针吗?

1 个答案:

答案 0 :(得分:2)

将3地址表示转换为堆栈比将堆栈转换为3地址更容易。

您的顺序应如下:

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