SlideShare a Scribd company logo

llvm入門

1 of 19
Download to read offline
LLVM入門


2013/3/30 光成滋生(@herumi)
x86/x64最適化勉強会5(#x86opti)
目次
 目標
   LLVMで簡単な関数を作ってCから呼び出す
 足し算関数を作ろう
 比較と条件分岐
 メモリアクセス
 ループ
 carryつき整数加算

  注意 : 私はLLVM歴2週間の初心者です
  つまり、私がLLVMに入門した話…



2013/3/30 #x86opti 5        2 /19
LLVM
 プログラミング言語や実行環境に依存しない仮想機械
  をターゲットにした最適化支援コンパイラ基盤全般
   LLVMアセンブラで書かれたプログラムの実行、最適化、タ
    ーゲット環境への変換などの機能がある


 LLVMアセンブラ
   SSA(Static Single Assignment)ベース
     変数の再代入はできない
   型安全
     i32, float, doubleなどの型情報を持つ
   レジスタは任意個
   モジュール(翻訳単位に分かれたプログラム)を合成できる
   http://llvm.org/docs/LangRef.html
2013/3/30 #x86opti 5                    3 /19
ツール
 clang –S –emit-llvm <C/C++ソース>.c
   C/C++からLLVMアセンブラ(以下LLVMと略)を生成


 llc <LLVMアセンブラ>.ll
   LLVMアセンブラからターゲットCPUのアセンブラを生成
   -marchオプションでターゲットCPUを指定
     x86, arm, mips, sparc, etc.
     llc –versionでサポートターゲット一覧表示
     llc –mattr=helpでより詳細な設定一覧表示
 lli <LLVMアセンブラ>.ll
   LLVMアセンブラを仮想マシン上で実行する
 当然リンカや逆アセンブラ、最適化ツールなどもある

2013/3/30 #x86opti 5                 4 /19
足し算
 二つのuint32_t変数を足して返す関数を作る
 define(関数定義)   define i32 @add1(i32 %x, i32     %y) {
                        entry:
     関数名:@なんとか
                          %ret = add i32 %x, %y
     レジスタ名:%なんとか         ret i32 %ret
                        }
 i32(32bitレジスタ)
     符号は特に無い(使う命令で決める)
     i1なら1bitのレジスタ(フラグ)
     i128なら128bitのレジスタ
 entry(ラベル)
   とりあえず一つラベルがいる
 add(加算命令), ret(関数から返る命令)
   各命令にも型情報が必要

2013/3/30 #x86opti 5                                 5 /19
アセンブル(1/3)
 アセンブルして標準出力に出す
  llc add.ll –o – // コメント削除
  add1:
      leal    (%rdi,%rsi), %eax
      ret
   Linuxの64bit環境ではrdiが第一引数, rsiが第二引数
     C/C++の呼び出し規約にしたがって処理される
     lealで eax ← rdi + rsiを実行
     LLVMのaddが単純にx64のaddになるわけではない
   x86用に出力してみる
  llc add.ll –o – -march=x86
  add1:
      movl    4(%esp), %eax ; 一つ目の引数
      addl    8(%esp), %eax ; 二つ目の引数
      ret

2013/3/30 #x86opti 5                    6 /19

Recommended

AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解MITSUNARI Shigeo
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxpsMITSUNARI Shigeo
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 

More Related Content

What's hot

ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方Shigenori Sagawa
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenMITSUNARI Shigeo
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミングNorishige Fukushima
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法MITSUNARI Shigeo
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだGenya Murakami
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~Norishige Fukushima
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話Kinuko Yasuda
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)Akihiko Matuura
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードShigenori Sagawa
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについてkumake
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化yosupo
 

What's hot (20)

Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについて
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
 

Similar to llvm入門

Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Fixstars Corporation
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介MITSUNARI Shigeo
 
Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)ryos36
 
Intel AVX2を使用したailia sdkの最適化
Intel AVX2を使用したailia sdkの最適化Intel AVX2を使用したailia sdkの最適化
Intel AVX2を使用したailia sdkの最適化HitoshiSHINABE1
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。Kazuki Onishi
 
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...Masahiro Sakai
 
