中間表現
中間表現(ちゅうかんひょうげん、英: Intermediate Representation、IR)は、コンピュータがデータをクロスプラットフォームで扱うため、あるいはその他多数のさまざまな目的のために使用されるデータ構造の表現である。
中間表現を用いたデータの抽象化は、コンピューティング分野では一般的な手法である。異なるプラットフォームで同等の情報を保持するデータを異なるフォーマットで扱う場合に、データを中間表現で表現することで複数フォーマットへの変換処理を効率化することを手助けできる、というのは、この手法のあまたある利点(あるいは応用)のごく1つである。
初期のBASIC処理系の実装で用いられた中間言語は、バイトコードのようなものではなく、字句解析のみを行い、BASICの各ステートメント(またはコマンド)を単にコードに直接変換するだけといったものもあった。実行時の字句解析が不要になるが、ソースコードに戻して表示、編集することもできる。GOTOの飛び先をキャッシュするなどの工夫がされたものもあった。高度な中間言語を利用する実装もあり、N88-日本語BASIC(86)(MS-DOS版)のコンパイラは、実行ファイルを出力するが、その内部は中間言語コードでありまたその実行には外部に、中間言語のインタプリタを含むランタイムライブラリが必要だった。
いくつかのバーチャルマシンやインタプリタは中間言語を直接実行する。しかし、実行時コンパイル(JITコンパイル)により、中間言語から実行環境に応じた機械語を生成してから実行するほうが高速である。
GPU上で動作するシェーダープログラムやコンピュートカーネルも、移植性の高い中間言語や中間表現が利用されることが多い。
Microsoft DirectX(Direct3D)では、DirectX 8でプログラマブルシェーダーが導入された当初はアセンブリ言語を利用してシェーダープログラムを記述していたが、このときすでにDXBC(DirectX Bytecode)と呼ばれるGPUベンダー非依存の中間表現を採用していた。まずDirect3Dランタイムがシェーダーコードのバリデーションを実行し、妥当性や有効性を事前に評価してから、Direct3Dドライバーがシェーダーコードを解釈する。この方式はグラフィックスドライバー側の負担を減らし、プログラムの品質を確保することにもつながる。
1980年代には一般的に見られるようになり、GNU Compiler Collectionでは、中間表現の内部形式はRegister Transfer Language(RTL)などの非依存なものであり、Machine Descriptions(MD)と呼んでいるターゲットの記述によってコードを生成することにより、複数の言語やターゲットに対応している。ただし、中間表現を外部のファイルに書き出したり、外部のファイルから読み込んだり、ということが簡単にできるようにはなっておらず、これは意図的なものである。
その後2000年頃から日本において、GPLでなく利用できるそのようなインフラストラクチャが必要だという考えから整備された「COINSコンパイラ・インフラストラクチャ」(COINS: a COmpiler INfraStructure)がある。COINSには高水準中間表現(HIR: High-level Intermediate Representation)と低水準中間表現(LIR: Low-level Intermediate Representation)があるなど、対応を広げるためと現代的な最適化のための充実した中間表現を持っている。またその少し後にあらわれたLLVMも同様に、ライセンスがGPLでなく、中間言語を活用しており、フロントエンドが異なるプログラミング言語のソースコードを1つの中間言語に変換し、バックエンドが1つの中間言語を異なるターゲットのコードへ変換する。LLVMはclang・rustc・Emscriptenなどの「コンパイラ基盤」として使われている。