Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Activity & Community Developing LINE Creators Studio at LINE Fukuoka

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Swift Optimizing at Compiler World

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Swift Compiler

Slide 13

Slide 13 text

Why need to learn Swift Compiler (Optimizer)?

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Basis of Swift Compiler

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Flow of Compiling Swift Code App

Slide 20

Slide 20 text

AST AST (Typed) SIL IR (LLVM) App Flow of Compiling Swift Code

Slide 21

Slide 21 text

AST AST (Typed) SIL IR (LLVM) App Flow of Compiling Swift Code

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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)

Slide 27

Slide 27 text

AST AST (Typed) SIL IR (LLVM) App Flow of Compiling Swift Code

Slide 28

Slide 28 text

AST AST (Typed) SIL IR (LLVM) App Flow of Compiling Swift Code

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Swift Intermediate Language

Slide 32

Slide 32 text

AST AST (Typed) SIL IR (LLVM) App Swift Intermediate Language

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

SIL Two kinds of SIL

Slide 37

Slide 37 text

Two kinds of SIL

Slide 38

Slide 38 text

Two kinds of SIL raw SIL canonical SIL

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

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) -> ()

Slide 43

Slide 43 text

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) -> ()

Slide 44

Slide 44 text

Structure of SIL Code SIL Module Generated from Swift Source File

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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 {

Slide 55

Slide 55 text

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) -> ()

Slide 56

Slide 56 text

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) -> ()

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

Structure of SIL Code Converted from Swift Function SIL Function

Slide 59

Slide 59 text

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'

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

“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

Slide 62

Slide 62 text

Structure of SIL Code SIL Function SIL Basic Block SIL Basic Block SIL Basic Block SIL Basic Block SIL Basic Block

Slide 63

Slide 63 text

Structure of SIL Code SIL Function SIL Basic Block SIL Basic Block SIL Basic Block SIL Basic Block SIL Basic Block

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

… // 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

Slide 67

Slide 67 text

… // 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

Slide 68

Slide 68 text

Structure of SIL Code SIL Basic Block SIL Instruction SIL Instruction SIL Instruction SIL Instruction SIL Instruction

Slide 69

Slide 69 text

Structure of SIL Code Converted from Swift Code SIL Instruction

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

SIL Optimizer

Slide 87

Slide 87 text

How SIL Optimizer works

Slide 88

Slide 88 text

raw to canonical raw SIL canonical SIL

Slide 89

Slide 89 text

raw to canonical raw SIL canonical SIL SIL Code Optimization

Slide 90

Slide 90 text

raw to canonical raw SIL canonical SIL SIL Optimizer SIL Code Optimization

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

AST AST (Typed) SIL IR (LLVM) App Diagnostic of Type Check

Slide 98

Slide 98 text

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'

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

SIL AST AST (Typed) IR (LLVM) App OK OK OK Diagnostic of return

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

AST AST (Typed) SIL IR (LLVM) App OK Diagnostic of return OK OK OK OK No error by fatalError

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

raw SIL raw SIL canonical SIL SIL Optimizer Optimizing

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

SIL Optimizer

Slide 117

Slide 117 text

More Deeper Dive into SIL Optimizer

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

How to know what kind of Pass Dead Code Elimination class DCE : public SILFunctionTransform { … } lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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 } };

Slide 127

Slide 127 text

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 } };

Slide 128

Slide 128 text

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 } };

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

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 } };

Slide 131

Slide 131 text

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()) { }

Slide 132

Slide 132 text

Reading Pass Code getFunction returns current scanning SILFunction for (auto &BB : *getFunction()) { } … SILFunction can be treated as SILBasicBlock Collection

Slide 133

Slide 133 text

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()) { }

Slide 134

Slide 134 text

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) { }

Slide 135

Slide 135 text

Reading Pass Code } … for (auto &I : BB) { SILBasicBlock is SILInstruction Collection Scanning SILInstruction from top

Slide 136

Slide 136 text

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) { }

Slide 137

Slide 137 text

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)

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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)

Slide 141

Slide 141 text

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();

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

Now, you can read Swift Compiler Code!

Slide 145

Slide 145 text

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

Slide 146

Slide 146 text

For More your learning Compiler

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

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