Slide 1

Slide 1 text

Cookpad Spring Internship 2019 Swi$ίϯύΠϥίʔε 1

Slide 2

Slide 2 text

؀ڥߏஙऴΘͬͯͳ͍ਓ • ! • ͕͔͔࣌ؒΔͷͰߨٛΛฉ͖ͳ͕ΒΠϯετʔϧ͠·͠ΐ͏ • h#ps:/ /github.com/giginet/MinSwi6-workshop/blob/master/ bootstrap.md 2

Slide 3

Slide 3 text

Agenda • 10:00 ~ 10:15 ! ձࣾ঺հ • 10:15 ~ 11:00 " ߨٛ • 11:00 ~ 13:00 # ϫʔΫγϣοϓޕલͷ෦ • 13:00 ~ 14:00 $ ϥϯν • 14:00 ~ 17:00 # ϫʔΫγϣοϓޕޙͷ෦ • 17:00 ~ 18:00 % ੒Ռൃදձ 3

Slide 4

Slide 4 text

୭ @giginet • ϞόΠϧج൫෦ • ๺ւಓവؗࢢग़਎ɹ • ๺ւಓେֶ৘ใՊֶݚڀՊଔ • 2015೥৽ଔೖࣾ • Core Contributor of Carthage/fastlane 4

Slide 5

Slide 5 text

࿩͢͜ͱ • ΦʔϓϯιʔεSwi%ͷݱঢ়ͱߏ੒ • LLVMೖ໳ • LLVM IRೖ໳ • MinSwi% Workshop 5

Slide 6

Slide 6 text

swi$c • Swi%ίϯύΠϥ • Φʔϓϯιʔε h"ps:/ /github.com/apple/swi4 6

Slide 7

Slide 7 text

Θ͍Θ͍swi$c 7

Slide 8

Slide 8 text

h"ps:/ /academy.realm.io/jp/posts/tryswi5-jesse-squires-contribu;ng-open-source-swi5/ 8

Slide 9

Slide 9 text

swi$c • ͍͔ͭ͘ͷαϒγεςϜʹΘ͔ΕΔ • શͯΛ೺Ѳ͢Δͷ͸೉͍͠ h"ps:/ /swi).org/compiler-stdlib/#compiler-architecture 9

Slide 10

Slide 10 text

Parser • ࣈ۟ղੳΛߦͬͯASTʹม׵͢Δ • ͜ͷ࣌఺Ͱ͸ҙຯղੳ͸ߦ͍ͬͯͳ͍ɻܕ৘ใ΋ͳ͍ • h&ps:/ /github.com/apple/swi8/tree/master/lib/Parse 10

Slide 11

Slide 11 text

Sema • ҙຯղੳ(Seman$c Analysis) • ܕਪ࿦ͳͲΛߦ͍ɺܕ৘ใ෇͖ͷASTʹม׵͢Δ • h1ps:/ /github.com/apple/swi>/tree/master/lib/Sema 11

Slide 12

Slide 12 text

SIL • Swi% Intermediate Language • SIL is an SSA-form IR with high-level seman;c informa;on designed to implement the Swi% programming language • Swi%ίϯύΠϥ͕ੜ੒͢Δதؒݴޠ • h>ps:/ /github.com/apple/swi%/blob/master/docs/SIL.rst 12

Slide 13

Slide 13 text

IRGen • SILΛLLVM IRʹม׵͢Δ • ͋ͱ͸LLVMόοΫΤϯυʹΑͬͯॲཧ͞ΕΔ 13

Slide 14

Slide 14 text

LLVMʁ 14

Slide 15

Slide 15 text

LLVMͱ͸ • ίϯύΠϥج൫ • ݱࡏͷίϯύΠϥ͸શͯΛ࣮૷͢Δʹ͸ෳࡶ͗͢ΔͷͰɺػցޠͷੜ੒΍࠷దԽͳͲΛڞ௨Խͯ͠࡞ΕΔΑ͏ʹͨ͠ ࢓૊Έ • ଟ͘ͷݴޠͷίϯύΠϥ͕LLVM IRΛੜ੒͢ΔLLVM Frontendͱ࣮ͯ͠૷͞Ε͍ͯΔ 15

