| LLVM | |
|---|---|
| 原作者 | クリス・ラトナー、ヴィクラム・アドヴェ |
| 開発者 | LLVM 開発者グループ |
| 初回リリース | 2003 (2003年) |
| 安定版リリース | 21.1.8 [ 2 ] |
| プレビューリリース | 22.1.0-rc1 [ 3 ] |
| リポジトリ | |
| 書かれた | C++ |
| オペレーティング·システム | クロスプラットフォーム |
| タイプ | コンパイラ |
| ライセンス | Apache License 2.0 with LLVM Exceptions (v9.0.0以降) [ 4 ] レガシーライセンス: [ 5 ] UIUC ( BSDスタイル) |
| Webサイト | www.llvm.org |
LLVMは、コンパイラとツールチェーン技術の集合体[ 6 ]であり、あらゆるプログラミング言語のフロントエンドと、あらゆる命令セットアーキテクチャのバックエンドを開発するために使用できます。LLVMは、言語に依存しない中間表現(IR)を中心に設計されており、移植性の高い高水準アセンブリ言語として機能し、複数のパスにわたる様々な変換によって最適化できます。 [ 7 ] LLVMという名前は、もともとLow Level Virtual Machine(低レベル仮想マシン)の略でした。しかし、その後プロジェクトは拡大し、その名前はもはや頭字語ではなく、孤立した頭字語となっています。[ 8 ]
LLVM はC++で記述されており、コンパイル時、リンク時、実行時の最適化を目的として設計されています。 LLVM はもともとCおよび C++用に実装されていましたが、言語に依存しない設計により、さまざまなフロントエンドが生まれました。 LLVM を使用するコンパイラーを持つ言語 (または LLVM を直接使用しないが、コンパイルされたプログラムを LLVM IR として生成できる言語) には、ActionScript、Ada、.NETのC#、[ 9 ] [ 10 ] [ 11 ] Common Lisp、[ 12 ] PicoLisp、Crystal、CUDA、D、[ 13 ] Delphi、[ 14 ] Dylan、Forth、[ 15 ] Fortran、[ 16 ] FreeBASIC、Free Pascal、Halide、Haskell、Idris、[ 17 ] Jai (最適化されたリリースビルドのみ)、Java バイトコード、Julia、Kotlin、LabVIEWの G 言語、[ 18 ] [ 19 ]などがあります。 Objective-C、OpenCL、[ 20 ] PostgreSQLのSQLおよびPL/pgSQL、[ 21 ] Ruby、[ 22 ] Rust、[ 23 ] Scala、[ 24 ] [ 25 ] Standard ML、[ 26 ] Swift、Xojo、Zig、Odin [ 27 ]。
LLVMプロジェクトは、2000年にイリノイ大学アーバナ・シャンペーン校で、ヴィクラム・アドベとクリス・ラトナーの指導の下で始まりました。LLVMはもともと、静的および動的プログラミング言語の動的コンパイル手法を調査するための研究基盤として開発されました。LLVMは、イリノイ大学/NCSAオープンソースライセンス[ 4 ]、つまり寛容なフリーソフトウェアライセンスの下でリリースされました。2005年、アップル社はラトナーを雇用し、アップルの開発システム内での様々な用途のためにLLVMシステムに取り組むチームを結成しました[ 28 ]。LLVMは、2011年のXcode 4以来、macOSとiOS向けのアップルのXcode開発ツールの不可欠な部分となっています[ 29 ] 。
2006年、ラトナーはClangという新しいプロジェクトに着手しました。ClangフロントエンドとLLVMバックエンドの組み合わせは、Clang/LLVM、あるいは単にClangと呼ばれています。
LLVMという名称は、もともとLow Level Virtual Machine(低レベル仮想マシン)の頭字語でした。しかし、LLVMプロジェクトは、現在の開発者のほとんどが仮想マシンと考えるものとはほとんど関係のない包括的なプロジェクトへと進化しました。このため、頭字語は「紛らわしく」「不適切」なものとなり、2011年以降、LLVMは「正式には頭字語ではなくなり」[ 30 ]、LLVM包括的なプロジェクトに適用されるブランドとなりました[ 31 ] 。このプロジェクトは、LLVM中間表現(IR)、LLVMデバッガ、 C++標準ライブラリのLLVM実装( C++11およびC++14の完全サポート[ 32 ])などを網羅しています。LLVMはLLVM Foundationによって管理されています。コンパイラエンジニアのTanya Lattnerが2014年に会長に就任し[ 33 ]、2025年11月現在も会長兼エグゼクティブディレクターを務めています[ 34 ]。
「LLVMの設計と実装」に対して、ACM (米国計算機学会)はVikram Adve、Chris Lattner、Evan Chengに2012年のACMソフトウェアシステム賞を授与しました。[ 35 ]
このプロジェクトは当初UIUCライセンスの下で利用可能でした。2019年にリリースされたバージョン9.0.0以降、[ 36 ] LLVMはApache License 2.0 with LLVM Exceptionsに再ライセンスされました。[ 4 ] 2022年11月時点で、約400の貢献が再ライセンスされていません。[ 37 ] [ 38 ]
LLVMは完全なコンパイラシステムの中間層を提供することができ、コンパイラから中間表現(IR)コードを受け取り、最適化されたIRを出力します。この新しいIRは、ターゲットプラットフォームのマシン依存アセンブリ言語コードに変換・リンクすることができます。LLVMはGNUコンパイラコレクション(GCC)ツールチェーンからIRを受け入れることができるため、そのプロジェクト用に作成された様々な既存のコンパイラフロントエンドと併用できます。LLVMはバージョン7.5以降のgccでもビルドできます。[ 39 ]
LLVM は、コンパイル時またはリンク時に 再配置可能なマシン コードを生成することも、実行時にバイナリ マシン コードを生成することもできます。
LLVM は、言語に依存しない命令セットと型システムをサポートしています。[ 7 ]各命令は静的単一代入形式(SSA) です。つまり、各変数(型付きレジスタと呼ばれる) は 1 度代入され、その後凍結されます。これにより、変数間の依存関係の分析が簡素化されます。LLVM では、従来の GCC システムのようにコードを静的にコンパイルすることも、Javaのようにジャストインタイムコンパイル(JIT)によって IR からマシンコードに後でコンパイルすることもできます。型システムは、整数や浮動小数点数などの基本型と、ポインタ、配列、ベクトル、構造体、関数の 5 つの派生型で構成されています。具体的な言語の型構造は、LLVM でこれらの基本型を組み合わせることで表現できます。たとえば、C++ のクラスは、構造体、関数、関数ポインタの配列を組み合わせて表現できます。
LLVM JITコンパイラは、実行時にプログラムから不要な静的分岐を最適化できるため、プログラムに多くのオプションがあり、そのほとんどは特定の環境では不要であると容易に判断できる場合の部分評価に役立ちます。この機能は、 Mac OS X Leopard (v10.5)のOpenGLパイプラインで、不足しているハードウェア機能のサポートを提供するために使用されています。[ 40 ]
OpenGLスタック内のグラフィックスコードは中間表現のままにしておき、ターゲットマシンで実行する際にコンパイルすることができます。ハイエンドのグラフィックス処理装置(GPU)を搭載したシステムでは、結果として得られるコードは非常に軽量で、最小限の変更で命令をGPUに渡します。ローエンドのGPUを搭載したシステムでは、LLVMはGPUが内部で実行できない命令をエミュレートする、ローカルの中央処理装置(CPU)上で実行されるオプションのプロシージャをコンパイルします。LLVMは、Intel GMAチップセットを搭載したローエンドマシンのパフォーマンスを向上させました。同様のシステムがGallium3D LLVMpipeの下で開発され、 GNOMEシェルに組み込まれ、適切な3Dハードウェアドライバーがロードされていなくても実行できるようになりました。[ 41 ]
2011年には、GCCでコンパイルされたプログラムはLLVMでコンパイルされたプログラムよりも平均で10%優れたパフォーマンスを示しました。[ 42 ] [ 43 ] 2013年には、phoronixがLLVMがGCCに追いつき、ほぼ同等のパフォーマンスのバイナリをコンパイルしたと報告しました。[ 44 ]
LLVM は複数のコンポーネントを含む包括的なプロジェクトになりました。
LLVMはもともとGCCスタックの既存のコードジェネレータの代替として書かれたもので、 [ 45 ] GCCフロントエンドの多くがLLVMで動作するように修正され、現在は廃止されているLLVM-GCCスイートが生まれた。この修正には、GIMPLEからLLVMへのIRステップが含まれるのが一般的で、LLVMのオプティマイザとコード生成をGCCのGIMPLEシステムの代わりに使用できるようにした。AppleはXcode 4.x(2013年)を通じてLLVM-GCCの重要なユーザーであった。[ 46 ] [ 47 ] GCCフロントエンドのこの使用は一時的な手段と考えられていたが、LLVM/ Clangのより現代的でモジュール化されたコードベースとコンパイル速度 の出現により、ほとんど廃止された。
LLVM は現在、さまざまなフロントエンドを使用してAda、C、C++、D、Delphi、Fortran、Haskell、Julia、Objective-C、Rust、およびSwiftのコンパイルをサポートしています。
LLVMへの関心が高まったことにより、多くの言語向けの新しいフロントエンドを開発する取り組みがいくつか行われています。そのようなフロントエンドの一つがClangです。これはC、C++、Objective-Cをサポートする新しいコンパイラです。主にAppleによってサポートされているClangは、GCCシステムのC/Objective-Cコンパイラを、統合開発環境(IDE)との統合が容易で、マルチスレッドのサポートが幅広いシステムに置き換えることを目指しています。OpenMPディレクティブのサポートは、リリース3.8以降、 Clangに含まれています。[ 48 ]
Utrecht HaskellコンパイラはLLVM用のコードを生成できます。このジェネレータは開発初期段階でしたが、多くの場合、Cコードジェネレータよりも効率的でした。[ 49 ] Glasgow Haskellコンパイラ(GHC)のバックエンドはLLVMを使用しており、GHCまたはCコード生成後にコンパイルするネイティブコードと比較して、コンパイル済みコードの30%の高速化を実現しています。GHCに実装されている多くの最適化手法のうち、1つだけが欠けています。[ 50 ]
その他の多くのコンポーネントもさまざまな開発段階にあります。これには、Rustコンパイラ、Java バイトコードフロントエンド、共通中間言語(CIL) フロントエンド、Ruby 1.9 のMacRuby実装、 Standard MLのさまざまなフロントエンド、新しいグラフ カラーリングレジスタ アロケータなどが含まれますが、これらに限定されません。

