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

Swift Optimizing at Compiler World

Swift Optimizing at Compiler World

@NSSpain 2020 Remote Edition

freddi(Yuki Aki)

November 20, 2020
Tweet

More Decks by freddi(Yuki Aki)

Other Decks in Programming

Transcript

  1. Swift Optimizing at Compiler World
    NSSpain 2020: Remote Edition, November 20th 2020
    Yuki Aki from LINE Fukuoka

    View Slide

  2. About Me
    Yuki Aki (freddi)
    iOS Engineer at LINE Fukuoka

    View Slide

  3. Activity & Community
    Developing LINE Creators Studio at LINE Fukuoka

    View Slide

  4. Activity & Community
    Writing Swift for 2 years
    Swift Compiler, XcodeGen etc …
    Contributed to OSS Projects
    As a Speaker at many conferences

    View Slide

  5. About Me
    Yuki Aki (freddi)
    iOS Engineer at LINE Fukuoka

    View Slide

  6. Swift Optimizing at Compiler World

    View Slide

  7. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  8. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  9. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  10. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  11. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  12. Swift Compiler

    View Slide

  13. Why need to learn
    Swift Compiler (Optimizer)?

    View Slide

  14. Why learn about Swift Compiler?
    Increase ways to solve difficult problems in Swift Coding
    Compiling Time, Compiler Bugs, Effective Code …
    Start Contributing to Swift Language
    So Fun

    View Slide

  15. Why learn about Optimizer?
    Easy to learn!
    Helpful to know what happened on Compiling for Product
    And how to try to solve problems related to Optimizer

    View Slide

  16. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language
    SIL Optimizer

    View Slide

  17. Basis of Swift Compiler

    View Slide

  18. Basis of Swift Compiler
    Looks Difficult?
    Don’t be afraid! I’ll describe Complier easily!

    View Slide

  19. Flow of Compiling Swift Code

    App

    View Slide

  20. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Flow of Compiling Swift Code

    View Slide

  21. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Flow of Compiling Swift Code

    View Slide

  22. AST
    Flow of Compiling Swift Code
    Convert to Abstract Syntax Tree by grammar rule of Swift
    Syntax Tree is a format for compiler to understand Code easy
    Parser

    View Slide

  23. AST AST
    (Typed)
    Flow of Compiling Swift Code
    AST to Typed AST
    Checking Type of the Code by generated AST or Type-Error
    Sema

    View Slide

  24. AST
    (Typed)
    SIL
    Flow of Compiling Swift Code
    SILGen
    Typed AST to Swift Intermediate Language(SIL)
    IR (Intermediate Representation)

    View Slide

  25. SIL IR
    (LLVM)
    Flow of Compiling Swift Code
    IRGen
    Swift Intermediate Language Code to LLVM IR
    LLVM is a backend of Swift

    View Slide

  26. IR
    (LLVM)

    App
    Flow of Compiling Swift Code
    Convert to executable, like iOS App, Command Line Tools …
    Other compiler phases like Linker are here (not touch today)

    View Slide

  27. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Flow of Compiling Swift Code

    View Slide

  28. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Flow of Compiling Swift Code

    View Slide

  29. SIL
    SIL is one of topic of talk topic!
    Let’s focus on SIL!

    View Slide

  30. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language
    SIL Optimizer

    View Slide

  31. Swift Intermediate Language

    View Slide

  32. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Swift Intermediate Language

    View Slide

  33. SIL
    Swift Intermediate Language
    Intermediate Representation(IR) of Swift
    Used for specialized optimization for Swift

    View Slide

  34. SIL
    Swift Intermediate Language
    LLVM IR is also optimized later
    IR
    (LLVM)
    Some effective optimization cannot be run on LLVM IR

    View Slide

  35. Swift Intermediate Language
    Let’s convert this code to SIL!
    print("Hello, World")
    hello.swift

    View Slide

  36. SIL
    Two kinds of SIL

    View Slide

  37. Two kinds of SIL

    View Slide

  38. Two kinds of SIL
    raw
    SIL
    canonical
    SIL

    View Slide

  39. raw
    SIL
    canonical
    SIL
    Two kinds of SIL
    raw SIL is generated by SILGen (from AST)
    canonical SIL is optimized raw SIL by SIL Optimizer

    View Slide

  40. Swift Intermediate Language
    raw
    SIL
    print("Hello, World")
    hello.swift

    View Slide

  41. View Slide

  42. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()

    View Slide

  43. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()

    View Slide

  44. Structure of SIL Code
    SIL Module
    Generated from Swift Source File

    View Slide

  45. Structure of SIL Code
    SIL Module
    Meta information
    (Imported libraries, Function signature, Witness Table …)

    View Slide

  46. Structure of SIL Code
    SIL Module
    SIL Function
    SIL Function
    SIL Function
    Meta information
    (Imported libraries, Function signature, Witness Table …)

    View Slide

  47. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims
    sil_stage raw

    View Slide

  48. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    sil_stage raw
    raw or canonical

    View Slide

  49. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims

    View Slide

  50. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims

    View Slide

  51. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims
    $Builtin.Int

    View Slide

  52. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims
    $Builtin.Int

    View Slide

  53. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims
    $Builtin.Int
    My Builtin Literal talk is avalible on YouTube

    View Slide

  54. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    import Builtin
    import Swift
    import SwiftShims
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {

    View Slide

  55. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()

    View Slide

  56. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()

    View Slide

  57. Structure of SIL Code
    SIL Module
    SIL Function
    SIL Function
    SIL Function
    Meta information
    (imported libraries, vtable, function signature,witness table …)

    View Slide

  58. Structure of SIL Code
    Converted from Swift Function
    SIL Function

    View Slide

  59. sil_stage raw
    import Builtin
    import Swift
    import SwiftShims
    %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5
    (%5, %6) = destructure_tuple %4 : $(Array, Builtin.RawPointer) // users: %24, %21, %7
    %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
    %8 = string_literal utf8 "Hello, World" // user: %13
    %9 = integer_literal $Builtin.Word, 12 // user: %13
    %10 = integer_literal $Builtin.Int1, -1 // user: %13
    %11 = metatype $@thin String.Type // user: %13
    // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    %12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
    %13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
    %14 = init_existential_addr %7 : $*Any, $String // user: %15
    store %13 to [init] %14 : $*String // id: %15
    // function_ref default argument 1 of print(_:separator:terminator:)
    %16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
    %17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
    // function_ref default argument 2 of print(_:separator:terminator:)
    %18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
    %19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
    // function_ref print(_:separator:terminator:)
    %20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> () // user: %21
    %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    destroy_value %19 : $String // id: %22
    destroy_value %17 : $String // id: %23
    destroy_value %5 : $Array // id: %24
    %25 = integer_literal $Builtin.Int32, 0 // user: %26
    %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27
    // _allocateUninitializedArray(_:)
    sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
    // String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
    sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
    // default argument 1 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String
    // default argument 2 of print(_:separator:terminator:)
    sil hidden_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String
    // print(_:separator:terminator:)
    sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array, @guaranteed String, @guaranteed String) -> ()
    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'

    View Slide


  60. // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'

    View Slide

  61. “main” Function of Swift
    print("Hello, World")
    hello.swift
    Body code is surrounded by Main function
    Main function works as entry point like other languages

    View Slide

  62. Structure of SIL Code
    SIL Function
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block

    View Slide

  63. Structure of SIL Code
    SIL Function
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block
    SIL Basic Block

    View Slide

  64. Structure of SIL Code
    SIL Basic Block
    Basic Block is kind of Scope in Swift Function
    Increased as Conditional Branches of program

    View Slide


  65. // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'

    View Slide


  66. // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    bb represents Basic Block

    View Slide


  67. // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'
    Basic Block is increased as Conditional Branches
    bb1 …:

    bb represents Basic Block
    if, while, switch, … in Swift

    View Slide

  68. Structure of SIL Code
    SIL Basic Block
    SIL Instruction
    SIL Instruction
    SIL Instruction
    SIL Instruction
    SIL Instruction

    View Slide

  69. Structure of SIL Code
    Converted from Swift Code
    SIL Instruction

    View Slide

  70. %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF …
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …)

    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'

    View Slide

  71. %2 = integer_literal $Builtin.Word, 1 // user: %4
    // function_ref _allocateUninitializedArray(_:)
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF …
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …)

    // main
    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 {
    bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>):
    return %26 : $Int32 // id: %27
    } // end sil function 'main'

    View Slide

  72. Structure of SIL Code
    Converted from Swift Code
    SIL Instruction
    Conformed to Static Single Assignment format

    View Slide

  73. Static Single Assignment (SSA)
    Each variable cannot be assigned value twice
    %2 = integer_literal $Builtin.Word, 1
    %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF …
    %4 = apply %3(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …)
    A left value starts from % is variable
    Instruction with assigning is %n = instruction

    View Slide

  74. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B

    View Slide

  75. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B
    Removing Dead(not used) Code of Function

    View Slide

  76. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B ← return and %7 should be marked as Live (used) Code

    View Slide

  77. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B ← return and %7 should be marked as Live (used) Code

    View Slide

  78. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B ← return and %7 should be marked as Live (used) Code
    ← %5 and %6 should be marked as Live (used) Code

    View Slide

  79. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B ← return and %7 should be marked as Live (used) Code
    ← %5 and %6 should be marked as Live (used) Code

    View Slide

  80. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B ← return and %7 should be marked as Live (used) Code
    ← %5 and %6 should be marked as Live (used) Code
    ← Marked as Dead Code because referred by return

    View Slide

  81. Why converting SSA?
    Very easy to track how code is using each variable
    /// Body of SIL Function
    // A: integer variable
    %2 = integer_literal
    %3 = function_ref Int.init(:)
    %4 = apply %3(%2)
    // B: integer variable
    %5 = integer_literal
    %6 = function_ref Int.init(:)
    %7 = apply %5(%6)
    return %7 // return B
    Searching for variable proceeds by Unidirectional flow

    View Slide

  82. Dead Code Elimination
    Constant Propagation
    Why converting SSA?
    Very easy to track how code is using each variable

    View Slide

  83. Structure of SIL Code
    Converted from Swift Code
    SIL Instruction
    The Code Style is conformed to SSA
    Reference: docs/SIL.rst in apple/swift

    View Slide

  84. Recap of SIL
    raw SIL and canonical SIL
    SIL consists of Module, Function, Basic Block and Instruction
    SIL is conformed to Single Static Assignment Format

    View Slide

  85. Agenda
    Why need to learn Swift Compiler (Optimizer)?
    Basis of Swift Compiler
    Swift Intermediate Language (SIL)
    SIL Optimizer

    View Slide

  86. SIL Optimizer

    View Slide

  87. How SIL Optimizer works

    View Slide

  88. raw to canonical
    raw
    SIL
    canonical
    SIL

    View Slide

  89. raw to canonical
    raw
    SIL
    canonical
    SIL
    SIL Code Optimization

    View Slide

  90. raw to canonical
    raw
    SIL
    canonical
    SIL
    SIL Optimizer
    SIL Code Optimization

    View Slide

  91. Role of SIL Optimizer
    SIL Optimizer has two important roles on Compiler Phase
    Optimization SIL Code
    Diagnostic SIL Code

    View Slide

  92. Role of SIL Optimizer
    SIL Optimizer has two important roles on Compiler Phase
    SIL Code
    Diagnostic SIL Code
    Optimization

    View Slide

  93. by SIL Optimizer
    Optimization specialized for Swift Language
    Optimization
    Generic Specialization
    Witness and VTable Devirtualization etc

    View Slide

  94. Role of SIL Optimizer
    SIL Optimizer has two important roles on Compiler Phase
    SIL Code
    SIL Code
    Diagnostic
    Optimization

    View Slide

  95. by Compiler
    Each phase of Compiler diagnoses your Swift Code
    Checking Grammar on Parser Phase (to AST)
    Checking Type on Sema Phase (to typed AST)
    ??? on SIL Optimizer Phase (to canonical SIL)
    Compiler will show error if diagnostic fails
    Diagnostic

    View Slide

  96. func wrongReturnType() -> String {
    return 2020
    }
    wrong-type.swift
    by Compiler
    Diagnostic

    View Slide

  97. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Diagnostic of Type Check

    View Slide

  98. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    Diagnostic of Type Check
    OK
    NG
    error:
    cannot convert return expression of type 'Int' to return type 'String'

    View Slide

  99. func wrongReturnType() -> String {
    return 2020
    }
    wrong-type.swift
    Diagnostic of return

    View Slide

  100. func wrongReturnType() -> String {
    }
    wrong-type.swift
    Diagnostic of return

    View Slide

  101. SIL
    AST AST
    (Typed)
    IR
    (LLVM)

    App
    OK OK OK
    Diagnostic of return

    View Slide

  102. raw
    SIL
    canonical
    SIL
    Diagnostic in SIL Optimizer
    NG
    error: missing return in a function expected to return 'String'
    SIL Code Optimization

    View Slide

  103. Diagnostic of return
    func wrongReturnType() -> String {
    }
    no-return.swift
    … // some code
    fatalError()

    View Slide

  104. AST AST
    (Typed)
    SIL IR
    (LLVM)

    App
    OK
    Diagnostic of return
    OK OK OK OK
    No error by fatalError

    View Slide

  105. Examples
    Diagnostic of Grammar by Parser
    Diagnostic of validation no-return by SIL Optimizer
    Diagnostic
    Diagnostic of Overflow by SIL Optimizer
    Diagnostic of Type (of return) by Sema
    etc

    View Slide

  106. Role of SIL Optimizer
    SIL Optimizer has two important role on Compiler Phase
    Optimizing SIL Code
    SIL Code
    Diagnostic
    Guaranteeing safety as other roles of each phase

    View Slide

  107. raw SIL
    raw
    SIL
    canonical
    SIL
    SIL Optimizer
    Optimizing

    View Slide

  108. raw SIL
    raw
    SIL
    canonical
    SIL
    Optimizing
    Many Passes optimize your code in order
    Pass Pass
    Pass Pass
    Each Pass has role for optimization and diagnostic

    View Slide

  109. Example of Pass in SIL Optimizer
    Dead Code Elimination
    Constant Propagation
    Memory Promotion
    Other Diagnostic etc

    View Slide

  110. Pass Pipeline has information that which Pass must be called
    Pass Pipeline
    Pass Pass
    Pass Pass
    SIL Optimizer calls only registered Pass on Pipeline
    is Pass Pipeline

    View Slide

  111. How Pass PipeLine is built
    Pass Pass
    Pass Pass
    Pipeline is built from optimization level of Compiler
    -Onone : Minimum optimization for debugging situation
    -O : Optimization for production code
    -Osize : Optimization for reducing size than performance

    View Slide

  112. Which Pass is called or not?
    lib/SILOptimizer/PassManager/PassPipeline.cpp
    https://github.com/apple/swift

    View Slide

  113. Which Pass is called or not?
    lib/SILOptimizer/PassManager/PassPipeline.cpp
    addMandatoryDiagnosticOptPipeline
    getOnonePassPipeline
    etc

    View Slide

  114. List of Passes
    include/swift/SILOptimizer/PassManager/Passes.def
    https://github.com/apple/swift

    View Slide

  115. Recap of SIL Optimizer
    SIL Optimizer’s roles are Optimization and Diagnostic
    raw SIL is optimized by Passes in SIL Optimizer
    Pipeline has information which Pass must be called
    Pass Pipeline is built by optimization level

    View Slide

  116. SIL Optimizer

    View Slide

  117. More Deeper Dive into SIL Optimizer

    View Slide

  118. Two kinds of Pass
    For SIL Module
    For SIL Function
    Run by each SIL Module
    Run by each SIL Function

    View Slide

  119. Two kinds of Pass
    For SIL Module
    For SIL Function
    Dead Function Elimination
    Global Variable Optimization
    Dead Code Elimination
    Alloc Box to Stack
    etc
    etc

    View Slide

  120. How to know what kind of Pass
    Passes are developed by C++ Class in Compiler Code
    Each Pass inherits two kinds of Bass Class
    SILModuleTransform
    SILFunctionTransform

    View Slide

  121. How to know what kind of Pass
    For SIL Module
    For SIL Function
    Dead Function Elimination
    Global Variable Optimization
    Dead Code Elimination
    Alloc Box to Stack
    etc
    etc

    View Slide

  122. How to know what kind of Pass
    Dead Function Elimination
    class SILDeadFuncElimination : public SILModuleTransform {

    }
    lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

    View Slide

  123. How to know what kind of Pass
    Dead Code Elimination
    class DCE : public SILFunctionTransform {

    }
    lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

    View Slide

  124. Pass’s implementation
    Making Class from SILModule(Function)Transform
    Implementing run() as Entry Point

    View Slide

  125. Reading Pass Code
    For example, let’s read AssumeSingleThreaded Pass
    The smallest Pass in Swift Compiler
    Optimizes program specialized for Single Thread

    View Slide

  126. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    }
    /// Post treatment
    }
    };

    View Slide

  127. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    }
    /// Post treatment
    }
    };

    View Slide

  128. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    }
    /// Post treatment
    }
    };

    View Slide

  129. Reading Pass Code
    Easy to understand if we know structure of SIL Code
    SIL Module
    SIL Function
    SIL Basic Block
    SIL Instruction

    View Slide

  130. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    }
    /// Post treatment
    }
    };

    View Slide

  131. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    /// Post treatment
    }
    };
    for (auto &BB : *getFunction()) {
    }

    View Slide

  132. Reading Pass Code
    getFunction returns current scanning SILFunction
    for (auto &BB : *getFunction()) {
    }

    SILFunction can be treated as SILBasicBlock Collection

    View Slide

  133. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    }
    /// Post treatment
    }
    };
    for (auto &BB : *getFunction()) {
    }

    View Slide

  134. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    /// Post treatment
    }
    };
    for (auto &I : BB) {
    }

    View Slide

  135. Reading Pass Code
    }

    for (auto &I : BB) {
    SILBasicBlock is SILInstruction Collection
    Scanning SILInstruction from top

    View Slide

  136. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    if (auto RCInst = dyn_cast(&I))
    RCInst->setNonAtomic();
    }
    /// Post treatment
    }
    };
    for (auto &I : BB) {
    }

    View Slide

  137. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    if (. )
    RCInst->setNonAtomic();
    }
    /// Post treatment
    }
    };
    for (auto &I : BB) {
    }
    auto RCInst = dyn_cast(&I)

    View Slide

  138. Reading Pass Code
    Checking what kind of SILInstruction by casting
    RefCountingInst is instruction related to ARC
    auto RCInst = dyn_cast(&I)

    View Slide

  139. Reading Pass Code
    If we want to check instruction is return or not
    Check type-cast by ReturnInst
    auto ReturnInst = dyn_cast(&I)

    View Slide

  140. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    if (. )
    RCInst->setNonAtomic();
    }
    /// Post treatment
    }
    };
    for (auto &I : BB) {
    }
    auto RCInst = dyn_cast(&I)

    View Slide

  141. lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
    class AssumeSingleThreaded : public swift::SILFunctionTransform {
    /// The entry point to the transformation.
    void run() override {
    /// Checking option …
    for (auto &BB : *getFunction()) {
    for (auto &I : BB) {
    if (auto RCInst = dyn_cast(&I))
    }
    }
    /// Post treatment
    }
    };
    RCInst->setNonAtomic();

    View Slide

  142. Reading Pass Code
    Setting Reference Count instruction as non Atomic
    RCInst->setNonAtomic();

    View Slide

  143. What AssumeSingleThreaded?
    Scanning SIL Instruction related to Reference Count
    Marking Reference Count Instruction as non Atomic
    Called by each SIL Function

    View Slide

  144. Now, you can read
    Swift Compiler Code!

    View Slide

  145. Using docs/SIL.rst for reference of SIL Instruction
    Understanding C++ and LLVM for more deep dive
    Recap to read SIL Optimizer Code
    Understanding structure of SIL Code

    View Slide

  146. For More your learning Compiler

    View Slide

  147. Build Swift Compiler!
    You can clone from https://github.com/apple/swift
    It requires more than 60 GB ⚠ to build

    View Slide

  148. SIL Optimizer may have bugs which not tracked
    There is many chance to contribute!
    Contribute to Swift Compiler!

    View Slide

  149. Talk/Write about Swift Compiler!
    Swift Compiler is difficult topic
    Your talk/article would be helpful for next learner!

    View Slide

  150. Thank you!
    Twitter: _ _ _ freddi _ _ _
    Give me a feed back and question!

    View Slide