Slide 16

Slide 16 text

͖ͭͶ͞ΜͰ΋Θ͔ΔLLVM P8ΑΓ 16

Slide 17

Slide 17 text

LLVM frontend • ιʔείʔυΛߏจղੳͯ͠LLVM IRΛੜ੒͢Δ΋ͷ • swi+cͰ͸IRGen·Ͱ͕͜͜ʹ૬౰ 17

Slide 18

Slide 18 text

LLVM IR • LLVM Intermediate Representa2on • ͲͷݴޠͰ͋ͬͯ΋LLVM IRʹม׵͢Δ͜ͱͰLLVMͷج൫ʹ৐ ΕΔ 18

Slide 19

Slide 19 text

#include int main(void) { printf("Hello World"); return 0; } $ clang -S -emit-llvm hello.c 19

Slide 20

Slide 20 text

; ModuleID = 'hello.c' source_filename = "hello.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.14.0" @.str = private unnamed_addr constant [12 x i8] c"Hello World\00", align 1 ; Function Attrs: noinline nounwind optnone ssp uwtable define i32 @main() #0 { %1 = alloca i32, align 4 store i32 0, i32* %1, align 4 %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"Apple LLVM version 10.0.0 (clang-1000.11.45.5)"} 20

Slide 21

Slide 21 text

; ModuleID = 'hello.c' source_filename = "hello.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.14.0" @.str = private unnamed_addr constant [12 x i8] c"Hello World\00", align 1 ; Function Attrs: noinline nounwind optnone ssp uwtable define i32 @main() #0 { %1 = alloca i32, align 4 store i32 0, i32* %1, align 4 %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"Apple LLVM version 10.0.0 (clang-1000.11.45.5)"} 20

Slide 22

Slide 22 text

Pass • LLVM IRʹԿΒ͔ͷॲཧΛߦ͏΋ͷ • ࠷దԽͳͲ 21

Slide 23

Slide 23 text

22

Slide 24

Slide 24 text

LLVM backend • LLVM IRΛॲཧͯ͠ग़ྗ͢Δ΍ͭ • ΞηϯϒϦ • ࣮ߦΦϒδΣΫτ • JITίϯύΠϧͰͷ࣮ߦ • ଞͷݴޠͷίʔυੜ੒ • ͱͯ΋೉͍͠ 23

Slide 25

Slide 25 text

LLVMΛษڧ͢Δ • LLVM Tutorial(Kaleidoscope) • h7ps:/ /llvm.org/docs/tutorial/index.html • h7ps:/ /github.com/sonsongithub/llvm-tutorial • ͖ͭͶ͞ΜͰ΋Θ͔ΔLLVM • LLVM Cookbook 24

Slide 26

Slide 26 text

LLVM IRೖ໳ 25

Slide 27

Slide 27 text

LLVM IR define i32 @main() { ret i32 42 } 26

Slide 28

Slide 28 text

int main(void) { return 42; } $ clang -S -emit-llvm hello.c 27

Slide 29

Slide 29 text

int main(void) { int a = 10; int b = 20; return a + b; } 28

Slide 30

Slide 30 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 31

Slide 31 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 32

Slide 32 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 33

Slide 33 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 34

Slide 34 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 35

Slide 35 text

define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 10, i32* %2, align 4 store i32 20, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 ret i32 %6 } 29

Slide 36

Slide 36 text

SSA(੩త୯Ұ୅ೖࣜ) • ֤ม਺͕1౓͔͠มߋ͞Εͳ͍͜ͱΛอূͨ͠ॻࣜ • ͜ΕͩͱҰ൪্ͷ୅ೖ͕ҙຯΛ੒͞ͳ͍͜ͱΛύοͱ൑ఆͰ͖ ͳ͍ y := 1 y := 2 x := y 30

Slide 37

Slide 37 text

SSA(੩త୯Ұ୅ೖࣜ) • ࠶୅ೖ͢Δͱ͖ʹผ໊Λ෇͚ͯόʔδϣχϯά • ͋ͱ͔Βy1͕ࢀর͞Εͳ͍ͷͰɺ࠷ॳͷ୅ೖ͕ແҙຯͳ͜ͱ͕ ൑ఆ͠΍͍͢ y1 := 1 y2 := 2 x1 := y2 31

