Upgrade to Pro — share decks privately, control downloads, hide ads and more …

hito-ga-oshieru-llvm

Kmotiko
March 22, 2014

 hito-ga-oshieru-llvm

Kmotiko

March 22, 2014
Tweet

Other Decks in Programming

Transcript

  1. 自己紹介  柏木餅子(♂)  サークルMotiPizzaで活動中  「きつねさんでもわかる!LLVM」  達人出版会様&インプレスジャパン様から 

    LLVM本ではフロントエンド側担当  LLVM本の弱い方  金髪幼女の方  お仕事はソフトウェア開発色々  LLVMを使う機会は無いです  外で発表するのは初めてなので。。。 2
  2. アジェンダ  LLVMとは?  コンパイラの処理  LLVMのイメージ  LLVM-IR 

    LLVM-IRの特徴  LLVM-IRの例  Pass  Passの概念  Passの種類  おまけ 3
  3. アジェンダ  LLVMとは?  コンパイラの処理  LLVMのイメージ  LLVM-IR 

    LLVM-IRの特徴  LLVM-IRの例  Pass  Passの概念  Passの種類  おまけ 4
  4. コンパイラの処理 C/C++ X86 Java ARM Haskell PowerPC 中間表現 フロントエンド (解析・変換)

    ミドルエンド (解析・最適化) バックエンド (コード生成) 10
  5. コンパイラの処理 C/C++ X86 Java ARM Haskell PowerPC 中間表現 フロントエンド (解析・変換)

    ミドルエンド (解析・最適化) バックエンド (コード生成) ・中間表現の規定 ・中間表現の生成・解析/最適化 ・中間表現から各種ターゲットのコード生成 ⇒各種モジュールが整理されて再利用できると嬉しいよね 11
  6. LLVMのイメージ C/C++ X86 Java ARM Haskell PowerPC 中間表現 (LLVM-IR) 変換前

    LLVM-IR Pass A Pass B Backend Pass LLVM バックエンド 処理 変換後 LLVM-IR 解析・最適化 Pass=中間表現(LLVM-IR)の解析や 最適化を行うモジュール 12
  7. LLVMとは?  コンパイラ基盤だよ?  中間表現(LLVM-IR)と最適化・コード生成等のモジュール  正しくは、LLVM=Clangとかを含むプロジェクトの総称  どちらを指しているかは文脈による 

    最近人気なようですね?  BSDライクの比較的緩いライセンス  モジュール化されていて再利用しやすい  読みやすい(読める) 16
  8. アジェンダ  LLVMとは?  コンパイラの処理  LLVMのイメージ  LLVM-IR 

    LLVM-IRの特徴  LLVM-IRの例  Pass  Passの概念  Passの種類  おまけ 17
  9. LLVM IRの特徴  LLVM IR=LLVMの中間表現  言語非依存  レジスタマシンがターゲット 

    i32,floatなどの型があります  静的単一代入形式(SSA)  変数への代入は一度だけ  def-useが追いやすい 21
  10. LLVM IRの特徴  LLVM IR=LLVMの中間表現  言語非依存  レジスタマシンがターゲット 

    i32,floatなどの型があります  静的単一代入形式(SSA)  変数への代入は一度だけ  def-useが追いやすい  3種類あるけど全て等価  メモリ上のIR  シリアライズされたビットコード  人間が読めるアセンブリ形式  詳細はLLVMのドキュメントに・・・  LLVM Language Reference Manual 22
  11. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} 24
  12. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module 25
  13. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module Grobal Variable 26
  14. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module Grobal Variable 27 Function
  15. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module Grobal Variable 28 Function BasicBlock
  16. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module Grobal Variable 29 Function BasicBlock Instruction
  17. LLVM IRの例 ; ModuleID = 'HelloWorld.cpp' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:

    0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00", align 1 ; Function Attrs: uwtable define i32 @main() #0 { entry: %retval = alloca i32, align 4 store i32 0, i32* %retval %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { 省略 } attributes #1 = { 省略 } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4 (tags/RELEASE_34/final 204003)"} Module Grobal Variable 30 Function BasicBlock Instruction Metadata
  18. アジェンダ  LLVMとは?  コンパイラの処理  LLVMのイメージ  LLVM-IR 

    LLVM-IRの特徴  LLVM-IRの例  Pass  Passの概念  Passの種類  おまけ 31
  19. Passの種類  以下の基底クラスを目的に応じて継承  ImmutablePass  ModulePass  FunctionPass 

    LoopPass  RegionPass  BasicBlockPass  MachineFunctionPass  どのようなPassがあるかは公式ドキュメントを・・・  LLVM’s Analysis and Transform Passes 33
  20. Passの種類  以下の基底クラスを目的に応じて継承  ImmutablePass  ModulePass  FunctionPass 

    LoopPass  RegionPass  BasicBlockPass  MachineFunctionPass  どのようなPassがあるかは公式ドキュメントを・・・  LLVM’s Analysis and Transform Passes 34 ART内のGPCExpander はFunctionPassを継承
  21. アジェンダ  LLVMとは?  コンパイラの処理  LLVMのイメージ  LLVM-IR 

    LLVM-IRの特徴  LLVM-IRの例  Pass  Passの概念  Passの種類  おまけ 35
  22. おまけ:ARTにおけるLLVM  ARTの処理系も幾つか種類があるらしい  Quick  Portable  SeaIR 

    インタプリタ?  今回はPortableまわりで読んだところを少しだけ  Dexを入力としてコード生成する 40 LLVMが関係してくるのはここ
  23. おまけ:ARTにおけるLLVM  Portableの場合  Dex2Oat::CreateOatFile  art/dex2oat/dex2oat.cc  一番下にmainがあるのでそこから読んでみる 

    CompilerDriver::CompileAll  art/compiler/llvm/compiler_driver.cc  CompilerLLVM::CompileDexFile等を経由しCompilerLLVM::CompileDexMethodへ? 42
  24. おまけ:ARTにおけるLLVM  Portableの場合  Dex2Oat::CreateOatFile  art/dex2oat/dex2oat.cc  一番下にmainがあるのでそこから読んでみる 

    CompilerDriver::CompileAll  art/compiler/llvm/compiler_driver.cc  CompilerLLVM::CompileDexFile等を経由しCompilerLLVM::CompileDexMethodへ?  CompilerLLVM::CompileDexMethod  art/compiler/llvm/compiler_llvm.cc  CompileOneMethod,LLVMCompilationUnit::Materialize 43
  25. おまけ:ARTにおけるLLVM  Portableの場合  Dex2Oat::CreateOatFile  art/dex2oat/dex2oat.cc  一番下にmainがあるのでそこから読んでみる 

    CompilerDriver::CompileAll  art/compiler/llvm/compiler_driver.cc  CompilerLLVM::CompileDexFile等を経由しCompilerLLVM::CompileDexMethodへ?  CompilerLLVM::CompileDexMethod  art/compiler/llvm/compiler_llvm.cc  CompileOneMethod,LLVMCompilationUnit::Materialize  CompileOneMethod  frontend.ccのCompileMethodへ  MIRの最適化とLLVMIRへの変換(PortableじゃなければArm/MIPS/X86CodeGenerator) 44
  26. おまけ:ARTにおけるLLVM  Portableの場合  Dex2Oat::CreateOatFile  art/dex2oat/dex2oat.cc  一番下にmainがあるのでそこから読んでみる 

    CompilerDriver::CompileAll  art/compiler/llvm/compiler_driver.cc  CompilerLLVM::CompileDexFile等を経由しCompilerLLVM::CompileDexMethodへ?  CompilerLLVM::CompileDexMethod  art/compiler/llvm/compiler_llvm.cc  CompileOneMethod,LLVMCompilationUnit::Materialize  CompileOneMethod  frontend.ccのCompileMethodへ  MIRの最適化とLLVMIRへの変換(PortableじゃなければArm/MIPS/X86CodeGenerator)  LLVMCompilationUnit::Materialize  GBCExpanderの適用とPassManagerBuilderを利用してO3最適化  PassManagerはnothingcosmosさんのwikiとエントリがわかりやすいよ! 45
  27. まとめ  LLVMはコンパイラ基盤  コンパイラ基盤=中間表現とその操作セット  Passを用いて解析や最適化  optコマンドで任意のPassを適用可能 

    自分で実装する場合は目的に応じて基底クラスを継承  Android4.4のARTでもLLVMが!  PortableではDex⇒MIR⇒MIR最適化⇒LLVMIR⇒GBCExpander⇒O3最適化⇒コード生成 47