コンテンツにスキップ

LLVM

出典: フリー教科書『ウィキブックス(Wikibooks)』

LLVMハンドブック

[編集]

はじめに

[編集]

LLVMとは

[編集]

LLVMは、コンパイラを開発するためのモジュール化されたフレームワークであり、再利用可能なコンパイラおよびツールチェーンコンポーネントのセットです。LLVMは、最適化、コード生成、リンカなど、コンパイルプロセスの多くの段階で使用されます。

LLVMの歴史と開発コミュニティ

[編集]

LLVMは2000年代初頭にクリス・ラットナーによって設立されました。その後、Apple、Google、Facebookなどの主要企業がLLVMを採用し、開発を支援しています。LLVMプロジェクトはオープンソースであり、世界中の開発者が貢献しています。

かつてBSD系UNIX(FreeBSDやNetBSDなど)では、GCCやbinutilsがコンパイラツールチェインとして使用されていましたが、2000年代に相次いでLLVM/Clangに移行しました。

LLVMプロジェクトの全体構成

[編集]

LLVMプロジェクトは、以下の多くのサブプロジェクトで構成されています。

各サブプロジェクトについては、後続の章で概要を説明し、詳細は専用のハンドブックを参照してください。

LLVMメインプロジェクト

[編集]

LLVMコアライブラリ

[編集]

LLVMコアライブラリは、コンパイラのフロントエンドからバックエンドまで、すべての段階で使用される基本的なライブラリです。

インストールとビルド

[編集]

LLVMのインストールとビルドは、以下のコマンドで行います。

git clone --depth=1 -b llvmorg-18.1.6 https://github.com/llvm/llvm-project.git
cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="llvm" -DCMAKE_BUILD_TYPE=Release llvm
cmake --build build/

基本的な使い方

[編集]

LLVMは、様々なツール(clangoptllcなど)を提供しています。例えば、C言語のソースコードをコンパイルしてLLVM IRに変換するには、以下のようにします。

clang -S -emit-llvm hello.c -o hello.ll

中間表現(IR)

[編集]

LLVM IRは、LLVMコンパイラフレームワークの中心であり、フロントエンドとバックエンドの間でコードを表現するための形式です。

最適化パス

[編集]

LLVMは、多くの最適化パスを提供しており、これを使用してコードを最適化できます。最適化パスの例として、デッドコード除去やループ最適化があります。

進んだ使い方とカスタマイズ

[編集]

LLVMは、高度にカスタマイズ可能であり、独自の最適化パスやコード生成器を追加することができます。

Clangと周辺ツール

[編集]

Clangの概要

[編集]

Clangは、C、C++、Objective-C、Objective-C++用のLLVMベースのフロントエンドです。高速でモジュール化されており、他のツールやIDEと容易に統合できます。

インストールとビルド

[編集]

Clangのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" llvm
cmake --build build/

基本的な使い方

[編集]

Clangを使用してC++プログラムをコンパイルするには、以下のようにします。

clang++ hello.cpp -o hello

コンパイルオプションとフラグ

[編集]

Clangは、多くのコンパイルオプションを提供しており、最適化レベルの指定や警告の制御が可能です。

clang++ -march=native -Oz -Weverything -std=c++23 -use-ld=lld hello.cpp -o hello

静的解析ツール

[編集]

Clangには、静的解析ツールが組み込まれており、コードの品質を向上させるために使用できます。

進んだ使い方とカスタマイズ

[編集]

Clangは、プラグインを通じて機能を拡張することができます。また、AST(抽象構文木)を直接操作することも可能です。

compiler-rt

[編集]

compiler-rtの概要

[編集]

compiler-rtは、LLVMとClangに依存するランタイムライブラリ群です。主にサニタイザやプロファイリングツールとして使用されます。

インストールとビルド

[編集]

compiler-rtのインストールとビルドは、LLVMとClangのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" llvm
cmake --build build/

サニタイザ(AddressSanitizer, ThreadSanitizer, UndefinedBehaviorSanitizerなど)

[編集]

compiler-rtには、様々なサニタイザが含まれており、メモリエラーやデータ競合などを検出することができます。

clang -fsanitize=address example.c -o example
./example

