【ちゅうかんひょうげん】

中間表現(IR) とは?

💡 ソースとマシンコードの「通訳メモ」。これがあるから一つのコードが何でも動かせる。
📌 このページのポイント
中間表現(IR)の役割 C / C++ Rust Swift ソース言語 LLVM IR 中間表現 最適化パスを ここで適用 共通中間表現 x86-64 ARM RISC-V ターゲットCPU N言語 × M ターゲット → N+M の組み合わせに削減 IRがなければ N×M 通りのコンバーターが必要になる
中間表現(IR)による多言語・多ターゲット対応のしくみ
ひよこ ひよこ

中間表現って、コンパイルの途中で何か別のコードが生まれるってこと?

ペンギン先生 ペンギン先生

そうだよ。コンパイラソースコードをいきなりCPUの命令には変換しないで、まず「IRという中間のコード」に変換するんだ。そのIRをさらに最適化してから、最終的にマシンコードを生成するんだよ。

ひよこ ひよこ

なんでわざわざ中間を挟むの?

ペンギン先生 ペンギン先生

二つ大きな理由があるよ。一つ目は「最適化の共通化」。IRで最適化すれば、言語ごとに最適化ロジックを書き直さなくて済む。二つ目は「マルチターゲット対応」。同じIRからx86ARM・RISCVなど異なるCPU向けのコードを別々に出力できるんだ。

ひよこ ひよこ

LLVMって聞いたことあるけど、これもIRと関係あるの?

ペンギン先生 ペンギン先生

LLVMはまさにIRを中心に設計されたコンパイラ基盤だよ。ClangはC/C++をLLVM IRに変換して、その後のフェーズはLLVMに丸投げする。SwiftRustもLLVM IRを経由してネイティブコードになるんだ。

ひよこ ひよこ

JVMバイトコードもIRの仲間なの?

ペンギン先生 ペンギン先生

広い意味ではそうだよ。JavaKotlinはバイトコードに変換されて、JVM(Java仮想マシン)がそれを実行する。バイトコードはCPUに直接依存しない中間的な表現なので、IRと同じ役割を果たしているね。LLVMのIRと違うのは、バイトコードが仮想マシン上で実行される点だよ。

ひよこ ひよこ

IRを見ることって実際にあるの?

ペンギン先生 ペンギン先生

あるよ。たとえばClangなら `clang -emit-llvm -S` でLLVM IRをテキストで出力できるし、コンパイラを自作するときにはIRの設計が最大の課題になるんだ。WebAssemblyも一種のIRとして扱われることがあって、IRの概念はとても幅広いよ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「中間表現(IR)」って出てきたら「コンパイラがソースとマシンコードの間に作る抽象的な中間コード」と思えればだいたいOK!
📖 おまけ:英語の意味
「Intermediate Representation」 = 中間表現
💬 コンパイラ理論で古くから使われてきた概念で、「中間(Intermediate)」はソースとターゲットの中間にある、「表現(Representation)」はコードを別の形で表したもの、という意味だよ。
← 用語集にもどる