🏋
Cranelift IRを簡単に実行する
手軽にCranelift IR(.clif
ファイル)を実行する方法が意外とドキュメントで見つからなかったので、備忘録として残しておきます。
cranelift-tools
をインストールする
clif-tool
というコマンドが欲しいので、含まれているcranelift-tools
をインストールします。
cranelift-tools
は crates.io にはないので、git からインストールします。
$ cargo install --git=https://github.com/bytecodealliance/wasmtime.git cranelift-tools
clif を書く
なんでもいいです
add.clif
function %add(i32, i32) -> i32 fast {
block0(v0: i32, v1: i32):
v2 = iadd v0, v1
return v2
}
clif-util 用のコメントを書く
add.clif
function %add(i32, i32) -> i32 fast {
block0(v0: i32, v1: i32):
v2 = iadd v0, v1
return v2
}
;print: %add(1, 2)
;run: %add(1, 2) == 3
行内の;
以降はclif
のコメントです。
print: %add(1, 2)
は%add(1, 2)
の結果を表示するように指示します。
run: %add(1, 2) == 3
は%add(1, 2)
の結果が3
であることをテストします。
実行する
$ clif-util run -v add.clif
%add(1, 2) -> 3
add.clif
1 file
-v
をつけないと clif の文法とかでエラーが出た場合にどこが悪いのかわからないので、つけておきましょう。
;run
の部分はテストに失敗した場合にエラーが表示されます。
cliu-util test
clif-util test
サブコマンドを-v
オプションと一緒に使うと実行時間がでてくるので、簡単なベンチマークとして使えます。
これは filetestをラッパしてるコマンドです。
適当に作ったナイーブなフィボナッチ数列
fib.clif
test run
target x86_64
function %fib(i32) -> i32 fast {
fn0 = %fib(i32) -> i32
block0(v0: i32):
v1 = iconst.i32 2
v3 = icmp ult v0, v1
brif v3, block1, block2
block1:
return v0
block2:
v4 = iconst.i32 1
v5 = isub v0, v1
v6 = isub v0, v4
v7 = call fn0(v5)
v8 = call fn0(v6)
v9 = iadd v7, v8
return v9
}
;print: %fib(42)
実行結果
$ clif-util test -v fib.clif
%fib(42) -> 267914296
1.448 fib.clif
1 tests
実行時間 1.448 秒
ちなみに clang でコンパイルした場合はこんな感じです。
fib.c
#include <stdio.h>
int fib(int x)
{
if (x < 2)
{
return x;
}
else
{
return fib(x - 2) + fib(x - 1);
}
}
int main()
{
printf("%d\n", fib(42));
return 0;
}
$ clang -O3 fib.c
$ time ./a.out
267914296
real 0m0.830s
user 0m0.831s
sys 0m0.001s
Cranelift 思ったより速いですね。
Discussion