LLVM

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」、CUDAOpenCL向けの「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に導入することについての議論

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。