プロファイリングツール

[編集]

compiler-rtには、プロファイリングツールも含まれており、パフォーマンスのボトルネックを特定するのに役立ちます。

進んだ使い方とカスタマイズ

[編集]

compiler-rtの機能をカスタマイズすることで、特定のニーズに応じたエラー検出やプロファイリングが可能です。

Polly

[編集]

Pollyの概要

[編集]

Pollyは、LLVMのループ最適化ツールです。ループの並列化やタイル化を行うことで、プログラムの実行速度を向上させます。

インストールとビルド

[編集]

Pollyのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;polly" llvm
cmake --build build/

基本的な使い方

[編集]

Pollyを使用してコードを最適化するには、clang-mllvmおよび-pollyオプションを使用します。

clang -O3 -mllvm -polly example.c -o example

ループ最適化

[編集]

Pollyは、ループの依存関係を解析し、並列化やタイル化を行います。これにより、プログラムの実行速度を大幅に向上させることができます。

進んだ使い方とカスタマイズ

[編集]

Pollyの機能をカスタマイズすることで、特定のループ最適化手法を適用することが可能です。

libFuzzer

[編集]

libFuzzerの概要

[編集]

libFuzzerは、LLVMプロジェクトの一部であり、ライブラリ内のバグを検出するためのファジングツールです。入力をランダムに生成し、テスト対象の関数に与えて異常動作を引き起こすことで、バグを発見します。

インストールとビルド

[編集]

libFuzzerのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" llvm
cmake --build build/

基本的な使い方

[編集]

libFuzzerを使用するには、ファジング対象の関数を定義し、libFuzzerのAPIを使用してファズテストを実行します。

#include <stdint.h>
#include <stddef.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    // ファジング対象のコード
    return 0;
}

コンパイルと実行は以下の通りです。

clang++ -fsanitize=fuzzer example.cpp -o example
./example

進んだ使い方とカスタマイズ

[編集]

libFuzzerは、カスタムの入力生成器やターゲット関数のインストルメンテーションをサポートしており、特定のニーズに合わせてカスタマイズ可能です。

LLDB

[編集]

LLDBの概要

[編集]

LLDBは、LLVMプロジェクトのデバッガであり、高速でモジュール化されたデバッグツールです。C、C++、Objective-Cなどの言語をサポートしています。

インストールとビルド

[編集]

LLDBのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;lldb" llvm
cmake --build build/

基本的な使い方

[編集]

LLDBを使用してプログラムをデバッグするには、以下のコマンドを使用します。

lldb ./example
(lldb) target create "./example"
(lldb) run

デバッグテクニック

[編集]

LLDBは、ブレークポイント設定、ステップ実行、変数の検査など、多くのデバッグ機能を提供します。

(lldb) breakpoint set --name main
(lldb) step
(lldb) print variable_name

進んだ使い方とカスタマイズ

[編集]

LLDBはスクリプトを使用してカスタマイズ可能であり、Pythonスクリプティングをサポートしています。

LLD (Linker)

[編集]

LLDの概要

[編集]

LLDは、LLVMプロジェクトのリンカであり、高速かつ柔軟性に富んだリンキングツールです。ELF、COFF、Mach-Oなど、様々なフォーマットをサポートしています。

インストールとビルド

[編集]

LLDのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;lld" llvm
cmake --build build/

基本的な使い方

[編集]

LLDを使用してプログラムをリンキングするには、以下のコマンドを使用します。

clang++ -fuse-ld=lld example.o -o example

進んだ使い方とカスタマイズ

[編集]

LLDは、多くのリンキングオプションを提供しており、特定のリンキングシナリオに応じてカスタマイズ可能です。

libc++

[編集]

libc++の概要

[編集]

libc++は、LLVMプロジェクトの一部である標準C++ライブラリです。最新のC++標準に準拠しており、高いパフォーマンスと互換性を提供します。

インストールとビルド

[編集]

libc++のインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" llvm
cmake --build build/

基本的な使い方

[編集]

libc++を使用するには、コンパイル時に指定します。

clang++ -stdlib=libc++ example.cpp -o example

進んだ使い方とカスタマイズ

[編集]

