共通部分式最適化をしないという選択:明示的中間表現と責任の分離
概要
[編集]本稿では、コンパイラが共通部分式の最適化(Common Subexpression Elimination, 以下CSE)を意図的に行わない設計方針について論じる。CSEは通常、プログラマの書いた冗長な式を統合し、計算効率を上げる目的で用いられるが、本稿ではその逆の立場を取る。
CSEを廃することで、式の再利用はプログラマの責任となり、結果としてコードの構造が明示的かつ可視的となる。これは中間表現(IR)としての言語や、自己記述的な構文系を目指すYOYUにおいて極めて有用である。
通常のCSEとその問題点
[編集]CSEの基本的な目的は、プログラム中に複数回現れる同一の副作用のない式を一度だけ評価し、再利用することである。例えば:
a = (x + y) + z; b = x + y;
このコードに対し、コンパイラはx + yを1度しか評価しないよう最適化を行う。
しかしこの最適化は、以下の問題を孕んでいる:
プログラマが実際に何を意図して書いたかを不明瞭にする
副作用を持つ式の場合に意図を破壊する可能性がある
中間表現が最終コードと乖離するため、可読性とデバッグ性を損なう
最適化しないコンパイラの意義
[編集]本稿が提案するのは、CSEを廃し、その責任をプログラマに返還するという設計である。つまり、再利用される部分式はテンポラリ変数によって明示されなければならない:
temp1 = x + y; a = temp1 + z; b = temp1;
このスタイルには以下の利点がある:
式の再利用が明示的であり、コードの意味構造が明快になる
副作用の有無をプログラマが意識せざるを得ず、バグの混入を防ぐ
IRとの対応が良く、最適化や変換パスの設計が容易になる
表現が単純になり、構文解析や表示系の実装が軽くなる
YOYUへの応用
[編集]YOYUにおいては、トークン列から意味構造へと至る変換の過程が完全に明示的であることが重要であり、CSEを自動化せずテンポラリを明示させるという設計は、 その哲学と強く合致する。
また、YOYUが持つ中間表現はしばしば構文木に極めて近く、手動でのコード変換・最適化を支援するためには、 すべての変数代入や計算が明示的でなければならない。ここにおいてCSEの抑制は、記述と意味の一致性を保つ。
結論
[編集]コンパイラが「最適化しません」と宣言することは、最適化の放棄ではない。それは意味の可視化であり、責任の分離であり、中間表現としての正直さの追求である。
YOYUのように、プログラムが記述と意味の一致性を追求する文脈において、CSEの排除は理にかなった選択肢である。それにより、プログラマの意図はコンパイラによって改変されることなく、忠実に実行へと至る。