llvm workshop osaka umeda, japan
DESCRIPTION
LLVM in 20 minutesTRANSCRIPT
![Page 1: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/1.jpg)
LLVM勉強会梅田2009年1月15日(金)
![Page 2: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/2.jpg)
LLVM概要
Tatsuhiro Ujihisa
![Page 3: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/3.jpg)
LLVM
The Low Level Virtual Machine (LLVM) is a compilerinfrastructure, written in C++, which is designed for compile-
time, link-time, run-time, and "idle-time" optimization ofprograms written in arbitrary programming languages. LLVM
was originally developed as a research infrastructure at theUniversity of Illinois at Urbana-Champaign to investigatedynamic compilation techniques for static and dynamic
programming languages...
http://en.wikipedia.org/wiki/Low_Level_Virtual_Machine
![Page 4: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/4.jpg)
In short,
CのためのJVM
ただし、gccでコンパイルした実行可能ファイルより速く動く
(ことが多い)
最適化がスゴい (後述)
![Page 5: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/5.jpg)
C言語のコードの実行方法
C → アセンブラ → 機械語 → 実行
$ vim a.c$ gcc a.c -S -o a.s$ gcc a.s -o a$ ./a
![Page 6: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/6.jpg)
LLVMの実行方法 (1)
C → LLVMアセンブラ → LLVMビットコード → インタプリタで
実行
$ vim a.c$ llvm-gcc a.c -S -o a.ll$ llvm-as a.ll -o a.bc$ lli a.bc
![Page 7: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/7.jpg)
LLVMの実行方法 (2)
C → LLVMアセンブラ → LLVMビットコード → 機械語 → 実行
$ vim a.c$ llvm-gcc a.c -S -o a.ll$ llvm-as a.ll -o a.bc$ llc a.bc -o a$ ./a
![Page 8: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/8.jpg)
LLVMの実行方法 (3)
LLVMアセンブラ → LLVMビットコード → インタプリタで実行
$ vim a.ll$ llvm-as a.ll -o a.bc$ lli a.bc
![Page 9: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/9.jpg)
LLVMの実行方法 (4)
LLVMアセンブラ → LLVMビットコード → 最適化 → インタプリ
タで実行
$ vim a.ll$ llvm-as a.ll -o a.bc$ opt a.bc -o a2.bc$ lli a2.bc
![Page 10: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/10.jpg)
LLVMの実行方法 (5)
LLVMアセンブラ → LLVMビットコード → 最適化 → 最適化 → イ
ンタプリタで実行
$ vim a.ll$ llvm-as a.ll -o a.bc$ opt -O3 a.bc -o a2.bc$ opt -O3 a2.bc -o a3.bc$ lli a3.bc
![Page 11: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/11.jpg)
LLVMの最適化の確認
逆アセンブル
$ llvm-as a.ll -o a.bc$ opt -O3 a.bc -o a2.bc$ opt -O3 a2.bc -o a3.bc$ llvm-dis a3.bc -o a3.ll$ vim a3.ll
![Page 12: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/12.jpg)
整理
llvm-as: LLVMアセンブリ言語ファイル(.ll) から
LLVMビットコード(.bc)に変換
lli: LLVMビットコード(.bc)を実行
opt: LLVMビットコード(.bc)を最適化し、別のLLVM
ビットコード(.bc)を生成
llvm-dis: llvm-asの逆
llvm-gcc: C言語ファイル(.c)からLLVMアセンブリ
言語(.ll)に変換
![Page 13: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/13.jpg)
LLVMアセンブリ言語でHello,world!
Hello, world!
@str = internal constant [14 x i8] c"Hello, world!\00"declare i32 @puts(i8*)define i32 @main(){ call i32 @puts( i8* getelementptr ([14 x i8]* @str, i32 0,i32 0)) ret i32 0}
![Page 14: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/14.jpg)
LLVMアセンブリ言語の特徴
逐次処理
再代入禁止 (全ては定数)
Cの関数は大抵そのまま呼べる
![Page 15: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/15.jpg)
ちなみに
VimのquickrunはLLVMアセンブリ言語対応済み
.llなファイルを編集中に<Space>rするだけでllvm-asとlliしてく
れる
![Page 16: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/16.jpg)
LLVMの用途と目的
コンパイラを作る人のための道具。
新しいコンパイル型言語を作るなら、LLVMアセン
ブリ言語にさえ変換すればOK (C言語経由でもOK)
LLVMならばMac, Linux, Windowsで確実に動く上に、
かなり速い。
![Page 17: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/17.jpg)
LLVM化された(らしい)言語処理系
C (llvm-gcc)
Perl
Python (pypy)
Ruby (Rubinius, MacRuby, etc)
Haskell
Brainf**k
... LLVM対応されていない言語を探す方が難しい
![Page 18: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/18.jpg)
LLVM前提で作られた言語
Pure
動的型付け
関数型 (項書き換え)
ユーザ定義文法、マクロ
Haskell風の文法
sudo port install pure
![Page 19: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/19.jpg)
ここまでのまとめ
LLVMは速くて便利
コンパイラを作るならLLVMを使おう
既にLLVMを使ったコンパイラがたくさん
![Page 20: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/20.jpg)
問題点
まだ混沌 (最適化の二度漬けなど)
LLVMを使った処理系をビルドするのが難しいとき
も (MacRuby)
変化がすごすぎる (終わらないsvn up)
![Page 21: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/21.jpg)
実践!
Brainf**k → LLVMアセンブリ言語
BFC: Brainf**k Compiler
git clone
git://github.com/ujihisa/bfc.git
vim bfc/bfc.rb
![Page 22: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/22.jpg)
変換例: +
+: ポインタが示すメモリ位置のデータをインクリメント
/* Cでいうと、 *//* char *hがあるとして */++*h;
LLVMは変数の値を書き換えれない! → 変数としてはポインタだ
けを使えばとりあえずOK
![Page 23: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/23.jpg)
コンパイラ実装例 (bfc.rbより抜粋)
when '+' a = tc += 1; b = tc += 1; c = tc += 1; d = tc += 1 "%tmp#{a} = load i32* %i, align 4\n" << "%tmp#{b} = getelementptr [1024 x i8]* %h, i32 0, i32 %tmp#{a}\n" << "%tmp#{c} = load i8* %tmp#{b}, align 1\n" << "%tmp#{d} = add i8 1, %tmp#{c}\n" << "store i8 %tmp#{d}, i8* %tmp#{b}, align 1\n"
1. ポインタが指す位置を取得
2. その位置から、実際のデータの位置を取得
3. その位置から、実際のデータを取得
4. そのデータに1を足す
![Page 24: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/24.jpg)
実演
$ cat helloworld.bf$ cat helloworld.bf | ruby bfc.rb --llvm > helloworld.ll$ llvm-as helloworld.ll > helloworld.bc$ opt -O3 helloworld.bc # 引数指定なしで自分自身を書き換える$ lli helloworld.bcHello, world!
もしくは単に
$ ruby bfc.rb --llvm helloworld.bf --run
![Page 25: LLVM Workshop Osaka Umeda, Japan](https://reader033.vdocuments.net/reader033/viewer/2022052821/55493f81b4c9050f4d8b4faf/html5/thumbnails/25.jpg)
おわり
参考文献:
BFC: Brainf**k Compilers
http://ujihisa.blogspot.com/2009/12/bfc-
brainfk-compilers.html
LLVM For Starters
http://ujihisa.blogspot.com/2009/12/llvm-
for-starters.html
Let's Try LLVM
http://ujihisa.blogspot.com/2009/12/let-
try-llvm.html