プログラミング言語における最適化について #2
(0)
(1)
- 「プログラミング言語における最適化について」(a21_opt)では、(3-1)として、
- コンパイル時に答えが確定しているものは、定数に置き換えてしまう。
- という最適化を紹介しました。これの話の続きです。
- この最適化を実現するアルゴリズムは簡単です。
- プログラムを上から順番に見ていくことにします。
- もし変数に定数が代入されたら、この変数の値は〇〇である、とテーブルに登録しておきます。
- もし定数ではない値が代入されたら、もう変数の値は不定なので、もしテーブルにその変数が登録されていればそれを消しますし、登録されていなければ何もしません。
- テーブルに登録された変数を参照された場合は、それを全部定数に置換してしまいます。
- ラベル定義文やforやwhileの先頭は繰り返しやcontiuneで合流が発生する可能性があるところです。そうなると合流の際に変数の値がどうなっているかわかったものではないので、テーブルはクリアしてしまいます。forやwhileの直後の文もbreakなどで飛んでくるので、テーブルのクリアが必要です。そんな感じで、合流の可能性があるところでは全部テーブルクリアです。
- 置換の結果(もしくは置換する前から)式の一部または全部が定数だけで構成されていたら、そこは計算してしまって計算値と置換します。
- こうして最後までプログラムをチェックし終わったら、それでおしまいです。
- ちなみにプログラム内で一度でもポインタを取得した変数(p = &i; としたときのiのこと)は、そのポインタを使って中身を書き換えたり読んだりする可能性があります。それはいつ起こるか簡単にはわかりません。だからそういう変数に対しては、たとえ定数の代入があってもその後も定数のままでいると仮定することなく、変数扱いにします。
- ここも頑張ればもっと最適化がうまくなるのですが、それをやると大変なので、面倒なら無理せずに変数扱いにしてしまいましょう。それでも多くのケースで十分に最適化はできます。
- しかしこのアルゴリズムでは、たとえば関数の冒頭で一度だけ定数で初期化されて、それ以降一度も上書きされない変数があっても、最初の合流ポイントでテーブルクリアされてしまい、せっかくの定数が生かされません。これをどうにかしてやりたいと思いました。・・・もちろんできるだけ難しくないアルゴリズムで。
こめんと欄