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

Cookpad Spring Intern 2019 - Swiftコンパイラ -

giginet
March 28, 2019

Cookpad Spring Intern 2019 - Swiftコンパイラ -

giginet

March 28, 2019
Tweet

More Decks by giginet

Other Decks in Technology

Transcript

  1. 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
  2. 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
  3. ; 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
  4. ; 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
  5. 22

  6. LLVM backend • LLVM IRΛॲཧͯ͠ग़ྗ͢Δ΍ͭ • ΞηϯϒϦ • ࣮ߦΦϒδΣΫτ •

    JITίϯύΠϧͰͷ࣮ߦ • ଞͷݴޠͷίʔυੜ੒ • ͱͯ΋೉͍͠ 23
  7. int main(void) { int a = 10; int b =

    20; return a + b; } 28
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. func main() -> Int { let a = 10 let

    b = 20 return a + b } $ swiftc -emit-ir hello.swift > hello2.ll 35
  16. ; 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
  17. MinSwi& 1. Swi&ͷίʔυΛύʔε 2. Abstract Syntax Treeʹม׵ 3. LLVM IRΛੜ੒

    4. Ϗϧυͯ͠όΠφϦΛੜ੒ 5. Swi&͔ΒϦϯΫ࣮ͯ͠ߦ 40
  18. // 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
  19. 56

  20. 58

  21. 59

  22. 60

  23. 61

  24. 62

  25. 63