llvmチュートリアル(その4)

今回は関数を定義してみたいと思います。

llvmrubyで生成したllvmのコードをRubyから実行するには、関数を定義しないといけません。ちょうど、C言語でmain関数を定義しないといけないことと似ています。ただし、llvmrubyでは関数の名前は正しい関数の名前であれば、何でもいいです。実行するときに、この関数から実行してねって引数で渡すことになっています。

Hello Worldの関数を定義するところを見てみます。

ftype = Type.function(Type::Int32Ty, [])
main = m.get_or_insert_function('main', ftype)
b = main.create_block.builder

ftypeはその3で説明したとおりです。関数の型を定義します。今回は32ビットの整数を返すようにします。引数はありません。引数が無いときは[]とします。

次に「main = m.get_or_insert_function('main', ftype)」で関数を定義します。mにはその3で重要だと書いたLLVM::Moduleクラスのインスタンスです。get_or_insert_fucntionは関数を定義するメソッドで、名前の通り関数を定義するか、既に関数が定義されているときはその定義されている関数を返します。get_or_insert_fucntionが返す値は関数オブジェクトです。'main'の関数オブジェクトをmainという変数に入れておきます。

次に「b = main.create_block.builder」で、main関数内にブロックを作って、そのブロックのbuilderを変数bに入れます。
ブロックとはLLVMの命令列です。ただし、ジャンプ命令はブロックの最後にしか現れません。結局ブロックは、途中で流れを変えないで実行する命令列といえます。LLVMでは関数はブロックの集まりで表現します。そして、ジャンプ命令は飛び先をブロックで指定します。
builderとは命令を追加するためのオブジェクトです。builderのクラスには命令を追加するためのメソッドが定義されていて、それらのメソッドを呼ぶことでブロックの命令列を作っていきます。

つづく