Renjin (JVM の場合は R) のバイト コード コンパイラに取り組んでおり、中間 3 アドレス コード (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 が必要になると考えている必要があります。手動で考えることはできますが、これを正しく行うためのアルゴリズムを考えるのに苦労しています。ポインタはありますか?