libc++は、高度にカスタマイズ可能であり、独自のアロケータやスレッド管理機能を実装することができます。

OpenMP

[編集]

OpenMPの概要

[編集]

OpenMPは、マルチプラットフォームの並列プログラミングAPIであり、C、C++、Fortranで使用されます。LLVMは、OpenMPのコンパイラサポートを提供しています。

インストールとビルド

[編集]

OpenMPのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;openmp" llvm
cmake --build build/

基本的な使い方

[編集]

OpenMPを使用して並列プログラムを作成するには、以下のディレクティブを使用します。

#include <omp.h>

auto main() -> int {
    #pragma omp parallel
    {
        // 並列化されたコード
    }
    return 0;
}

コンパイルは以下の通りです。

clang++ -fopenmp example.cpp -o example

進んだ使い方とカスタマイズ

[編集]

OpenMPの高度な機能には、タスク並列性、データ指向の並列性、およびネストされた並列性が含まれます。

libclc

[編集]

libclcの概要

[編集]

libclcは、オープンソースのOpenCL実装であり、LLVMバックエンドを使用してOpenCLカーネルをコンパイルします。

インストールとビルド

[編集]

libclcのインストールとビルドは、以下の手順で行います。

git clone --depth=1 -b llvmorg-18.1.6 https://github.com/llvm/llvm-project.git
cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="libclc" llvm
cmake --build build/

基本的な使い方

[編集]

libclcを使用してOpenCLカーネルをコンパイルするには、Clangを使用します。

clang -x cl -cl-std=CL1.2 example.cl -o example.bc

進んだ使い方とカスタマイズ

[編集]

libclcは、特定のデバイス向けのカスタムビルトイン関数を追加するなど、カスタマイズが可能です。

libunwind

[編集]

libunwindの概要

[編集]

libunwindは、スタックトレースを取得し、例外処理のためにコールスタックを巻き戻すためのライブラリです。

インストールとビルド

[編集]

libunwindのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="libunwind" llvm
cmake --build build/

基本的な使い方

[編集]

libunwindを使用してスタックトレースを取得するには、以下のコードを使用します。

#include <libunwind.h>

auto printStackTrace() -> void {
    unw_cursor_t cursor;
    unw_context_t context;
    unw_getcontext(&context);
    unw_init_local(&cursor, &context);

    while (unw_step(&cursor) > 0) {
        unw_word_t offset, pc;
        unw_get_reg(&cursor, UNW_REG_IP, &pc);
        printf("0x%lx\n", pc);
    }
}

進んだ使い方とカスタマイズ

[編集]

libunwindは、特定のプラットフォームやアーキテクチャに応じてカスタマイズが可能です。

MLIR

[編集]

MLIRの概要

[編集]

MLIR(Multi-Level Intermediate Representation)は、LLVMプロジェクトの一部であり、ドメイン固有の中間表現を構築するためのフレームワークです。

インストールとビルド

[編集]

MLIRのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="mlir" llvm
cmake --build build/

基本的な使い方

[編集]

MLIRを使用して中間表現を操作するには、以下のコードを使用します。

#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"

auto main() -> int {
    mlir::MLIRContext context;
    auto module = mlir::ModuleOp::create(mlir::UnknownLoc::get(&context));
    module.dump();
    return 0;
}

進んだ使い方とカスタマイズ

[編集]

MLIRは、カスタムのディアレクトやオペレーションを定義することで、特定のドメインに適した中間表現を構築することが可能です。

BOLT

[編集]

BOLTの概要

[編集]

BOLT(Binary Optimization and Layout Tool)は、バイナリの最適化ツールであり、実行時プロファイリングデータを使用してバイナリのパフォーマンスを向上させます。

インストールとビルド

[編集]

BOLTのインストールとビルドは、以下の手順で行います。

git clone --depth=1 -b llvmorg-18.1.6 https://github.com/facebookincubator/BOLT.git
cd BOLT
cmake -S . -B build/ .. llvm
cmake --build build/

基本的な使い方

[編集]

BOLTを使用してバイナリを最適化するには、以下のコマンドを使用します。

perf record -e cycles:u ./example
llvm-bolt ./example -o example.bolt --data=perf.data

