コードの最適化 - 構文ツリーと中間表現
-
29-09-2020 - |
質問
私は独自のカスタム言語のコンパイラを開発しています。コードの最適化に関する記事を読んでいたとき、コードの中間表現がすでに形成されていることを前提としていることに気づきました。コンパイラの最適化セクションの作成はまだ始めていませんが、頭の中で検討しており、中間表現に変換する前にオプティマイザが構文ツリー上で動作するようにすることが望ましいと思われます。
あるアプローチを他のアプローチよりも好む理由はあるのでしょうか、それとも主に個人的な好みの問題なのでしょうか?
たとえば、 if
ブロックのような
if ( some_expression ) {
do_stuff
}
コンパイラが認識できれば some_expression
常に true と評価され、副作用がない場合は、ツリーを枝刈りするだけでその計算を削除できます。
ただし、ツリーをすでに中間表現 (アセンブリ風の単純な命令のリストなど) に変換していた場合、シナリオの認識と解決のプロセスは次のようになります (まだ実装しようとしていないため、想像の中で)。はるかに複雑です。
解決
最近では、中間表現を使用して最適化を行うのがトレンドです。チェックアウト LLVM 例えば:
LLVM コア ライブラリは、ソースおよびターゲットに依存しない最新のオプティマイザと、多くの一般的な CPU (およびあまり一般的ではない CPU) のコード生成サポートを提供します。これらのライブラリは、LLVM 中間表現として知られる明確に指定されたコード表現を中心に構築されています。 (「LLVM IR」)。LLVM コア ライブラリは十分に文書化されており、オプティマイザーおよびコード ジェネレーターとして LLVM を使用する独自の言語を発明する (または既存のコンパイラーを移植する) ことは特に簡単です。
LLVM は、コードが LLVM IR で表現された後にのみコード上で最適化パスを実行するため、ソースに依存しないオプティマイザーを提供できます。
これを行うのがはるかに複雑になるのはなぜでしょうか?それは中間表現によって異なります。中間表現の設計目標の 1 つは、さまざまな最適化を不必要に複雑にするのではなく、容易にすることです。たとえば、LLVM IR での作業で LLVM が達成できるすべての最適化を参照してください。 分析パスと変換パスのリスト。