あまぁいRcpp生活
あまぁいRcpp生活あまぁいRcpp生活
あまぁいRcpp生活Masaki Tsuda
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 

Similar to llvm入門 (20)

フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
 
Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)
 
Slide
SlideSlide
Slide
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
Boost Tour 1.50.0 All
Boost Tour 1.50.0 AllBoost Tour 1.50.0 All
Boost Tour 1.50.0 All
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
Intel AVX2を使用したailia sdkの最適化
Intel AVX2を使用したailia sdkの最適化Intel AVX2を使用したailia sdkの最適化
Intel AVX2を使用したailia sdkの最適化
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
 
あまぁいRcpp生活
あまぁいRcpp生活あまぁいRcpp生活
あまぁいRcpp生活
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 

More from MITSUNARI Shigeo

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコルMITSUNARI Shigeo
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advancedMITSUNARI Shigeo
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装MITSUNARI Shigeo
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化MITSUNARI Shigeo
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用MITSUNARI Shigeo
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介MITSUNARI Shigeo
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 

More from MITSUNARI Shigeo (20)

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advanced
 
暗認本読書会12
暗認本読書会12暗認本読書会12
暗認本読書会12
 
暗認本読書会11
暗認本読書会11暗認本読書会11
暗認本読書会11
 
暗認本読書会10
暗認本読書会10暗認本読書会10
暗認本読書会10
 
暗認本読書会9
暗認本読書会9暗認本読書会9
暗認本読書会9
 
暗認本読書会8
暗認本読書会8暗認本読書会8
暗認本読書会8
 
暗認本読書会7
暗認本読書会7暗認本読書会7
暗認本読書会7
 
暗認本読書会6
暗認本読書会6暗認本読書会6
暗認本読書会6
 
暗認本読書会5
暗認本読書会5暗認本読書会5
暗認本読書会5
 
暗認本読書会4
暗認本読書会4暗認本読書会4
暗認本読書会4
 
私とOSSの25年
私とOSSの25年私とOSSの25年
私とOSSの25年
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
 
楕円曲線と暗号
楕円曲線と暗号楕円曲線と暗号
楕円曲線と暗号
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
ゆるバグ
ゆるバグゆるバグ
ゆるバグ
 

Recently uploaded

AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。
AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。
AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。iPride Co., Ltd.
 
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)Kanta Sasaki
 
解説: Token Extensions - Solana Developer Hub Online #SolDevHub
解説: Token Extensions - Solana Developer Hub Online #SolDevHub解説: Token Extensions - Solana Developer Hub Online #SolDevHub
解説: Token Extensions - Solana Developer Hub Online #SolDevHubK Kinzal
 
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdf
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdfHarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdf
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdfMatsushita Laboratory
 
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdfAyachika Kitazaki
 
scikit-learn以外の分類器でpipelineを作ってみた! いずみん
scikit-learn以外の分類器でpipelineを作ってみた! いずみんscikit-learn以外の分類器でpipelineを作ってみた! いずみん
scikit-learn以外の分類器でpipelineを作ってみた! いずみんtoshinori622
 

Recently uploaded (6)

AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。
AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。
AWS (Amazon Web Services) を勉強してみる おさらい 2024/02/16の勉強会で発表されたものです。
 
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)
オリジナルNFTを発行するブロックチェーン開発ハンズオン(NFTの発行に必要なツールから実装まで)
 
解説: Token Extensions - Solana Developer Hub Online #SolDevHub
解説: Token Extensions - Solana Developer Hub Online #SolDevHub解説: Token Extensions - Solana Developer Hub Online #SolDevHub
解説: Token Extensions - Solana Developer Hub Online #SolDevHub
 
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdf
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdfHarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdf
HarukiShinkawa_果樹農家が期待する行動への変容を促す仕掛け設計のための収穫作業体験者の行動観察とモデル化_仕掛学2024.pdf
 
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf
20240222_Neko_IoTLT_vol9_kitazaki_v1.pdf
 
