【コードせいせい】

コード生成(コンパイラ) とは?

最終更新:
💡 対象環境に合う命令やコードへ変換する

コンパイラが入力の表現を、対象環境で使うコードへ変換する処理。IRからCPU向けコードへの変換、命令選択・レジスタ割り当て・スケジューリング、出力とリンクの違いを解説します。

📌 このページのポイント
コード生成:対象環境に合うコードへ入力:IR中間表現出力対象向けコードCPU向けコード生成の主な処理の例命令選択演算を対象CPUの命令へレジスタ割り当て使う値の場所を決めるスケジューリング依存関係などで調整出力:アセンブリ・オブジェクトなど実行ファイルにはリンクが必要な場合も
矢印は入力から出力への変換、中央は固定の3工程や順序を示さない処理例です。出力形式は実装により、別の段階ではIRを生成する処理もあります。
ひよこ ひよこ
コンパイラのコード生成は、AIがソースコードを書くこと?
ペンギン先生 ペンギン先生
ここで扱うのは、コンパイラが入力の表現を別のコードへ変換する処理だよ。CPU向けのバックエンドでは、IRという中間表現から、そのCPUに合う命令列などを作る。AIによるソースコード作成とは文脈を分けよう。
ひよこ ひよこ
命令選択では、何を選ぶの?
ペンギン先生 ペンギン先生
IRにある演算などを、対象CPUで利用できる命令や組合せへ対応させるよ。同じ意味の計算でも、CPUの命令セットや設定によって出力が変わる。IRの1操作が、必ず1つのCPU命令になるわけではないんだ。
ひよこ ひよこ
レジスタ割り当ては、変数を16個の場所に入れること?
ペンギン先生 ペンギン先生
使う値を、対象CPUで利用できるレジスタへ割り付ける処理だよ。使える数や種類、制約はCPUや呼出規約などによって違う。足りない場合にはメモリへの退避が必要になることもある。「どのCPUも16個」と覚えないようにしよう。
ひよこ ひよこ
その後は、命令の順番を並べるだけ?
ペンギン先生 ペンギン先生
依存関係やCPUの特徴を考慮する命令スケジューリングなども行うけれど、工程はそれだけではないよ。LLVMの説明にも複数の段階がある。処理の順序や繰返しは実装によるので、命令選択→割り当て→並べ替えという固定の3工程ではないんだ。
ひよこ ひよこ
生成できたら、そのまま実行できる?
ペンギン先生 ペンギン先生
アセンブリやオブジェクトファイルなど、出力の形によるよ。必要なライブラリなどとリンクして実行ファイルにする場合もある。JITでは実行中にコードを生成することもあるけれど、それだけで常に速くなる保証はないんだ。
もっと詳しく知りたい人へ

最適化は、コード生成だけが担当する?

コンパイラの最適化は、IRなどを対象にした段階にもあります。CPU向けの生成では対象の命令や制約に応じた処理を行いますが、プログラム全体の速さはアルゴリズム、メモリの使い方、実行環境などにも左右されます。コンパイラの更新で、すべてのコードが毎回速くなるわけではありません。

「IRを生成する」と「IRから生成する」は矛盾する?

変換の段階が異なります。フロントエンドでは構文木などからIRを作り、バックエンドではIRから対象向けのコードを作ります。code generationという言葉を見たら、何を入力し、何を出力する段階かを確認すると理解しやすくなります。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「コード生成」って出てきたら「コンパイラで対象環境に合うコードを作る処理」と思えばだいたいOK!
📖 おまけ:英語の意味
「Code Generation」 = コードの生成
💬 文脈によって生成するものが異なります。LLVMのチュートリアルには構文木からLLVM IRへのcode generationもあり、必ず機械語だけを意味する用語ではありません。

参考資料

← 用語集にもどる