LLILC (ライラック: LLVM ベースの IL コンパイラー)
なんか割かしひっそりと公開されていましたが、.NET Foundation 配下で、LLVM ベースの IL コンパイラー(.NET の IL コードをネイティブ コード化)が出てきました。
プロジェクト名 LLILC。LLVM な IL Compiler で LL IL C でしょうし割かし安直なんですが、「lilac」(普通に花のライラック)と読ませるそうで読み方的には結構おしゃれ。縦棒並びすぎロシアの筆記体かよとか、L 並びすぎ呪文かよとか思ったりもしますが。
LLVM
大きなイベントで発表があったわけではなく、MSDN Blogs で取り上げられるでもなく(.NET Foundation のブログ記事はあり)、LLVM Project Blog でブログ記事が上がるってあたりが何か新しい。
マイクロソフトが LLVM を使うこと自体は少し前から前兆みたいなものはあって、例えば、去年、インターンで来た学生が、.NET Native のコード生成部分での LLVM 利用について調査してたとかがあったりします。
LLILC (JIT)と RyuJIT
LLILC は、予定としては JIT と AOT の両方を提供するそうですが、最初のターゲットは JIT だそうです。つまるところ、やってること自体は RyuJIT (マイクロソフトの最新の JIT 実装)と同じになります。
LLILC と RyuJIT は求めるものが異なっていて相補的な立ち位置にあります。
RyuJIT は高いパフォーマンスを求めていて、.NET 特有の(特に、C# 特有の)最適化をガチガチに掛けます。
一方で、LLILC は、LLVM の中間形式を経るので(Clang などの実績があってかなりよい最適化がかかるとはいえ)、RyuJIT ほどのパフォーマンスは出ないはずです。パフォーマンスよりも、より多くの環境で .NET プログラムが動くという点を求めています。
LLILC の現状の進捗としては Windows のみ。当面の目標としては Linux と Mac OS を狙っているそうです。また、LLILC が見本となることで、他の開発者による LLVM 実装が容易になればという期待もあるそうです。
LLILC (AOT)と .NET Native
(予定には含まれている) AOT 対応では、今度は .NET Native に近い土俵になります。ただ、.NET Native は単に IL からのネイティブ コード生成すること以外にも、より多くの仕事を担っています:
- (JIT の場合動的にやっている)マーシャリング向けのコードをコンパイル時に生成する
- (これも通常は動的にやる)シリアライズ用のコードを生成する
- 複数のアセンブリ(DLL, EXE)を1つにまとめる(アセンブリをまたいだ最適化が掛かるようにする)
- AOT 向けに IL コードを書き替え・最適化する
- 使われていないコード・型情報を削除する
- ネイティブ コード化する
(詳しくは .NET Native Performance and Internals を参照)
このうち、LLILC (AOT)が担える仕事は 6. の部分になります。今の .NET Native はこの部分にマイクロソフト製 C++ コンパイラー(cl.exe)と共通のインフラを使っているそうです。当然、この部分は LLILC での置き替えも考えられます。おそらくは、LLILC (JIT)と RyuJIT と同じような、高いパフォーマンスと、多くの環境で動くことのトレードオフになるでしょう。
マイクロソフト以外による LLVM 実装
Mono のランタイムは今、IL のコンパイル(JIT も AOT も)に LLVM を使って(使えるオプションを提供して)います。他にも、SharpLang とか LLVMSharp とか、いくつかの実装があるみたいです。それにマイクロソフト自身も、内部的には(たぶん、研究目的)LLVM 実装を持っていたそうです。
これらをそのまま使わなかった理由は、CoreCLR のインターフェイスに合わせるためとのこと。なので、LLILC のインターフェイスは RyuJIT のものとそろっているそうです。
LLILC と Roslyn (コンパイラーのフロントエンドとバックエンド)
RyuJIT が出た時にも詳しくない人は少し混乱したみたいなんですが、コンパイラーにはフロントエンドとバックエンドがあります。
フロントエンドの仕事は、高級言語から何らかの中間形式(抽象構文木(AST: abstract syntax tree)とか、仮想マシン語コード(.NET でいう IL、LLVM でいう BitCode)とか)に変換するところまで。バックエンドの仕事は、その中間形式から何らかの成果物(特定 CPU のマシン語コード化や、他の高級言語への変換)を得ることです。
フロントエンドとバックエンドが分かれていることで、高級言語の専門家と、CPU コード生成の専門家が分業できるというメリットがあります。分業によって、いろんな高級言語を、いろんな環境に対応させやすくなります。また、多くの場合、それぞれの専門家の努力によって、高級言語から一気に CPU コードを生成するよりも、中間形式を挟む方がよりよいコード生成ができたりします。
Roslyn (C#/VB コンパイラー)の仕事はフロントエンドです。C#/VB のソースコードを、IL (.NET の中間言語)に変換するところまでが仕事です。この範疇でやれることは、例えば以下のようなものです。
- 高級言語の構文ハイライト
- 警告やエラーが出ている箇所を(下線を引くなどして)表示
- 変数やメソッドなどの「定義へ移動」「参照の検索」
- ソースコードのリファクタリングや整形
- 静的ソースコード分析(人的ミスを起こしやすそうなコードの発見や、コーディング規約への準拠チェックなど)
一方、LLILC の仕事はバックエンドで、CPU コード生成に加えて、以下のようなものが含まれ得ます。
- プロファイリング、コード追跡、デバッグなど用の IL コード追加
- 自動ベクトル化(SIMD 命令や GPU の活用)や自動並列化
- テストケース削減(コード分析によってある程度のテストケースを自動的に作る。この手の機能は、Visual Studio 2015 にも載る予定: Smart Unit Tests)
LLILC がやっていること
LLILC は、要するに以下のような仕事をします。
- IL (.NET の中間形式)の読み込み
- IL から BitCode (LLVM の中間形式)への変換
- .NET 固有な機能の提供
.NET 固有な機能には例えば以下のようなものがあります。
- COFF (Common Object File Format: 実行形式ファイル中の情報)ローダー
- ガベージ コレクション(.NET は強い型情報を持っているので、この情報に基づいて効率よくガベージ コレクションを提供できる)
- 型情報に基づく最適化
- 例外処理機構
[…] なんか割かしひっそりと公開されていましたが、.NET Foundation 配下で、LLVM ベースの IL コンパイラー(.NET の IL コードをネイティブ コード化)が出てきました。 プロジェクト名 LLILC。LLVM な IL Compiler で LL IL C でしょうし割かし安直なんですが、「lilac」(普通に花のライラック)と読ませるそうで読み方的には結構おしゃれ。縦棒並びす…[続きを読む] […]
LLILC (ライラック: LLVM ベースの IL コンパイラー) | ++C++; // 未確認飛行 C ブログ | Apple FAN|macやiPhoneなどアップル製品のニュースサイト
2015年4月17日 at 15:02