Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
LLVM IR入門
Search
rchaser53
September 05, 2018
Programming
3k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
LLVM IR入門
rchaser53
September 05, 2018
More Decks by rchaser53
See All by rchaser53
pitch loaderについて
rchaser53
1
590
Rustからwasmを生成してみた話
rchaser53
1
820
Base64 VLQ概要
rchaser53
2
1.7k
sourcemap規格概要
rchaser53
1
1.3k
TypeScript+React入門
rchaser53
1
920
Other Decks in Programming
See All in Programming
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
240
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
200
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
180
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
4
500
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
Domain-Driven Transformation
hschwentner
2
2.3k
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
150
APNsからLive Activityを開始する話
yumnumm
0
180
ChromeでローカルLLM
ryu1013
0
160
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
380
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.7k
GraphQL の onError と Nullability のこれから
quramy
0
180
Featured
See All Featured
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
880
Designing for humans not robots
tammielis
254
26k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Test your architecture with Archunit
thirion
2
2.5k
The Curious Case for Waylosing
cassininazir
1
580
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
320
How to train your dragon (web standard)
notwaldorf
96
6.9k
A Modern Web Designer's Workflow
chriscoyier
699
190k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
960
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
30 Presentation Tips
portentint
PRO
1
440
Transcript
Rust でLLVM IR 入門 @rchaser53
誰 ? 誰 ? 職業: 雑用 web エンジニア 名前: 吉澤
峻行 最近はVue とかGo とか
を用いてhello world する話 思いの外hello world で苦戦したので書いた プリントデバッグに必要な知識だから仕方ないね LLVM IR をこれから触る方の足しになれば幸いです
llvm-sys.rs
前座が長いので本題だけ見たい方は 前座が長いので本題だけ見たい方は 14 ページまでジャンプしていただければ… サンプルの loop, if, struct の使用などのサンプルもある( 暇なら)
レポジトリ
LLVM とは ? LLVM とは ? コンパイラ基盤を作るプロジェクト ツールチェーンやコンパイラ、モジュールなどを提供 Rust もLLVM
を使用している
LLVM IR とは ? LLVM IR とは ? LLVM はThree-stage
compiler structure を採用している LLVM IR は各フェイズ間のデータのやりとりに使う
THREE-STAGE COMPILER STRUCTURE THREE-STAGE COMPILER STRUCTURE 複数のフェイズに分けて開発するコンパイラの設計方法 フロントエンド パース, エラーチェック、AST
の生成など ミドルエンド(Optimizer) 最適化、高速化など バックエンド 各プラットフォーム向けの最終産物の生成など IR を用いて各フェイズでデータのやり取りをする
LLVM IR とは ? LLVM IR とは ? こんな感じで各フェイズ間のデータのやりとりに使う 以下でRust
でも見れる cargo rustc -- --emit=llvm-ir
背景 背景 をRust で書いてる じゃあ改良して任意のLLVM IR を出力してみよう Go 言語でつくるインタプリタ 制作途中のものはこれ
もうやった人いる
背景 背景 hello world までの道のりが辛い 資料らしい資料がない では自分で書こう( イマココ)
何を使うの ? 何を使うの ? というLLVM IR を出力するモジュールを使う LLVM はLLVM IR
を出力するモジュールを提供している C とC++ で書かれておりllvm-sys.rs はC のやつをbinding している llvm-sys.rs
LLVM-SYS.RS LLVM-SYS.RS 非常に薄い。ほとんどC のAPI と大差ない ドキュメントやサンプルはほぼない C のAPI に関しても少ない。C++ ならいくらか
困ったら を見に行くのをオススメ ponyc
何が難しい ? 何が難しい ? GetElementPtr(GEP) が難しいと思う まである LLVM IR 上で直にいじるのにも慣れがいる
C のAPI やリファレンスが正直わかりにくいのも原因 公式の専用の解説ページ
GEP(GETELEMENTPTR) とは GEP(GETELEMENTPTR) とは Array やStruct のsubelement のアドレスを取得する つまりArray やStruct
を操作する際に把握が必須 文字列はi8 のArray 。hello world するにはこいつが必要
まずは LLVM IR で出力できるようにする まずは LLVM IR で出力できるようにする 拡張子はll 。test.ll
とか作れば良い LLVM のツールチェーンであるlli を用いて実行すると楽 $ lli test.ll
多分の最小の構成 define i32 @main(i32, i8**) { entry: %local_str = alloca
[12 x i8] store [12 x i8] c"hello world\00", [12 x i8]* %local_str %input_puts = getelementptr [12 x i8], [12 x i8]* %local_str, i32 0 call i32 @printf(i8* %input_puts) ret i32 0 } declare i32 @printf(i8*)
解説1 ; 頭文字 ; 行 ; @xxx 変数 %yyy 変数
型 ; 戻 値 型 関数名(引数 型1, 引数 型2) define i32 @main(i32, i8**) { ; 必須 entry: %local_str = alloca [12 x i8] store [12 x i8] c"hello world\00", [12 x i8]* %local_str %input_puts = getelementptr [12 x i8], [12 x i8]* %local_str, i32 0 call i32 @printf(i8* %input_puts) ret i32 0 }
解説2 define i32 @main(i32, i8**) { entry: ; 確保 ;
[12 x i8] 要素 12 Array %local_str = alloca [12 x i8] ; 確保 値 設定 ; 基本的 型 値 形 記述 ; (例) [12 x i8] c"hello world\00" store [12 x i8] c"hello world\00", [12 x i8]* %local_str ; getelementptr(後述) %input_puts = getelementptr [12 x i8], [12 x i8]* %local_str, i32 0 call i32 @printf(i8* %input_puts) i
解説3 define i32 @main(i32, i8**) { entry: %local_str = alloca
[12 x i8] store [12 x i8] c"hello world\00", [12 x i8]* %local_str %input_puts = getelementptr [12 x i8], [12 x i8]* %local_str, i32 0 ; 関数呼 出 call i32 @printf(i8* %input_puts) ; return ret i32 0 } ; 標準 呼 出 関数 指定 declare i32 @printf(i8*)
LLVM IR の GEP LLVM IR の GEP Array やStruct
のsubelement のアドレスを取得する 引数のパターンはいくらかある llvm-sys.rs から出力できないパターンは割愛 ; 型, 型 変数, index1, index2, ...(以下状況 変更) getelementptr %[12 x i8], %[12 x i8]* %local_str, i32 0, i32 0 型, 型のポインタはわかるけど、index は何? => Array やStruct で考えてみる
LLVM IR の GEP(ARRAY) LLVM IR の GEP(ARRAY) // 感
Array 値 取得 int temp_array[4][4]; temp_array[1][3]; ; 上記 型 宣言 %array_type = type [4 x [4 x i8]] define i8* @test_array_gep(%array_type* %a) { entry: %ret_val = getelementptr %array_type, %array_type* %a, i32 0, i ret i8* %ret_val }
LLVM IR の GEP(STRUCT) LLVM IR の GEP(STRUCT) // 感
Struct 値 取得 struct temp_struct { char a; int b int c[4]; }; temp_struct.b ; 上記 型 宣言 %struct_type = type { i8, i32, [4 x i8] } define i32* @test_stuct_gep(%struct_type* %s) { entry: ; 直接field名 指定 肩 宣言 順番 記述 ; b 2 目 宣言 1 %ret_val = getelementptr %struct_type, %struct_type* %s, i32 0, ret i32* %ret_val }
LLVM IR の GEP LLVM IR の GEP ; 型,
型 変数, index1, index2, ...(以下状況 変更) getelementptr %[12 x i8], %[12 x i8]* %local_str, i32 0, i32 0 常にindex1 が0 にならない…?
LLVM IR の GEP LLVM IR の GEP index1 が0
以外のケース。ないことはないらしい… // C struct munger_struct { int f1; int f2; }; void munge(struct munger_struct *P) { P[0].f1 = P[1].f1 + P[2].f2; } ; LLVM IR void %munge(%struct.munger_struct* %P) { entry: %tmp = getelementptr %struct.munger_struct, %struct.munger_struct %tmp = load i32* %tmp %tmp6 = getelementptr %struct.munger_struct, %struct.munger_struc %tmp7 = load i32* %tmp6 %tmp8 = add i32 %tmp7, %tmp %tmp9 = getelementptr %struct.munger_struct, %struct.munger_struc store i32 %tmp8, i32* %tmp9 ret void }
LLVM-SYS.RS LLVM-SYS.RS 基本はllvm-sys.rs のexample を参考にすれば良い unsafe とか生ポインタとかの話は割愛 LLVMBuildGEP についての説明をする
作成する LLVM IR 作成する LLVM IR %local_str = alloca [12
x i8] store [12 x i8] c"hello world\00", [12 x i8]* %local_str %input_puts = getelementptr [12 x i8], [12 x i8]* %local_str, i32 0,
以下Rust のコード 長いし読みにくいので実際のコードの 貼る リンク先のコードの方がいくらかマシだと思う 次のスライドでgetelementptr だけ説明する リンク pub fn
codegen_string( builder: *mut LLVMBuilder, context: *mut LLVMContext, input_str: &str, ) -> *mut LLVMValue { let length = input_str.len() as u32; unsafe { // %local_str = alloca [12 x i8] let llvm_value = LLVMBuildAlloca( builder, LLVMArrayType(LLVMInt8Type(), length), c_string!("").as_ptr(), ); // i \ i
お作法なので知ってしまえば簡単 お作法なので知ってしまえば簡単 // getelementptr [12 x i8], [12 x i8]*
%local_str, i32 0, i32 0 // i32 0, i32 0 let mut args = [ LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 0, 0), ]; return LLVMBuildGEP( builder, llvm_value, // Array Struct args.as_mut_ptr(), args.len() as u32, // 第3引数 length 引数 指定 意味 CString::new("").unwrap().as_ptr(), // 空文字 場合 勝手 変数名 生成 );
まとめ 1 まとめ 1 GETELEMENTPTR について GETELEMENTPTR について 慣れればそこまで難しいものではないと思う 使えないとほぼ何もできないので勉強できて良かった
C のAPI 使われてなさすぎな気がするのだけど何故?
まとめ 2 まとめ 2 LLVM-SYS.RS で LLVM IR を出力する意味はあるのか ?
LLVM-SYS.RS で LLVM IR を出力する意味はあるのか ? あまりなさそう。Rust でLLVM IR を出力すれば良さそう な気はする しかしLLVM IR について知れたのは良いことなのでは? まぁその時楽しめれば良いよね
参考リンク 公式reference 公式のGetElementPtr の詳細な解説 ponyc のレポジトリ( 困ったら読む) The Architecture of
Open Source Applications のLLVM Three-stage_compiler_structure きつねさんでもわかるLLVM
ご静聴ありがとうございました ! ご静聴ありがとうございました !