scikit-learn以外の分類器でpipelineを作ってみた! いずみん
scikit-learn以外の分類器でpipelineを作ってみた! いずみんscikit-learn以外の分類器でpipelineを作ってみた! いずみん
scikit-learn以外の分類器でpipelineを作ってみた! いずみん
 

llvm入門

  • 2. 目次  目標  LLVMで簡単な関数を作ってCから呼び出す  足し算関数を作ろう  比較と条件分岐  メモリアクセス  ループ  carryつき整数加算 注意 : 私はLLVM歴2週間の初心者です つまり、私がLLVMに入門した話… 2013/3/30 #x86opti 5 2 /19
  • 3. LLVM  プログラミング言語や実行環境に依存しない仮想機械 をターゲットにした最適化支援コンパイラ基盤全般  LLVMアセンブラで書かれたプログラムの実行、最適化、タ ーゲット環境への変換などの機能がある  LLVMアセンブラ  SSA(Static Single Assignment)ベース 変数の再代入はできない  型安全 i32, float, doubleなどの型情報を持つ  レジスタは任意個  モジュール(翻訳単位に分かれたプログラム)を合成できる  http://llvm.org/docs/LangRef.html 2013/3/30 #x86opti 5 3 /19
  • 4. ツール  clang –S –emit-llvm <C/C++ソース>.c  C/C++からLLVMアセンブラ(以下LLVMと略)を生成  llc <LLVMアセンブラ>.ll  LLVMアセンブラからターゲットCPUのアセンブラを生成  -marchオプションでターゲットCPUを指定 x86, arm, mips, sparc, etc. llc –versionでサポートターゲット一覧表示 llc –mattr=helpでより詳細な設定一覧表示  lli <LLVMアセンブラ>.ll  LLVMアセンブラを仮想マシン上で実行する  当然リンカや逆アセンブラ、最適化ツールなどもある 2013/3/30 #x86opti 5 4 /19
  • 5. 足し算  二つのuint32_t変数を足して返す関数を作る  define(関数定義) define i32 @add1(i32 %x, i32 %y) { entry: 関数名:@なんとか %ret = add i32 %x, %y レジスタ名:%なんとか ret i32 %ret }  i32(32bitレジスタ) 符号は特に無い(使う命令で決める) i1なら1bitのレジスタ(フラグ) i128なら128bitのレジスタ  entry(ラベル)  とりあえず一つラベルがいる  add(加算命令), ret(関数から返る命令)  各命令にも型情報が必要 2013/3/30 #x86opti 5 5 /19
  • 6. アセンブル(1/3)  アセンブルして標準出力に出す llc add.ll –o – // コメント削除 add1: leal (%rdi,%rsi), %eax ret  Linuxの64bit環境ではrdiが第一引数, rsiが第二引数 C/C++の呼び出し規約にしたがって処理される lealで eax ← rdi + rsiを実行 LLVMのaddが単純にx64のaddになるわけではない  x86用に出力してみる llc add.ll –o – -march=x86 add1: movl 4(%esp), %eax ; 一つ目の引数 addl 8(%esp), %eax ; 二つ目の引数 ret 2013/3/30 #x86opti 5 6 /19
  • 7. アセンブル(2/3)  Intel形式で出してみる llc add.ll –o – -march=x86 -x86-asm-syntax=intel add1: mov EAX, DWORD PTR [ESP + 4] add EAX, DWORD PTR [ESP + 8] ret  arm用に出力 llc add.ll –o – -march=arm add1: add r0, r0, r1 mov pc, lr  二項演算としては他にsub, mul, udiv(符号なし), sdiv(符号あり), urem, srem, fadd(浮動小数)など 2013/3/30 #x86opti 5 7 /19
  • 8. 比較と分岐(1/3)  二つの値の大きい方 define i32 @my_max(i32 %x, i32 %y) {  比較命令はicmp entry: %r = icmp ugt i32 %x, %y  icmpの戻り値は br i1 %r, label %gt, label %else 1bitの変数 gt:  ugt → 符号なしgt ret i32 %x else: 他にeq, ne, sltなど ret i32 %y  brでラベルに飛ぶ } elseは予約語ではない  なんでもいい my_max: cmpl %esi, %edi jbe .LBB4_2 movl %edi, %eax ret .LBB4_2: movl %esi, %eax ret 2013/3/30 #x86opti 5 8 /19
  • 9. 比較と分岐(2/3)  絶対値の場合  0より小さいかを見るにはslt(signed less than)  y = sub 0, xで-xを作る nsw(no signed wrap)  制御の合流 define i32 @my_abs(i32 %x) { phi命令を使う entry: %cmp = icmp slt i32 %x, 0 br i1 %cmp, label %lt, label %else my_abs: lt: test edi, edi %neg = sub nsw i32 0, %x jns else br label %exit neg edi else: else: br label %exit mov eax, edi exit: ret %ret = phi i32 [%neg,%lt], [%x,%else] ret i32 %ret } 2013/3/30 #x86opti 5 9 /19
  • 10. 分岐(3/3)  selectを使う  cmpにしたがって値を選択 define i32 @my_max3(i32 %x, i32 %y) { entry: %cmp = icmp ugt i32 %x, %y %cond = select i1 %cmp, i32 %x, i32 %y ret i32 %cond }  x86ではcmov cmp edi, esi cmova esi, edi ; edi > esiならesi ← edi mov eax, esi ret  cmovを使わせないとジャンプ命令が使われる -march=x86 –mattr=-cmov 2013/3/30 #x86opti 5 10 /19
  • 11. メモリアクセス(1/2)  次の関数を作ってみる void add(int *z, const int *x, const int *y) { *z = *x + *y; }  loadとstore命令  alignを指定するとそのalignが仮定される  armでalign 1にするとバイト単位で読むコードに展開された x86/x64では気にしないw define void @add(i32* %z,i32* %x,i32* %y){ entry: %0 = load i32* %x, align 32 add: %1 = load i32* %y, align 32 mov eax,dword [rsi] %ret = add nsw i32 %0, %1 add eax,dword [rdx] store i32 %ret, i32* %z, align 32 mov dword [rdi],eax ret void ret } 2013/3/30 #x86opti 5 11 /19
  • 12. メモリアクセス(2/2)  uint128_tの足し算を作ってみる  i128を使う そんなレジスタが無い環境(たいていの環境)でも使える  i64*をi128*にして値を読む 型変換にはbitcastを使う define void @add(i64* %z,i64* %x,i64* %y){ entry: %0 = bitcast i64* %x to i128* add: %1 = bitcast i64* %y to i128* mov rax, [rsi] %2 = load i128* %0, align 64 mov rcx, [rsi + 8] %3 = load i128* %1, align 64 add rax, [rdx] %4 = add i128 %2, %3 adc rcx, [rdx + 8] %5 = bitcast i64* %z to i128* mov [rdi + 8], rcx store i128 %4, i128* %5, align 64 mov [rdi], rax ret void ret } 2013/3/30 #x86opti 5 12 /19
  • 13. ループ  uint64_tの配列の総和を求める  ループの更新では値の上書きができないのでphiを使う  getelementptr define i64 @sum(i64* %x,i64 %n) { entry: ポインタの計算に使う %n_is_0 = icmp eq i64 %n, 0  ループ変数が減る方向! br i1 %n_is_0, label %exit,label %lp lp: sum: %ip = phi i64 [0,%entry],[%i,%lp] xor eax, eax %retp = phi i64 [0,%entry],[%ret,%lp] test rsi, rsi %xi = getelementptr i64* %x, i64 %ip je exit %v = load i64* %xi lp: %ret = add i64 %retp, %v add rax, qword [rdi] %i = add i64 %ip, 1 add rdi, 8 %i_eq_n = icmp eq i64 %i, %n dec rsi br i1 %i_eq_n,label %exit,label %lp jne lp exit: exit: %r = phi i64 [0,%entry],[%ret,%lp] ret ret i64 %r } 2013/3/30 #x86opti 5 13 /19
  • 14. オーバーフロー(1/2)  多倍長演算のためにcarryを使う  組み込み関数llvm.uadd.with.overflow 使うにはdeclareが必要 戻り値は値とフラグのペア そこから値を取り出すにはextractvalueを使う // *z = x + y, return true if overflow // bool add_over(uint32_t *z, uint32_t x, uint32_t y); declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) define zeroext i1 @add_over(i32* %z, i32 %x, i32 %y) { entry: %0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x,i32 %y) %ret = extractvalue {i32, i1} %0, 0 store i32 %ret, i32* %z %flag = extractvalue {i32, i1} %0, 1 ret i1 %flag } 2013/3/30 #x86opti 5 14 /19
  • 15. オーバーフロー(2/2)  前ページのコードの出力 // *z = x + y, return true if overflow // bool add_over(uint32_t *z, uint32_t x, uint32_t y); add_over: addl %edx, %esi movl %esi, (%rdi) setb %al ret ; al ← set 1 if overflow  小さい幅のレジスタから大きい幅のレジスタへの拡張  zext(符号なし)やsext(符号あり)を使う  困った  carryをaddに加える命令が無い! LLVMのソースコードを見ると内部的にはz=ADDE(x, y, carry) というのがあるようだが、それを呼べない… 2013/3/30 #x86opti 5 15 /19
  • 16. 多倍長整数加算の実装(1/3)  疑似コード addn(uint64_t *pz,const uint64_t *px,const uint64_t *py,size_t n){ bool CF = 0; for (size_t i = 0; i < n; i++) (pz[i],CF)=add_with_carry(px[i], py[i], CF); }  add_with_carryは二つのレジスタとcarryを入力とし て加算の結果とCFのペアを返す define {i64, i1} @add_with_carry(i64 %x, i64 %y, i1 %c) { %vc1 = call {i64, i1}@llvm.uadd.with.overflow.i64(i64 %x,i64 %y) %v1 = extractvalue {i64, i1} %vc1, 0 %c1 = extractvalue {i64, i1} %vc1, 1 %zc = zext i1 %c to i64 %v2 = add i64 %v1, %zc %r1 = insertvalue {i64, i1} undef, i64 %v2, 0 %r2 = insertvalue {i64, i1} %r1, i1 %c1, 1 ret { i64, i1 } %r2 } 2013/3/30 #x86opti 5 16 /19
  • 17. 多倍長整数加算の実装(2/3)  作ったadd_with_carryを使って実装する  ループの一部 %x = load i64* %px_i, align 64 %y = load i64* %py_i, align 64 %rc1 = call {i64, i1} @add_with_carry(i64 %x, i64 %y, i1 %c_p) %r2 = extractvalue {i64, i1} %rc1, 0 %c = extractvalue {i64, i1} %rc1, 1  llc uint.ll –o – .lp: movq (%r15), %rsi movq (%r12), %rdi movzbl %dl, %edx callq add_with_carry ...  あれ、関数呼び出しのまま 2013/3/30 #x86opti 5 17 /19
  • 18. 多倍長整数加算の実装(3/3)  optコマンドを使って最適化する  一度bc(ビットコード)に変換して逆アセンブルしてllcを適用 opt uint.ll -o - -std-compile-opts | llvm-dis –o - | llc –o - .lp: movq (%rsi), %r9 addq (%rdx), %r9 setb %al movzbl %r8b, %r8d andq $1, %r8 addq %r9, %r8 movq %r8, (%rdi)  関数が展開されて埋め込まれた すばらしい!  性能については後半に続く 2013/3/30 #x86opti 5 18 /19
  • 19. 1週間ほど触った雑感  よくできている  ドキュメントが充実している  コマンドエラーが親切  他のCPUの勉強がしやすい  最適化機能はかなり頑張ってる  gccのインラインアセンブラよりずっと使いやすい  プログラムコードがきれい 何をやってるのか追いかけやすい  (私にとって)いまいちなところ  想像していたよりも抽象度が高い LLVMアセンブラと実行環境のアセンブラとの乖離 もちろん利点なのだが、うーん、それを隠蔽するかみたいな 異なるアーキテクチャのCPUを同じコードでやることのしわ寄せ 2013/3/30 #x86opti 5 19 /19