ちょっと話題の記事

LLVMとは

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

前回の記事「Rubyの処理系とGCについて」を書いたときに、LLVMがイマイチ理解できずもやっとしてたので調べました。このエントリーは「LLVMとは」でググった(先日の僕のような)人向けの記事です。間違ったことを書いてあったら教えてください。

疑問

この記事を書く前の疑問はおおよそ以下の様なものです。

  • LLVMはコンパイラ基盤って言われてるけど、コンパイラ基盤って何?
  • LLVMはコンパイラ基盤であってVMじゃないって言うけど、LLVMに含まれるJITコンパイラはVMと違うの?
  • LLVMでマシンコードを作ったあと、実際の実行はどうするの?

色々とググって調べたりしたのですが、LLVMの全体像がつかめるまとまった情報が見つからなかったので、一次情報(llvm.org)のドキュメントを読むことにしました。

Overview

The LLVM Compiler Infrastructure Project の訳です。

LLVMプロジェクトは、モジューラと再利用可能なコンパイラとツールチェーン技術の集まりです。その名前にもかかわらず、LLVMは従来のVMとはほとんど関係がありません。LLVMという名前は頭文字をとったものではなく、プロジェクトの名前です。

LLVMは、モダンでSSAベース1な任意のプログラミング言語の静的コンパイルと動的コンパイルの両方をサポートできるコンパイル戦略を提供することを目的とした、イリノイ大学の研究プロジェクトから始まりました。その後、LLVMはいくつかのサブプロジェクトからなるumbrella projectに成長しました。その多くは、学術研究はもちろん、幅広い分野の商業用やオープンソースプロジェクトによりプロダクションで使われています。LLVMプロジェクトのソースコードは、"UIUC" BSD-Style ライセンスです。

LLVMの主なサブプロジェクト

  1. LLVM Coreライブラリ
    sourceやtargetとは独立したモダンなオプティマイザと、多くの一般的なCPU(一般的ではないものもある)のコード生成をサポートしています。これらのライブラリは、LLVM intermediate representation(LLVM IR)として知られている、よく定義されたコード表現を中心に構成されます。LLVM Coreライブラリは、良くドキュメント化されていますので、あなた自身が言語を作成(または既存のコンパイラをもってきて)、オプティマイザやコードジェネレータとしてLLVMを使うことは特に簡単です。
  2. Clang
    LLVMネイティブなC/C++/Objective-Cのコンパイラで、驚くほど高速なコンパイルを提供することを目的としています。以下略。
  3. LLDB project
    LLVMとClangによって提供されたライブラリ上で、ネイティブなデバッガを提供します。以下略。
  4. ibc++ and libc++ ABI projects
    C++標準ライブラリの標準準拠と高性能な実装を提供します。以下略。
  5. compiler-rt project
  6. OpenMP subproject
  7. polly project
  8. libclc project
  9. klee project
  10. SAFECode project
  11. lld project

5以降の説明は、日本語に直しても意味が分からなくなってきたので割愛します。なんとなくですが「LLVM Coreライブラリ」が一番メインのプロジェクトということがわかります。一般的に「LLVMは〜」というとここを指すようですね。その他は「LLVM Coreライブラリ」の付随プロジェクトのように見えます。

Features

The LLVM Compiler Infrastructure Project の雑な訳です。

LLVM Features

この章はCとC++のコンパイラの話のようです。省略。

Strengths of the LLVM System

  1. LLVMはシンプルな低レベル言語を使います。
  2. LLVMにはCとC++向けのフロントエンドが含まれます。Java, Scheme, その他の言語のフロントエンドは開発中です。(´-`).。oO(フロントエンド?)
  3. LLVMにはすっごいオプティマイザが含まれます。超意訳。
  4. LLVMはlife-long compilation modelをサポートします。(´-`).。oO(全く分からん)
  5. LLVMはaccurate garbage collectionをフルサポートします。(´-`).。oO(お、GCがある。なんかVMっぽい?)
  6. LLVM code generatorというのがある。
  7. 以降は機能的な話ではないので省略。

うーん、いくつか気になるキーワードはありましたが、依然として全体像が見えません。図がほしい。図が。と思って「LLVM architecture」でググったらこんな図入りの解説が見つかりました。

The Architecture of Open Source Applications: LLVM

「11.4. LLVM's Implementation of Three-Phase Design」の図。

フロントエンドが各プログラム言語を解析する部分、中間にあるオプティマイザが「LLVM Coreライブラリ」、バックエンドが各プロセッサ向けのマシンコードを出力する部分でしょうか。「LLVM Coreライブラリ」の説明にもあったsourceとtargetはおそらく、このフロントエンドとバックエンドを指すのでしょう。そしてこれらは自分で作ることもできるようですね。なんとなくイメージが湧いてきました。

LLVM Audience

この章はLLVMが誰向けのものかについて書かれています。

  • コンパイラの研究者
  • VMの研究者
  • アーキテクチャの研究者
  • セキュリティの研究者
  • コンパイラのプロトタイプに興味があるインストラクターや開発者
  • パフォーマンスを追求したいエンドユーザ

答え合わせ

最初の疑問に戻って答え合わせをしようと思います。

Q1. LLVMはコンパイラ基盤って言われてるけど、コンパイラ基盤って何?

A1. 任意のプログラミング言語から任意のプロセッサのマシンコードにコンパイルできる基盤のことだと思います。

(2018/01/10 追記)LLVMを利用することで、中間言語の最適化処理や、様々なアーキテクチャに対応したマシンコードの生成処理を再利用できることがメリットになると思います。

Q2. LLVMはコンパイラ基盤であってVMじゃないって言うけど、LLVMに含まれるJITコンパイラはVMと違うの?

A2. (これはLLVMの説明に書いてあったわけじゃないけど、)VMはプロセッサをエミュレートするものに対して、JITコンパイラは機械言語にコンパイルして実行するという点が違うんじゃないかと思いました。

(2018/01/10 追記)コメントでご指摘いただいたように、例えばJVM(Java仮想マシン)はJITコンパイラを用いて実行2していながらVMと呼ばれるため、LLVMもJITコンパイラだからMVではないという表現は必ずしも正しくはなさそうです。言葉の定義の問題だと思うので、これ以上の言及は止めておきます。

Q3. LLVMでマシンコードを作ったあと、実際の実行はどうするの?

A3. (これもLLVMの説明に書いてあったわけじゃないけど、)そこはLLVMの範疇ではないので、LLVMがどうこうするという話ではないのだと思います。(2018/01/10 訂正)そのまま実行するなり、任意のVM向けのマシンコードを作ってVMが実行するなり、あると思います。そういうことかっ!!?JITコンパイルで動的に実行するなり、静的コンパイルしてマシンコードを生成して実行するなり、あるいは任意のVM向けのマシンコードを作ってVMが実行するなんてこともできるんじゃないかと思います。(訂正ここまで)

神(2018/01/10 追記)

この記事を書いた後に、自分が知りたかったことが非常によくまとまっている記事とスライドを見つけました。いろいろな仮想マシンが比較して紹介されていてとても分かり易いです。神としか言いようがありません。

終わりに

自分のリテラシーがなさすぎて日本語に訳しても理解できない部分が多かったですが、(2018/01/10 訂正)「LLVMはVMじゃない」ということが明確に分かってスッキリしました。「LLVMがVMじゃない」ということの意味はなんとなく理解できました。スッキリしてないな!!w(訂正ここまで)