2010年03月25日
LLVM の JIT を使ってみる (1)
LLVM を利用しているプロジェクトとしては MacRuby が有名ですが、他にも LLVM の JIT を利用しているプロジェクトはたくさん存在するようです。
The LLVM Compiler Infrastructure: Projects built with LLVM
では、具体的には、どのようにすれば LLVM の JIT が利用できるのでしょうか ?
The LLVM Compiler Infrastructure: Projects built with LLVM
では、具体的には、どのようにすれば LLVM の JIT が利用できるのでしょうか ?
LLVM には、Fibonacci など、API のサンプルがいろいろ付いています。
Index of /llvm/trunk/examples
ざっと眺めていたところ、HowToUseJIT というそのものズバリなサンプルがありました。main() 1つだけで、その中で API を使って関数を作ってモジュールに追加しています。
View of /llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp
GCC などのコンパイラの中身を眺めたことがある人ならば、すぐにピンとくるであろう、非常にわかりやすい API だと思いました。これはワクワクします。
上記サンプルを実行すると、このような出力結果が出ます。
その点 LLVM ならば、VisualStudio のプロジェクトを追加して、依存関係を設定するだけですぐに作れそうです。
HowToUseJIT の依存関係を見てみたところ、
Index of /llvm/trunk/examples
ざっと眺めていたところ、HowToUseJIT というそのものズバリなサンプルがありました。main() 1つだけで、その中で API を使って関数を作ってモジュールに追加しています。
View of /llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp
GCC などのコンパイラの中身を眺めたことがある人ならば、すぐにピンとくるであろう、非常にわかりやすい API だと思いました。これはワクワクします。
上記サンプルを実行すると、このような出力結果が出ます。
C:\llvm\work>HowToUseJIT.exe We just constructed this LLVM module: ; ModuleID = 'test' define i32 @add1(i32 %AnArg) { EntryBlock: %addresult = add i32 1, %AnArg ; <i32> [#uses=1] ret i32 %addresult } define i32 @foo() { EntryBlock: %add1 = tail call i32 @add1(i32 10) ; <i32> [#uses=1] ret i32 %add1 } declare void @abort() Running foo: Result: 11私は以前、GCC のフロントエンドの API を使って、サンプル言語のコンパイラを作ったりしていたのですが、その時はまず、自作フロントエンドを GCC のビルドシステムに組み込んでビルドできるところまで持っていくのが一苦労でした。
その点 LLVM ならば、VisualStudio のプロジェクトを追加して、依存関係を設定するだけですぐに作れそうです。
HowToUseJIT の依存関係を見てみたところ、
- intrinsics_gen
- LLVMAnalysis
- LLVMAsmPrinter
- LLVMCodeGen
- LLVMCore
- LLVMExecutionEngine
- LLVMInstCombine
- LLVMInterpreter
- LLVMIpa
- LLVMJIT
- LLVMMC
- LLVMScalarOpts
- LLVMSelectionDAG
- LLVMSupport
- LLVMSystem
- LLVMTarget
- LLVMTransformUtils
- LLVMX86CodeGen
- LLVMX86Info
- ZERO_CHECK