LLVM は複数のコンポーネントを含む包括的なプロジェクトになりました。
フロントエンド
LLVMはもともとGCCスタックの既存のコード生成器の代わりとして書かれ、多くのGCCフロントエンドはこれと動作するように修正され、結果として今はなき LLVM-GCC スイートにたどり着きました。 この修正は一般に、GCCのGIMPLEシステムの代わりにLLVM最適化器とcodegenが使えるように、GIMPLEからLLVMへのIRステップを含んでいます。 Appleは、Xcode 4.x(2013年)までのLLVM-GCCの重要なユーザーであった。 このGCCフロントエンドの使用は、ほとんど一時的な措置と考えられていましたが、Clangの出現とLLVMとClangのモダンでモジュラーなコードベース(コンパイル速度も)の利点により、ほとんど時代遅れになっています。
LLVM は現在、さまざまなフロントエンドを使用して、Ada、C、C++、D、Delphi、Fortran、Haskell、Julia、Objective-C、Rust、および Swift のコンパイルをサポートしています。
LLVMに対する幅広い関心が、さまざまな言語用の新しいフロントエンドを開発するいくつかの取り組みに結びつきました。 最も注目されているのは、C、C++、および Objective-C をサポートする新しいコンパイラーである Clang です。 主にApple社がサポートしているClangは、GCCシステムのC/Objective-Cコンパイラを、統合開発環境(IDE)との統合が容易で、マルチスレッドのサポートが充実したシステムに置き換えることを目的としている。 OpenMP ディレクティブのサポートは、リリース 3.8 以降 Clang に含まれています。
ユトレヒト Haskell コンパイラーは、LLVM 用のコードを生成することができます。 このジェネレーターは開発の初期段階にありますが、多くの場合、C コード ジェネレーターよりも効率的でした。 LLVM を使用した Glasgow Haskell Compiler (GHC) バックエンドがあり、GHC または C コード生成後のコンパイルによるネイティブ コード コンパイルと比較して、コンパイル済みコードの 30% 高速化を達成していますが、GHC によって実装された多くの最適化技術のうちの 1 つだけが欠落しています。
他の多くのコンポーネントがさまざまな開発段階にあり、Rust コンパイラー、Java バイトコード フロントエンド、Common Intermediate Language (CIL) フロントエンド、Ruby 1.0 の MacRuby 実装などが含まれますが、これらに限定されるものではありません。
中間表現 編集
LLVM の中核は中間表現 (IR) であり、アセンブリに似た低レベルのプログラミング言語です。 IR は強く型付けされた縮小命令セット コンピューター (RISC) 命令セットであり、ターゲットのほとんどの詳細を抽象化します。 例えば、呼び出し規則は、明示的な引数を持つcall命令とret命令によって抽象化される。 また、IRでは、固定されたレジスタのセットの代わりに、%0, %1などの形式のテンポラリの無限セットを使用します。 LLVMは、人間が読めるアセンブリ形式、フロントエンドに適したインメモリ形式、シリアライズに適した高密度ビットコード形式の3種類の同等のIRをサポートしています。 IR フォーマットのシンプルな “Hello, world!” プログラム:
@.str = internal constant c"hello, world\0A\00"declare i32 @printf(i8*, ...)define i32 @main(i32 %argc, i8** %argv) nounwind {entry: %tmp1 = getelementptr , * @.str, i32 0, i32 0 %tmp2 = call i32 (i8*, ...) @printf( i8* %tmp1 ) nounwind ret i32 0}
異なるターゲットによって使用され提供される多くの異なる慣習は、LLVM が本当にターゲット非依存の IR を生成できず、いくつかの確立した規則を破らずにそれを再ターゲットできないことを意味しています。 ドキュメントで明示的に言及されている以上のターゲット依存の例は、オンライン配布を目的とした LLVM IR の完全にターゲットに依存しないバリエーションである「wordcode」に対する 2011 年の提案で見つけることができます。 より実用的な例は PNaCl です。
Back endsEdit
バージョン 3.0 では、LLVM の IR は完全にターゲットに依存しません。4 では、LLVM は ARM、Qualcomm Hexagon、MIPS、Nvidia Parallel Thread Execution (PTX; LLVM のドキュメントでは NVPTX と呼ばれています)、PowerPC、AMD TeraScale、AMD Graphics Core Next (GCN) 、SPARC、z/Architecture (LLVM のドキュメントでは SystemZ と呼ばれています)、x86、x86-64 および XCore など多くの命令セットをサポートしています。 プラットフォームによっては、一部の機能が使用できません。 ほとんどの機能は、x86, x86-64, z/Architecture, ARM, PowerPCで利用可能です。 RISC-Vはバージョン7でサポートされました。 過去にLLVMは、Cバックエンド、Cell SPU、mblaze (MicroBlaze)、AMD R600、DEC/Compaq Alpha (Alpha AXP)、Nios2など他のバックエンドも完全または部分的にサポートしていたが、これらのハードウェアはほとんど時代遅れで、LLVMのサポートやメンテナンスが正当化できない状態である。
LLVMはターゲットとしてWebAssemblyもサポートしており、Google Chrome / Chromium、Firefox、Microsoft Edge、Apple SafariまたはWAVMなどのWebAssembly対応環境でコンパイルしたプログラムを実行できるようにします。 LLVM 準拠の WebAssembly コンパイラーは通常、C、C++、D、Rust、Nim、Kotlin およびその他のいくつかの言語で書かれた、ほとんど修正されていないソース コードをサポートします。
LLVM machine code (MC) サブプロジェクトは、テキスト形式と機械コードの間で機械命令を変換するための LLVM のフレームワークです。 以前は、LLVM はアセンブリをマシン コードに変換するために、システムのアセンブラまたはツール チェーンによって提供されるものに依存していました。 LLVM MCの統合アセンブラは、x86、x86-64、ARM、ARM64を含むほとんどのLLVMターゲットをサポートしています。
LinkerEdit
ld>サブプロジェクトは、LLVM 用の組み込み、プラットフォーム非依存のリンカーを開発する試みです。 2017 年 5 月現在、lld は ELF、PE/COFF、Mach-O、および WebAssembly を完全な順にサポートしています。lld は GNU ld の両方のフレーバーより高速です。
GNU リンカーとは異なり、lld にはリンク時最適化のサポートが組み込まれています。 これは、リンカー プラグインの使用を回避するため、より高速なコード生成を可能にしますが、その一方で、他のフレーバーの LTO との相互運用性を禁止します。
C++ Standard LibraryEdit
LLVM プロジェクトは libc++ という C++ 標準ライブラリの実装を含み、MIT ライセンスおよび UIUC ライセンスのデュアル ライセンスです。
v9.0.0 以降、LLVM Exceptions とともに Apache License 2.0 に再ライセンスされました。
PollyEdit
これは、自動並列処理や多面体モデルを使ったベクトル化と同様にキャッシュ位置最適化のスイートを実装しています。 LLDB (デバッガ)
.