進んだ使い方とカスタマイズ

[編集]

BOLTは、詳細なプロファイリングデータを収集し、特定のコードパスを最適化することで、さらにパフォーマンスを向上させることができます。

Flang

[編集]

Flangの概要

[編集]

Flangは、LLVMプロジェクトのFortranコンパイラフロントエンドです。FortranコードをLLVM IRに変換し、最適化およびコード生成を行います。

インストールとビルド

[編集]

Flangのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="flang" llvm
cmake --build build/

基本的な使い方

[編集]

Flangを使用してFortranプログラムをコンパイルするには、以下のコマンドを使用します。

flang hello.f90 -o hello

進んだ使い方とカスタマイズ

[編集]

Flangは、特定の最適化パスやランタイムライブラリのカスタマイズをサポートしています。

WebAssemblyサポート

[編集]

WebAssemblyの概要

[編集]

WebAssembly(Wasm)は、バイナリ命令フォーマットであり、LLVMはWebAssembly向けのバックエンドを提供しています。

インストールとビルド

[編集]

WebAssemblyのインストールとビルドは、LLVMのビルドと一緒に行われます。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TARGETS_TO_BUILD="WebAssembly" llvm
cmake --build build/

基本的な使い方

[編集]

WebAssembly向けにコードをコンパイルするには、以下のコマンドを使用します。

clang --target=wasm32-unknown-unknown-wasm -O3 -o hello.wasm hello.c

進んだ使い方とカスタマイズ

[編集]

WebAssemblyのバックエンドは、カスタムセクションや特定の最適化オプションをサポートしています。

LLVM libc

[編集]

LLVM libcの概要

[編集]

LLVM libcは、LLVMプロジェクトによって提供される標準Cライブラリです。高い移植性とパフォーマンスを目指しています。

インストールとビルド

[編集]

LLVM libcのインストールとビルドは、以下の手順で行います。

cd llvm-project/
cmake -S . -B build/ -DLLVM_ENABLE_PROJECTS="libc" llvm
cmake --build build/

基本的な使い方

[編集]

LLVM libcを使用するには、コンパイル時に指定します。

clang --rtlib=libc hello.c -o hello

進んだ使い方とカスタマイズ

[編集]

LLVM libcは、高度にカスタマイズ可能であり、独自の機能や最適化を追加することができます。

附録

[編集]

コマンド一覧

[編集]

以下は、LLVM関連のユーティリティを「名称」と「解説」の順で表組みしたものです。

