tokuhirom's Blog

llvmの基本となるツールたち 〜llvm 入門 その1〜

http://www.ibm.com/developerworks/jp/opensource/library/os-createcompilerllvm1/
最初なのでとりあえず↑の記事を基本なぞってます。

llvm ってなんなん?

LLVMは(Low Level Virtual Machineの略
LLVMは lightweight language とは関係ない。
LLVMはclang/clang++のバックエンドとしてつかわれている
LLVMはコンパイラーツクール

llvm IR とは?

intermediate representation(中間表現)のこと。 llvm API でくみたてることができる。dump してテキストで表現することも可能。dump したテキスト表現を llvm アセンブリとよんだりするようです。

重要な3つのツール

lli

llvmアセンブリを実行するインタープリタ。その場で JIT して実行。

llvm-gcc

llvm-gcc -S -emit-llvm foo.c

とすると、llvmアセンブリをはいてくれる!

llc

llvmアセンブリをネイティブのアセンブリに変換する。

3つのツールをためす

helloworld.c はこちら。

#include <stdio.h>
int main( )
{ 
  printf("Hello World!\n");
}

llvmアセンブリを生成!

$ llvm-gcc -S -emit-llvm helloworld.c 

helloworld.s ができてた。

; ModuleID = 'helloworld.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin11.4"

@.str = private constant [13 x i8] c"Hello World!\00", align 1 ; <[13 x i8]*> [#uses=1]

define i32 @main() nounwind ssp {
entry:
  %retval = alloca i32                            ; <i32*> [#uses=1]
  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
  %0 = call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
  br label %return

return:                                           ; preds = %entry
  %retval1 = load i32* %retval                    ; <i32> [#uses=1]
  ret i32 %retval1
}

declare i32 @puts(i8*)

実行してみる。

$ lli helloworld.s 
Hello World!

そして、ネイティブアセンブラへの変換もためす。

$ llc helloworld.s

helloworld.s.s という名前で x86 asm ができていた。

        .section        __TEXT,__text,regular,pure_instructions
        .globl  _main
        .align  4, 0x90
_main:                                  ## @main
## BB#0:                                ## %entry
        pushq   %rax
        leaq    L_.str(%rip), %rdi
        callq   _puts
        movl    4(%rsp), %eax
        popq    %rdx
        ret

        .section        __TEXT,__const
L_.str:                                 ## @.str
        .asciz   "Hello World!"


.subsections_via_symbols

なるほど動いている様子。

まとめ

llvm のツールをいくつかみてみた。各フェーズごとに途中経過をみれるのがありがたい。