Top Banner
LLVM勉強会梅田 2009115()
26

LLVM Workshop Osaka Umeda, Japan

May 06, 2015

Download

Technology

ujihisa

LLVM in 20 minutes
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: LLVM Workshop Osaka Umeda, Japan

LLVM勉強会梅田2009年1月15日(金)

Page 2: LLVM Workshop Osaka Umeda, Japan

LLVM概要

Tatsuhiro Ujihisa

Page 3: LLVM Workshop Osaka Umeda, Japan

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

In short,

CのためのJVM

ただし、gccでコンパイルした実行可能ファイルより速く動く

(ことが多い)

最適化がスゴい (後述)

Page 5: LLVM Workshop Osaka Umeda, Japan

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

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

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

LLVMの実行方法 (3)

LLVMアセンブラ → LLVMビットコード → インタプリタで実行

$ vim a.ll$ llvm-as a.ll -o a.bc$ lli a.bc

Page 9: LLVM Workshop Osaka Umeda, Japan

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

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

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

整理

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

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

LLVMアセンブリ言語の特徴

逐次処理

再代入禁止 (全ては定数)

Cの関数は大抵そのまま呼べる

Page 15: LLVM Workshop Osaka Umeda, Japan

ちなみに

VimのquickrunはLLVMアセンブリ言語対応済み

.llなファイルを編集中に<Space>rするだけでllvm-asとlliしてく

れる

Page 16: LLVM Workshop Osaka Umeda, Japan

LLVMの用途と目的

コンパイラを作る人のための道具。

新しいコンパイル型言語を作るなら、LLVMアセン

ブリ言語にさえ変換すればOK (C言語経由でもOK)

LLVMならばMac, Linux, Windowsで確実に動く上に、

かなり速い。

Page 17: LLVM Workshop Osaka Umeda, Japan

LLVM化された(らしい)言語処理系

C (llvm-gcc)

Perl

Python (pypy)

Ruby (Rubinius, MacRuby, etc)

Haskell

Brainf**k

... LLVM対応されていない言語を探す方が難しい

Page 18: LLVM Workshop Osaka Umeda, Japan

LLVM前提で作られた言語

Pure

動的型付け

関数型 (項書き換え)

ユーザ定義文法、マクロ

Haskell風の文法

sudo port install pure

Page 19: LLVM Workshop Osaka Umeda, Japan

ここまでのまとめ

LLVMは速くて便利

コンパイラを作るならLLVMを使おう

既にLLVMを使ったコンパイラがたくさん

Page 20: LLVM Workshop Osaka Umeda, Japan

問題点

まだ混沌 (最適化の二度漬けなど)

LLVMを使った処理系をビルドするのが難しいとき

も (MacRuby)

変化がすごすぎる (終わらないsvn up)

Page 21: LLVM Workshop Osaka Umeda, Japan

実践!

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

変換例: +

+: ポインタが示すメモリ位置のデータをインクリメント

/* Cでいうと、 *//* char *hがあるとして */++*h;

LLVMは変数の値を書き換えれない! → 変数としてはポインタだ

けを使えばとりあえずOK

Page 23: LLVM Workshop Osaka Umeda, Japan

コンパイラ実装例 (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

実演

$ 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

おわり

参考文献:

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