インライン展開をしても思ったよりも速くない原因を考える。
考察
最適化の過程でコードサイズが増加するのだけどこれの影響が大きそう。
具体的には
ソースコード
↓
α変換
↓
A正規化 ← (1)コードサイズ増加
↓
β簡約
↓
不要定義削除 ← コードサイズが微妙に減少
↓
インライン展開 ← (2)コードサイズ増加
↓
コンパイル
↓
VMで実行
と2箇所でコードサイズの増加がおきる。
それぞれのコードサイズ増加が今の コンパイラ/VM に与えるインパクトを考えてみよう。
(1)A正規化時の増加
計算の途中経過を変数に保持するような変換を行うので、ブロック(let1) のコードが大量に増える。
その結果
となってしまう。
ただし命令実行数が増えるのは現在の実装が、中間コードであるはずのものを何も考えずコンパイル/実行しているからであることに注意しないといけない。
let1 ブロックを全てスタックに変数を push する形でコンパイルするようになってしまっている。このうち一部の安全な(?)let1 の途中経過をレジスタに積むようにコンパイラを変更すれば断然速くなるのではなかろうか。
(2)インライン展開時のコードサイズ増加
あまりに大きな手続きを、何か所にも展開するとコードが大きくなる。ただし大きくなっても理論上は VM での命令数はほとんど変わらないはず。
コンパイル時間を稼ぐために、インライン展開をした手続きの定義を削除したいのだけ load とかがあるからうまく削除できるか微妙。
追記
う。しかしスタックマシンなので一時変数はスタックに積むのが筋だろうか。何か見落としているかな。
レジスタ割りあて?
ところで仮想スタックマシンで仮想レジスタに変数を割り付けるメリットてあるんだろうか。うーん。まだ分からない。
追記2
だいありー
お。2003頃にささださんも悩まれていたようですね。