SSA最適化

6502のバイナリを、Javaソースに変換した場合の話です。
6502で汎用レジスタと呼べるものは、Aレジスタだけしかないわけです。
そのため、大抵の場合は何をするにしても、Aレジスタを経由した処理になるわけです。
メモリ間で値をコピーするためには、LDAして、STAします。
たとえば、0x0001番地の値を、0x0002番地にコピーするとしましょう。
これをJavaコードに変換すると、
a = LdMem(0x0001);
StMem(0x0002, a);
という感じのコードに変換されます。現状では。

aの値を、その後使わないのであれば、
StMem(0x0002, LdMem(0x0001));
としても、同じ意味になります。

Javaコンパイラは、上のような最適化をやってくれないみたいです。
aにいったん代入すると、Javaバイトコードで、2命令ほど余計な処理が入ってしまいます。

現状だと、6502からJavaソースに変換したときに、上のような余計な代入を行っている箇所が大量にあるソースが出力されています。
これをなんとかして省きたい。

javacではない、違うJavaコンパイラなら、こういう最適化もやってくれるものがあるんじゃないだろうかとか、ProGuard等のclassファイルを難読化・最適化を行うツールで、こういう最適化をやってくれないかとか、調べたのですが、ダメでした。
自前で実装して、最適化するしかなさそうです。

となると、現状のプログラムの作りだと無理がある気がするんですよね。
今は、直接的に6502からJavaソースに変換していますので。

6502バイナリ

中間コード

SSA最適化

Javaソースコード

みたいにしないと厳しいと思います。

また、エミュレータで事前に取得している情報についてですが、今はホットスポットに関する情報を取得しています。
これをちょっと改良して、データフローを解析するための情報も集めるようにしようと思います。つまり、ここからここまでがひとつのブロックで、またこのブロックはサブルーチンとして使われている…みたいなのを調べるようにするわけです。