LLVMの中核は中間表現(IR)であり、これはアセンブリ言語に似た低水準プログラミング言語です。IRは、ターゲットのほとんどの詳細を抽象化する、強く型付けされたRISC(縮小命令セットコンピュータ)命令セットです。例えば、呼び出し規約はcall明示的な引数を持つ命令によって抽象化されますret。また、IRは固定のレジスタセットの代わりに、%0、%1などの形式の無限の一時変数セットを使用します。LLVMは、人間が読めるアセンブリ形式、[ 51 ] 、フロントエンドに適したメモリ内形式、そしてシリアル化のための高密度ビットコード形式という、同等の3つのIR形式をサポートしています。人間が読めるIR形式で記述された 単純な「Hello, world!」プログラム:
@.str =内部定数[ 14 x i8 ] c "Hello, world\0A\00"i32 @printf ( ptr , ...)を宣言します。i32を定義します@main ( i32 %argc , ptr %argv ) nounwind {エントリ: %tmp1 = getelementptr [ 14 x i8 ], ptr @.str , i32 0 , i32 0 %tmp2 = call i32 ( ptr , ...) @printf ( ptr %tmp1 ) nounwind ret i32 0 }様々なターゲットで使用される様々な規約と提供される機能のため、LLVMは真にターゲットに依存しないIRを生成し、既存のルールに違反することなくそれをリターゲットすることはできません。ドキュメントに明示的に記載されているもの以外のターゲット依存性の例としては、オンライン配布を目的としたLLVM IRの完全にターゲットに依存しない変種である「wordcode」の2011年の提案が挙げられます。[ 52 ]より実用的な例としては、PNaClが挙げられます。[ 53 ]
LLVMプロジェクトでは、MLIR [ 54 ]と呼ばれる別のタイプの中間表現も導入されています。これは、Dialect [ 55 ]と呼ばれるプラグインアーキテクチャを採用することで、再利用可能で拡張可能なコンパイラインフラストラクチャの構築に役立ちます。これにより、多面体コンパイルなどの最適化プロセスでプログラム構造に関する高レベルの情報を利用できるようになります。
バージョン16のLLVMは、 IA -32、x86-64、ARM、Qualcomm Hexagon、LoongArch、M68K、MIPS、NVIDIA Parallel Thread Execution(PTX、 LLVMのドキュメントではNVPTXとも呼ばれる)、PowerPC、AMD TeraScale、[ 56 ]最新のAMD GPU( LLVMのドキュメントではAMDGPUとも呼ばれる)、[ 57 ] SPARC、z/Architecture (LLVMのドキュメントではSystemZとも呼ばれる)、XCoreなど、多くの命令セットをサポートしています。
一部の機能は一部のプラットフォームでは利用できません。ほとんどの機能はIA-32、x86-64、z/Architecture、ARM、PowerPCで利用可能です。[ 58 ] RISC-Vはバージョン7以降でサポートされています。
過去には、LLVMはCバックエンド、Cell SPU、mblaze(MicroBlaze)[ 59 ]、AMD R600、DEC / Compaq Alpha(Alpha AXP)[ 60 ]、Nios2 [ 61 ]などの他のバックエンドも完全にまたは部分的にサポートしていましたが、これらのハードウェアはほとんどが時代遅れであり、LLVM開発者はサポートとメンテナンスのコストがもはや正当化されないと判断しました。
LLVM はWebAssemblyもターゲットとしてサポートしており、コンパイルされたプログラムをGoogle Chrome / Chromium、Firefox、Microsoft Edge、Apple Safari、WAVMなどの WebAssembly 対応環境で実行できます。LLVM 準拠の WebAssembly コンパイラは通常、C、C++、D、Rust、Nim、Kotlin などの他の言語で記述された、ほとんど変更されていないソースコードをサポートします。
LLVMマシンコード(MC)サブプロジェクトは、テキスト形式とマシンコード間でマシン命令を変換するためのLLVMのフレームワークです。以前は、LLVMはアセンブリをマシンコードに変換するために、システムアセンブラまたはツールチェーンによって提供されるアセンブラに依存していました。LLVM MCの統合アセンブラは、IA-32、x86-64、ARM、ARM64など、ほとんどのLLVMターゲットをサポートしています。MIPSの各種命令セットを含む一部のターゲットでは、統合アセンブリサポートが利用可能ですが、まだベータ段階です。
lldサブプロジェクトは、LLVM用の組み込みでプラットフォームに依存しないリンカーを開発する試みです。[ 62 ] lldはサードパーティ製リンカーへの依存を排除することを目的としています。2017年5月現在、lldはELF、PE/COFF、Mach-O、WebAssembly [ 63 ]をサポートしています(完成度の高い順に)。lldはGNU ldのどちらのバージョンよりも高速です。
GNUリンカーとは異なり、lldはリンク時最適化(LTO)のサポートを組み込んでいます。これによりリンカープラグインの使用を回避できるため、コード生成が高速化されますが、一方で他のLTOとの相互運用性は損なわれます。[ 64 ]
LLVMプロジェクトには、MITライセンスとUIUCライセンスのデュアルライセンスであるlibc++というC++標準ライブラリの実装が含まれています。[ 65 ]
バージョン9.0.0以降、 LLVM例外付きのApache License 2.0に再ライセンスされました。 [ 4 ]
これは、多面体モデルを使用した自動並列化とベクトル化に加えて、キャッシュ局所性の最適化スイートを実装します。[ 66 ]
llvm-libcはLLVMプロジェクトのために設計された、未完成で近々リリース予定のABI非依存のC標準ライブラリです。 [ 67 ]
LLVMは寛容なライセンスを採用しているため、多くのベンダーが独自のLLVMチューニングフォークをリリースしています。これはLLVMのドキュメントでも公式に認められており、機能チェックではバージョン番号を使用しないことが推奨されています。[ 68 ]こうしたベンダーには以下が含まれます。
は、
LLVMベースの事前(AOT)コンパイラを使用して、プロジェクトのRubyソースコードをマシンコードに変換します。
「LLVM」は正式には頭字語ではなくなりました。かつてLLVMの略称として使われていたこともあり、その頭字語は紛らわしく、ほぼ最初から不適切なものでした。:) LLVMが他のサブプロジェクトを包含するようになるにつれて、その有用性は低下し、意味を失っていきました。
「LLVM」という名前はかつては頭字語でしたが、現在は包括的なプロジェクトのブランドとしてのみ使用されています。
ベンダーによって番号体系が異なるため、言語機能の確認にはマーケティングバージョン番号を使用しないでください。代わりに、機能チェックマクロを使用してください。
現在のNVVM IRはLLVM 5.0に基づいています。