https://speakerdeck.com/matuyuji/swiftzhong-jian-yan-yu-wodu-mu
この資料によると、Swiftは
- .swift
- Swift AST
- SIL
- LLVM IR
- LLVM BC
- Native asm
- Native binary
と辿っていくらしいです。どうやれば各段階のコードを得られるかというお話。
.swift
今回は.swift単品が対象。適当に
print("hello, world!")
とか書いておく。
Swift AST
swiftc -dump-ast hello.swift
いきなり長いものが出るが、
print
と ()
があって、括弧の中には "hello, world!"
がある……
というのがちゃんと読める。
SIL
swiftc -emit-silgen hello.swift > hello.sil
swiftc -emit-silgen
は結果を標準出力してくるので適当なファイルに書かせておく。
できたhello.silは
swiftc -parse-sil hello.sil
./hello
といった感じで実行するとこまで進められる。
LLVM IR
swiftc -emit-ir hello.swift > hello.ll
この辺りはまだ人間の目で読める。
LLVM BC
読めない。
swiftc -emit-bc hello.swift > hello.bc
LLVM周りの話
LLVMインストール
Mac(Xcode?どっちだろう)にはこの手のものが最初から入っているらしいが、LLVMをフルで使うには足りないので、今後LLVMで遊ぶ予定がある場合は
brew install llvm
とか
export PATH=$PATH:/usr/local/opt/llvm/bin
とかしておく。
IRからBCへ
↑で llvm-as
というのが使えるようになっているはずなので、そいつでhello.llからhello.bcをつくる。
llvm-as hello.ll
.bcの実行
ちゃんとした.bcなら
lli hello.bc
で実行できるはずなのだが、
LLVM ERROR: Program used external function '_swift_once' which could not be resolved!
と怒られてしまう。多分なんか方法あるんだろうけど面倒くさいので省略。
Native asm
読める。
swiftc -emit-asm hello.swift > hello.s
LLVM BCからアセンブリへ
llc hello.bc
でhello.sが増える。↑とはちょっと違うけどだいたい似たようなことが書いてあるような気がする。
Native binary
できあがり
swiftc hello.swift
./hello
hello.sをgccに渡したらlswiftCoreがないって言われた(lswiftCore.dylibのことかな)。