LLVM(エルエルヴィーエム)は、プログラムの最適化をコンパイル時、リンク時、実行時など、あらゆる段階で行うことを目的とした
コンパイラ基盤です。様々な
プログラミング言語に対応できるように設計されており、その柔軟性が大きな特徴です。
LLVMの概要
LLVMは、プラットフォームに依存しない中間表現であるLLVM-IRを生成し、このLLVM-IRを特定の機械語に変換します。LLVM-IRの段階で、言語やプラットフォームに依存しない最適化が行われるため、LLVMは言語とアーキテクチャの両方から独立しています。この設計により、特定の
プログラミング言語向けのモジュールと、マシン向けのコード生成部を用意することで、多種多様な言語とアーキテクチャに対応することが可能になっています。
LLVMはプロシージャ間最適化を積極的に行うだけでなく、静的
コンパイラとしても、JIT
コンパイラとしても使用できます。また、開発の様々な段階で使用できる多くの部品を提供しており、
JavaバイトコードやCILの
フロントエンド、
Pythonの
フロントエンド、グラフ彩色式のレジスタ割り付けモジュールなどが含まれます。特にJIT
コンパイラの場合、実行時に不要な静的分岐を最適化する機能があり、プログラムが実行時に様々なオプションを持つ場合に強力な最適化手法となります。例えば、Mac OS X v10.5では、この機能を活用して、
ハードウェア機能がない場合にOpenGLパイプラインを実現しています。
LLVM自体は
C++で書かれており、
イリノイ大学でVikram AdveとChris Lattnerによって
2000年に開発が開始されました。初期の
ライセンスは
イリノイ大学/NCSAオープンソース
ライセンスでしたが、バージョン9.0.0からはLLVM例外付き
Apache License 2.0に変更されています。
LLVM IRとビットコード
LLVMは、言語から独立した命令セットと
型システムを持ちます。命令の多くは3番地コード形式に似ており、各命令は静的単一代入形であるため、変数は一度代入されるとその後は変更されません。これにより、変数間の依存関係の解析が容易になります。
型変換は、cast命令を使って明示的に行われます。LLVMの基本型には、固定長の
整数型があり、派生型としてポインタ、
配列、ベクトル、構造体、関数の5つがあります。具体的な言語で構築される型は、LLVM上ではこれらの型を組み合わせて表現されます。例えば、
C++におけるクラスは、構造体と関数、そして関数へのポインタの
配列を組み合わせて表現されます。
MLIR (Multi-Level IR)
MLIRは、LLVM IRを特定の用途に合わせて拡張するための仕組みです。MLIRでは、LLVM IR自体も「llvm」方言として扱われます。また、一部のアーキテクチャ固有のSIMD/SIMT命令も方言として表現され、例えばx86アーキテクチャ向けの「x86vector」や「amx」、ARMアーキテクチャ向けの「arm_neon」や「arm_sve」、
NVIDIA GPUアーキテクチャ向けの「nvvm」、AMD GPUアーキテクチャ向けの「rocdl」などがあります。
その他のMLIRの方言には、
OpenMP向けの「omp」、
OpenACC向けの「acc」、
CUDAや
OpenCL向けの「gpu」、Vulkanや
OpenCLで使われる中間言語SPIR-V向けのSPIR-V方言などがあります。また、機械学習に用いられる高度なベクトル/行列操作に関連する方言(TOSA、vector、Linalg、affineなど)も存在します。Googleの
TensorFlowプロジェクトによるMHLO方言は、
TensorFlowだけでなくJAXやTorch-MLIRなどでも広く使われています。その後、Googleは他の大手企業と共同でOpenXLAプロジェクトを立ち上げ、
TensorFlowから独立したStableHLO方言の開発を開始しました。PyTorch 2.0のTorchDynamoの標準バックエンドであるTorchInductorで使用されているOpenAI Tritonも、バックエンドをMLIRに移行し、独自のTriton方言およびTritonGPU方言を使用しています。
LLVMは、もともとGCCスタックよりも積極的な最適化を行う高性能なシステムとして開発されました。そのため、GCCの
フロントエンドをLLVMと連携させるための修正が行われました。現在では、GCC 4.6から派生した
フロントエンド(dragonegg)を用いて、
C言語、
C++、FORTRAN、
Adaをサポートし、Objective-C、Objective-
C++、Goもほぼ動作します。
しかし、LLVMへの関心が高まるにつれて、多数の
プログラミング言語に対応する新しい
フロントエンドの開発が進みました。特に注目されているのは、C、
C++、Objective-C、Objective-
C++をサポートする新しい
コンパイラClangです。
Appleの支援を受けて開発された
Clangは、GCCのC/
C++/Objective-C/Objective-
C++コンパイラを、統合開発環境と連携できるマルチスレッド対応のシステムで置き換えることを目指しています。GCCにおけるObjective-C/Objective-
C++の開発は停滞気味であり、
Appleが行った変更は別途メンテナンスされています。
Appleは自社で
コンパイラを開発することにより、Objective-C/Objective-
C++の実装を主導しつつ、統合開発環境との連携や現代的な機能への対応を実現しています。
Flangは、LLVMプロジェクトのFORTRAN
コンパイラです。旧来のFlangは
NVIDIAのnvfortranの派生でしたが、f18プロジェクトとして開発された次世代Flangは、
C++17やMLIRなどの新しい技術を採用しています。
Torch-MLIRは、機械学習で用いられるPyTorch向けの
コンパイラで、元々は
NumPyの
コンパイラであったnpcompが基になっています。
Polygeistは、従来のLLVM IRの代わりにMLIRを使用した実験的なC/
C++コンパイラです。MLIRを使用することで、多面体最適化が可能になり、C/
C++から
CUDAへのコンパイルもサポートしています。
標準C++ライブラリ
GNUはlibstdc++という標準
C++ライブラリを開発していますが、LLVMも独自のlibc++という標準
C++ライブラリを開発しています。
参照
関連項目
Clang
C--
Swift
OpenCL
Julia
外部リンク
公式ウェブサイト
LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation — by Chris Lattner and Vikram Adve.
LLVM Language Reference Manual — LLVMの中間表現の解説
*
LLVM/GCC Integration Proposal — LLVMをGCCに導入することについての議論