LLVMを捨てたやつが書く、怪しげなLLVM入門

>>> @miura1729 RT @yppp: あーあ、llvm使って言語作りたいけどバイトコードの
組み立てかたがわからない・・・・・・、
あとBoehm GCの組み込みかたも・・・・・・、まずはASTを作れって話なんだけどなw
 ああ、やる気がほしい

http://twitter.com/repeatedly/status/29599415588

ご指名戴いて嬉しかったのでちょっとまとめてみます。かなり間違い、偏りもあると思いますが、教えてもらえると嬉しいです。

LLVMを使ってコンパイラを書く場合、LLVMの命令を知らないと話にならないのでまずは、LLVMの命令を覚えます。

http://llvm.org/docs/LangRef.html

でも、これ全部読んでも余り使わないと思います。とりあえず、
NamedTypes http://llvm.org/docs/LangRef.html#namedtypes
Functions http://llvm.org/docs/LangRef.html#functionstructure
Integer Types http://llvm.org/docs/LangRef.html#t_integer
Derived Types http://llvm.org/docs/LangRef.html#t_derived
命令セット   http://llvm.org/docs/LangRef.html#instref

あたりを読んでおけばよいと思います。肝はアセンブラっぽいのにデータに型があることです。また、getelementptr命令 (http://llvm.org/docs/LangRef.html#i_getelementptr)は理解しづらいと評判ですが、コンパイラを作ると必ず使うので頑張って理解しましょう。あと、型変換命令( http://llvm.org/docs/LangRef.html#convertops )はあまり他にはない命令だし、知らないとはまることがあるので覚えておいた方がよいと思います。

さて、LLVMのbitcodeの仕様が分かったところでコンパイラをどう構築するかみていきます。

実際にコンパイラを書く場合、次の3つの道があると思います。

  1. llvm-asを使って文字列でLLVMのbitcodeの命令を出力する
  2. C++で、LLVMAPIを直接使って作る
  3. llvmrubyやllvm-pyなどライブラリを使って作る

1番目の方法は良く分からないです。
2番目の方法もやったことがないのですが、http://llvm.org/docs/tutorial/ を読むのが定番じゃないかなと思いますが読んでないです。
3番目の方法はそのライブラリにサンプルプログラムが付いてくるでしょうからそれを読むとよいです。お勧め(というかそれしか知らないのですが…)はYARVの命令をllvmrubyで定義した https://github.com/tombagby/llvmruby/blob/master/lib/ruby_vm.rb です。

あと、実際の言語処理系でLLVMを生成しているところを読むのもよいです。結構大変そうですが、意外と分かるんじゃないかなと思います。例えば、
MacRuby  http://svn.macosforge.org/repository/ruby/MacRuby/trunk/compiler.cpp
unladen-swallow http://code.google.com/p/unladen-swallow/source/browse/#svn/trunk/JIT/opcodes

LLVMを使い始めると初めはassertionエラーで泣きそうになると思いますが、すぐ慣れて胃が痛くなるくらいで済むようになると思いますので頑張ってください。