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. Activity & Community Writing Swift for 2 years Swift Compiler,

    XcodeGen etc … Contributed to OSS Projects As a Speaker at many conferences
  2. Agenda Why need to learn Swift Compiler (Optimizer)? Basis of

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

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

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

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

    Swift Compiler Swift Intermediate Language (SIL) SIL Optimizer
  7. 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
  8. 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
  9. Agenda Why need to learn Swift Compiler (Optimizer)? Basis of

    Swift Compiler Swift Intermediate Language SIL Optimizer
  10. 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
  11. AST AST (Typed) Flow of Compiling Swift Code AST to

    Typed AST Checking Type of the Code by generated AST or Type-Error Sema
  12. AST (Typed) SIL Flow of Compiling Swift Code SILGen Typed

    AST to Swift Intermediate Language(SIL) IR (Intermediate Representation)
  13. SIL IR (LLVM) Flow of Compiling Swift Code IRGen Swift

    Intermediate Language Code to LLVM IR LLVM is a backend of Swift
  14. 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)
  15. Agenda Why need to learn Swift Compiler (Optimizer)? Basis of

    Swift Compiler Swift Intermediate Language SIL Optimizer
  16. SIL Swift Intermediate Language LLVM IR is also optimized later

    IR (LLVM) Some effective optimization cannot be run on LLVM IR
  17. 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
  18. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> ()
  19. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> ()
  20. Structure of SIL Code SIL Module SIL Function SIL Function

    SIL Function Meta information (Imported libraries, Function signature, Witness Table …)
  21. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims sil_stage raw
  22. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () sil_stage raw raw or canonical
  23. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims
  24. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims
  25. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims $Builtin.Int
  26. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims $Builtin.Int
  27. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims $Builtin.Int My Builtin Literal talk is avalible on YouTube
  28. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () import Builtin import Swift import SwiftShims sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
  29. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> ()
  30. sil_stage raw import Builtin import Swift import SwiftShims // main

    sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // 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<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> ()
  31. Structure of SIL Code SIL Module SIL Function SIL Function

    SIL Function Meta information (imported libraries, vtable, function signature,witness table …)
  32. sil_stage raw import Builtin import Swift import SwiftShims %2 =

    integer_literal $Builtin.Word, 1 // user: %4 // function_ref _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4 %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %5 (%5, %6) = destructure_tuple %4 : $(Array<Any>, 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<Any>, @guaranteed String, @guaranteed String) -> () // user: %21 %21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () destroy_value %19 : $String // id: %22 destroy_value %17 : $String // id: %23 destroy_value %5 : $Array<Any> // id: %24 %25 = integer_literal $Builtin.Int32, 0 // user: %26 %26 = struct $Int32 (%25 : $Builtin.Int32) // user: %27 // _allocateUninitializedArray<A>(_:) 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<Any>, @guaranteed String, @guaranteed String) -> () // main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): return %26 : $Int32 // id: %27 } // end sil function 'main'
  33. … // main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>)

    -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): return %26 : $Int32 // id: %27 } // end sil function 'main'
  34. “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
  35. Structure of SIL Code SIL Function SIL Basic Block SIL

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

    Basic Block SIL Basic Block SIL Basic Block SIL Basic Block
  37. Structure of SIL Code SIL Basic Block Basic Block is

    kind of Scope in Swift Function Increased as Conditional Branches of program
  38. … // main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>)

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

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

    -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): 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
  41. Structure of SIL Code SIL Basic Block SIL Instruction SIL

    Instruction SIL Instruction SIL Instruction SIL Instruction
  42. %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref

    _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF … %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …) … // main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): return %26 : $Int32 // id: %27 } // end sil function 'main'
  43. %2 = integer_literal $Builtin.Word, 1 // user: %4 // function_ref

    _allocateUninitializedArray<A>(_:) %3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF … %4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …) … // main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): return %26 : $Int32 // id: %27 } // end sil function 'main'
  44. Structure of SIL Code Converted from Swift Code SIL Instruction

    Conformed to Static Single Assignment format
  45. 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<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned …) A left value starts from % is variable Instruction with assigning is %n = instruction
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. Structure of SIL Code Converted from Swift Code SIL Instruction

    The Code Style is conformed to SSA Reference: docs/SIL.rst in apple/swift
  55. 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
  56. Agenda Why need to learn Swift Compiler (Optimizer)? Basis of

    Swift Compiler Swift Intermediate Language (SIL) SIL Optimizer
  57. Role of SIL Optimizer SIL Optimizer has two important roles

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

    on Compiler Phase SIL Code Diagnostic SIL Code Optimization
  59. by SIL Optimizer Optimization specialized for Swift Language Optimization Generic

    Specialization Witness and VTable Devirtualization etc
  60. Role of SIL Optimizer SIL Optimizer has two important roles

    on Compiler Phase SIL Code SIL Code Diagnostic Optimization
  61. 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
  62. 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'
  63. raw SIL canonical SIL Diagnostic in SIL Optimizer NG error:

    missing return in a function expected to return 'String' SIL Code Optimization
  64. AST AST (Typed) SIL IR (LLVM) App OK Diagnostic of

    return OK OK OK OK No error by fatalError
  65. 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
  66. 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
  67. 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
  68. Example of Pass in SIL Optimizer Dead Code Elimination Constant

    Propagation Memory Promotion Other Diagnostic etc
  69. 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
  70. 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
  71. 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
  72. Two kinds of Pass For SIL Module For SIL Function

    Run by each SIL Module Run by each SIL Function
  73. 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
  74. 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
  75. 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
  76. How to know what kind of Pass Dead Function Elimination

    class SILDeadFuncElimination : public SILModuleTransform { … } lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
  77. How to know what kind of Pass Dead Code Elimination

    class DCE : public SILFunctionTransform { … } lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
  78. Reading Pass Code For example, let’s read AssumeSingleThreaded Pass The

    smallest Pass in Swift Compiler Optimizes program specialized for Single Thread
  79. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } } /// Post treatment } };
  80. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } } /// Post treatment } };
  81. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } } /// Post treatment } };
  82. Reading Pass Code Easy to understand if we know structure

    of SIL Code SIL Module SIL Function SIL Basic Block SIL Instruction
  83. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } } /// Post treatment } };
  84. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } /// Post treatment } }; for (auto &BB : *getFunction()) { }
  85. Reading Pass Code getFunction returns current scanning SILFunction for (auto

    &BB : *getFunction()) { } … SILFunction can be treated as SILBasicBlock Collection
  86. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } } /// Post treatment } }; for (auto &BB : *getFunction()) { }
  87. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } /// Post treatment } }; for (auto &I : BB) { }
  88. Reading Pass Code } … for (auto &I : BB)

    { SILBasicBlock is SILInstruction Collection Scanning SILInstruction from top
  89. 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<RefCountingInst>(&I)) RCInst->setNonAtomic(); } /// Post treatment } }; for (auto &I : BB) { }
  90. 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<RefCountingInst>(&I)
  91. Reading Pass Code Checking what kind of SILInstruction by casting

    RefCountingInst is instruction related to ARC auto RCInst = dyn_cast<RefCountingInst>(&I)
  92. Reading Pass Code If we want to check instruction is

    return or not Check type-cast by ReturnInst auto ReturnInst = dyn_cast<ReturnInst>(&I)
  93. 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<RefCountingInst>(&I)
  94. 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<RefCountingInst>(&I)) } } /// Post treatment } }; RCInst->setNonAtomic();
  95. What AssumeSingleThreaded? Scanning SIL Instruction related to Reference Count Marking

    Reference Count Instruction as non Atomic Called by each SIL Function
  96. 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
  97. SIL Optimizer may have bugs which not tracked There is

    many chance to contribute! Contribute to Swift Compiler!
  98. Talk/Write about Swift Compiler! Swift Compiler is difficult topic Your

    talk/article would be helpful for next learner!
  99. Thank you! Twitter: _ _ _ freddi _ _ _

    Give me a feed back and question!