Slide 38

Slide 38 text

LLVM IRͷಛ௃ • 1ͭͷIR͔Β͞·͟·ͳCPU޲͚ͷ੒Ռ෺Λੜ੒Ͱ͖Δ • ΞʔΩςΫνϟͷҧ͍Λҙࣝ͢Δඞཁ͕ݮΔ • ࠷దԽͷ࢓૊Έ͕͋Δ 32

Slide 39

Slide 39 text

LLVM IRͷ࠷దԽ • 10 + 20 = 30͸ίϯύΠϧ࣌ʹܭࢉՄೳ • ࠷దԽΦϓγϣϯ -O3 int main(void) { int a = 10; int b = 20; return a + b; } $ clang -S -O3 -emit-llvm ssa.c -o ssa03.ll 33

Slide 40

Slide 40 text

define i32 @main() local_unnamed_addr #0 { ret i32 30 } 34

Slide 41

Slide 41 text

func main() -> Int { let a = 10 let b = 20 return a + b } $ swiftc -emit-ir hello.swift > hello2.ll 35

Slide 42

Slide 42 text

; ModuleID = '-' source_filename = "-" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.14.0" @__swift_reflection_version = linkonce_odr hidden constant i16 3 @llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8 define i32 @main(i32, i8**) #0 { entry: %2 = bitcast i8** %1 to i8* ret i32 0 } define hidden swiftcc i64 @"$S3ssa4mainSiyF"() #0 { entry: ret i64 30 } attributes #0 = { "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" } !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7} !llvm.linker.options = !{!8, !9, !10} !llvm.asan.globals = !{!11} !0 = !{i32 1, !"Objective-C Version", i32 2} !1 = !{i32 1, !"Objective-C Image Info Version", i32 0} !2 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} !3 = !{i32 4, !"Objective-C Garbage Collection", i32 1536} !4 = !{i32 1, !"Objective-C Class Properties", i32 64} !5 = !{i32 1, !"wchar_size", i32 4} !6 = !{i32 7, !"PIC Level", i32 2} !7 = !{i32 1, !"Swift Version", i32 6} !8 = !{!"-lswiftSwiftOnoneSupport"} !9 = !{!"-lswiftCore"} !10 = !{!"-lobjc"} !11 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true} 36

Slide 43

Slide 43 text

Workshop 37

Slide 44

Slide 44 text

Workshop • 1೔ͰSwi&Λ࡞Δͷ͸ෆՄೳʢͦΕ͸ͦ͏ʣ • Swi&Λ࢖ͬͯSwi&͔ΒόΠφϦΛੜ੒͢ΔMinSwi&Λ࡞ͬͯΈ Δ • ཁ͸LLVMϑϩϯτΤϯυΛSwi&Ͱ࣮૷͢Δ 38

Slide 45

Slide 45 text

h"ps:/ /github.com/giginet/ MinSwi5-workshop 39

Slide 46

Slide 46 text

MinSwi& 1. Swi&ͷίʔυΛύʔε 2. Abstract Syntax Treeʹม׵ 3. LLVM IRΛੜ੒ 4. Ϗϧυͯ͠όΠφϦΛੜ੒ 5. Swi&͔ΒϦϯΫ࣮ͯ͠ߦ 40

Slide 47

Slide 47 text

ߏ੒ • MinSwi'Kit • minswi' • MinSwi'KitTests 41

Slide 48

Slide 48 text

MinSwi&Kit • MinSwi'ຊମ • ͜Ε͔Β࣮૷͍ͯ͘͠ 42

Slide 49

Slide 49 text

minswi& • CLIͷλʔήοτ • MinSwi*KitΛ࣮ߦ͢ΔͨΊͷΠϯλʔϑΣΠεΛఏڙ 43

Slide 50

Slide 50 text

MinSwi&KitTests • MinSwi'Kitͷςετέʔε • ࠓճ͸՝୊͕༻ҙ͞Ε͍ͯΔ • ͜ͷςετέʔε͕௨ΔΑ͏ʹ࣮૷͍ͯ͘͠ 44

Slide 51

Slide 51 text

