コード生成後の命令列ではなく、コード生成時に最適化を行う
モチベーション
以下のようなコードを最適化したい
code:最適化したいコード例1.asm
PUSH cstack+N
code:最適化したいコード例2.asm
PUSH 123
PUSH cstack+N
こんなコードにしたい
code:目標とする出力1.asm
LD cstack+N
code:目標とする出力2.asm
PUSH 123
ST cstack+N
コード生成後の命令列に対して最適化する方法
まず、コンパイラが出力した命令列を読み、PUSH cstack+N; LDD があれば LD cstack+N に置き換える方法を実装した。
これについては問題なく機能した。
コード生成後の命令列に対して最適化する方法の問題
次に、PUSH cstack+N; STA を ST cstack+N に置き換えることにした。
よく考えると、命令の挙動が変わるため、機械的に置き換えられないことが分かった。
PUSH cstack+N; STA は、スタックトップに cstack+N の計算結果が残る。
ST cstack+N は、スタックトップに何も残らない。
後に続く命令列がスタックトップの値を使うかどうかで、置き換え可能かが変わる。
コード生成時に最適化を行う方法
問題は、命令列を見ただけでは、「その後、スタックトップの値を使うかどうか」を調べるのが難しいこと。
もちろん、命令列をしっかり解釈していけば判明するが、仮想的に命令を実行するような仕組みが必要だろう。
コード生成時には「その後、スタックトップの値を使うかどうか」は明確。
そのため、コード生成時に最適な命令列を出力する方が楽だった。
改造前 は、問答無用で push cstack+N を出力していた。 改造後 は、ld cstack+N命令で事足りることが判明したときには push cstack+N を出力しないようにした。