名称 解説
FileCheck テストファイル内のチェックを行うツール。
amdgpu-arch AMD GPUのアーキテクチャを識別するツール。
analyze-build ビルドログを解析するツール。
bugpoint LLVMのバグを特定するためのツール。
c-index-test Clangのインデックス機能をテストするツール。
diagtool 診断ツールのユーティリティ。
dsymutil DWARFデバッグシンボルを操作するツール。
find-all-symbols ソースコード内のシンボルを検索するツール。
git-clang-format Gitのコミットにclang-formatを適用するツール。
hmaptool ヘッダーマップを操作するツール。
intercept-build ビルドプロセスをインターセプトするツール。
lit LLVMのテストランナー。
llc LLVM IRを機械語にコンパイルするツール。
lld LLVMのリンカ。
lldb LLVMのデバッガ。
lldb-argdumper LLDBの引数をダンプするツール。
lldb-dap LLDBのDebug Adapter Protocol実装。
lldb-instr LLDBのインストルメンテーションツール。
lldb-server LLDBのリモートデバッグサーバー。
lli LLVM IRをインタプリタ実行するツール。
llvm-ar LLVMのアーカイブツール。
llvm-as LLVMアセンブリをバイナリ形式に変換するツール。
llvm-bcanalyzer LLVMビットコードを解析するツール。
llvm-c-test LLVM C APIをテストするツール。
llvm-cat LLVMビットコードファイルを連結するツール。
llvm-cfi-verify CFI(Control Flow Integrity)を検証するツール。
llvm-config LLVMの設定情報を表示するツール。
llvm-cov コードカバレッジ情報を表示するツール。
llvm-cvtres Windowsリソースファイルを変換するツール。
llvm-cxxdump C++オブジェクトファイルの情報をダンプするツール。
llvm-cxxfilt C++のマングルされたシンボルをデマングルするツール。
llvm-cxxmap C++のシンボルマッピングを生成するツール。
llvm-debuginfo-analyzer デバッグ情報を解析するツール。
llvm-debuginfod デバッグ情報を提供するサーバー。
llvm-debuginfod-find デバッグ情報を検索するツール。
llvm-diff LLVM IRの差分を比較するツール。
llvm-dis LLVMビットコードをアセンブリに変換するツール。
llvm-dwarfdump DWARFデバッグ情報をダンプするツール。
llvm-dwarfutil DWARFデバッグ情報を操作するツール。
llvm-dwp DWARFパッケージファイルを生成するツール。
llvm-exegesis マイクロベンチマークを生成するツール。
llvm-extract LLVM IRから関数やグローバル変数を抽出するツール。
llvm-gsymutil GSYMシンボル情報を操作するツール。
llvm-ifs インターフェーススタブを生成するツール。
llvm-jitlink JITリンクのユーティリティ。
llvm-libtool-darwin Darwin用のライブラリツール。
llvm-link LLVMビットコードファイルをリンクするツール。
llvm-lipo ユニバーサルバイナリを操作するツール。
llvm-lit LLVMのテストランナー。
llvm-lto LLVMのLTO(Link Time Optimization)ツール。
llvm-lto2 LTOの実験的なツール。
llvm-mc 機械語をアセンブル/ディスアセンブルするツール。
llvm-mca 機械語分析ツール。
llvm-ml LLVM MASM Assembler
llvm-modextract Module extractor
llvm-mt Manifest Tool
llvm-nm オブジェクトファイルのシンボルを表示するツール。
llvm-objcopy オブジェクトファイルをコピー/変換するツール。
llvm-objdump オブジェクトファイルの情報をダンプするツール。
llvm-opt-report 最適化レポートを生成するツール。
llvm-pdbutil PDB(Program Database)ファイルを操作するツール。
llvm-profdata プロファイルデータを操作するツール。
llvm-profgen プロファイルデータを生成するツール。
llvm-rc Windowsリソースコンパイラ。
llvm-readobj オブジェクトファイルの情報を表示するツール。
llvm-readtapi TAPIファイルを読み取るツール。
llvm-reduce テストケースを縮小するツール。
llvm-remarkutil 最適化レマークを操作するツール。
llvm-rtdyld ランタイムダイナミックリンカ。
llvm-sim シミュレーションツール。
llvm-size オブジェクトファイルのサイズを表示するツール。
llvm-split LLVM IRを分割するツール。
llvm-stress LLVM IRをランダムに生成するツール。
llvm-strings バイナリファイルから文字列を抽出するツール。
llvm-symbolizer アドレスをシンボル情報に変換するツール。
llvm-tblgen LLVMのテーブルジェネレータ。
llvm-tli-checker ターゲットライブラリインターフェースをチェックするツール。
llvm-undname マングルされたシンボルをデマングルするツール。
llvm-xray XRayのログを解析するツール。
modularize モジュール化ツール。
nvptx-arch NVIDIA PTXアーキテクチャを識別するツール。
opt LLVM IRを最適化するツール。
pp-trace プリプロセッサのトレースツール。
reduce-chunk-list チャンクリストを縮小するツール。
run-clang-tidy clang-tidyを実行するツール。
sancov サニタイザーカバレッジツール。
sanstats サニタイザーの統計情報を表示するツール。
scan-build 静的解析ツール。
scan-build-py scan-buildのPythonラッパー。
scan-view scan-buildの結果を表示するツール。
tblgen-lsp-server テーブルジェネレータのLSPサーバー。
tblgen-to-irdl テーブルジェネレータからIRDLを生成するツール。
verify-uselistorder use-listの順序を検証するツール。

この表は、LLVM関連の主要なユーティリティをまとめたものです。各ツールの詳細な使用方法やオプションについては、公式ドキュメントを参照してください。

下位階層のページ

[編集]

外部リンク

[編集]
Wikipedia
Wikipedia
ウィキペディアLLVMの記事があります。