dependencies • apple/Swi*Syntax • llvm-swi*/LLVMSwi* • llvm-swi*/FileCheck 45

Slide 52

Slide 52 text

Swi$Syntax • libSyntaxͷϥούʔ • h,ps:/ /github.com/apple/swi9/tree/master/lib/Syntax • ੩తղੳπʔϧͳͲʹ࢖ΘΕ͍ͯΔ • ύʔαʔͷ࣮૷ʹར༻ 46

Slide 53

Slide 53 text

LLVMSwi' • libLLVMͷϥούʔ • LLVM IRͷੜ੒ʹར༻ • Swi-ͬΆ͍APIͰLLVM IRΛهड़Ͱ͖Δ 47

Slide 54

Slide 54 text

FileCheck • LLVMͷఏڙ͢ΔFileCheckͷϥούʔ • IRੜ੒ͷςετέʔεهड़ʹར༻ • ՝୊தʹग़ͯ͘Δ 48

Slide 55

Slide 55 text

Swi$PM • ϥΠϒϥϦ΍λʔήοτΛSwi%PM(Swi% Package Manager)Ͱ ؅ཧ • XcodeϓϩδΣΫτ΋Swi%PM͔Βੜ੒ 49

Slide 56

Slide 56 text

// swift-tools-version:4.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "MinSwift", products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. .library( name: "MinSwiftKit", targets: ["MinSwiftKit"]) ], dependencies: [ .package(url: "https://github.com/apple/swift-syntax.git", .exact("0.40200.0")), .package(url: "https://github.com/llvm-swift/LLVMSwift.git", from: "0.4.0"), .package(url: "https://github.com/llvm-swift/FileCheck.git", from: "0.0.3") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target(name: "minswift", dependencies: ["MinSwiftKit"]), .target( name: "MinSwiftKit", dependencies: ["SwiftSyntax", "LLVM"]), .testTarget( name: "MinSwiftKitTests", dependencies: ["MinSwiftKit", "FileCheck"]) ] ) 50

Slide 57

Slide 57 text

$ swift package generate-xcodeproj --xcconfig-overrides Settings.xcconfig 51

Slide 58

Slide 58 text

$ git clone https://github.com/giginet/MinSwift-workshop.git $ cd MinSwift-workshop h"ps:/ /github.com/giginet/MinSwi5-workshop/blob/master/ bootstrap.md 52

Slide 59

Slide 59 text

$ cat ./bootstrap $ ./bootstrap $ open MinSwift.xcodeproj 53

Slide 60

Slide 60 text

• λʔήοτΛMinSwift-Packageʹ͢Δ • Ϣχοτςετͷ࣮ߦ • ⌘ + U 54

Slide 61

Slide 61 text

ϫʔΫγϣοϓͷਐΊํ • ςετέʔε͕௨ΔΑ͏ʹMinSwi'Λ࣮૷͍ͯ͘͠ • MinSwi'KitTests/Prac2ce[1-8].swi' • ղઆ͕͋ΔͷͰಡΉ • handouts/prac2ce[1-8].md 55

Slide 62

Slide 62 text

56

Slide 63

Slide 63 text

Prac%ce 1 ύʔαʔͷ࣮૷جຊฤ • Prac&ce 1Ͱ͸ɺSwi-ͷιʔεΛಡΈऔΔύʔαʔͷجૅΛ࡞Γ ·͢ • Swi-SyntaxΛ࢖ͬͯɺιʔεΛτʔΫϯʹ෼ׂ͢Δํ๏ͱɺ ύʔαʔΛॻ͍͍ͯͨ͘ΊͷϢʔςΟϦςΟΛ࡞Γ·͠ΐ͏ 57

Slide 64

Slide 64 text

58

Slide 65

Slide 65 text

59

Slide 66

Slide 66 text

60

Slide 67

Slide 67 text

61

Slide 68

Slide 68 text

62

Slide 69

Slide 69 text

63

Slide 70

Slide 70 text

Mentors Θ͔Μͳ͔ͬͨΒั·͑ͯฉ͖·͠ΐ͏ 64

Slide 71

Slide 71 text

͔͜͜Β͸ϫʔΫγϣοϓͰ͢ Good Luck 65