SlideShare a Scribd company logo
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Under the Hood
InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
http://www.infoq.com/presentations
/swift-llvm
Presented at QCon London
www.qconlondon.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
 ▸ About This Talk
• Overview
• Where did Swift come from?
• What makes Swift fast?
• Where is Swift going?
• Alex Blewitt @alblue
• NeXT owner and veteran Objective-C programmer
• Author of Swift Essentials http://swiftessentials.org
Based on Swift 1.1,
the public release in
March 2015
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Where did Swift
come from?
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Pre-history
• Story starts in 1983 with Objective-C
• Created as a Smalltalk like runtime on top of C
• NeXT licensed Objective-C in 1988
• NextStep released in 1989 (and NS prefix)
• Apple bought NeXT in 1996
• OSX Server in 1999
• OSX 10.0 Beta in 2000, released in 2001
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Objective-C
• Originally implemented as a pre-processor for C
• Rewrote Objective-C code as C code
• Enhanced and merged into GCC
• Compiler integrated under GPL
• Runtime libraries open source (and GNUStep)
http://www.opensource.apple.com/source/
objc4/objc4-208/runtime/objc.h
/*!
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.!
* objc.h!
* Copyright 1988-1996, NeXT Software, Inc.!
*/!
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Timeline
C
1972
Objective-C
1983
Smalltalk
1972
Objective-C
2.0 2007
C++
1983
C++07
2007
C++11
2011
C++14
2014
LLVM 1.0
2003
Clang 1.0
2009
Swift 1.0
2014
Static dispatch
Dynamic dispatch
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Static and Dynamic?
• Static dispatch (used by C, C++, Swift)
• Function calls are known precisely
• Compiler generates call/callq to direct symbol
• Fastest, and allows for optimisations
• Dynamic dispatch (used by Objective-C, Swift)
• Messages are dispatched through objc_msgSend
• Effectively call(cache["methodName"])
Swift can generate
Objective-C classes
and use runtime
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
objc_msgSend
• Every Objective-C message calls objc_msgSend
• Hand tuned assembly – fast, but still overhead
40
50
60
70
80
90
100
110
Leopard Snow Leopard Lion Mountain Lion Mavericks
107
104
47 47
44
Removal of special-
case GC handling
CPU, registers
(_cmd, self),
energy🔋
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Static Dispatch
a() -> b() -> c()
a b c
Dynamic Dispatch
[a:] -> [b:] -> [c:]
a b c
objc_msgSend objc_msgSend
Optimises
to abc
Cannot be
optimised
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
What makes
Swift fast?
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Memory optimisation
• Contiguous arrays of data vs objects
• NSArray
• Diverse
• Memory fragmentation
• Limited memory load benefits for locality
• Array<…>
• Iteration is more performant over memory
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Optimisations
• Most optimisations rely on inlining
• Instead of a() -> b(), have ab() instead
• Reduces function prologue/epilog (stack/reg spill)
• Reduces branch miss and memory jumps
• May unlock peephole optimisations
• func foo(i:Int) {if i<0 {return}…}
• foo(-1) foo(negative) can be
optimised away completely
Increases code size
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Link Time Optimisation
• LTO performs whole-program optimisation
• Instead of writing out x86 .o files, writes LLVM
• LLVM linker reads all files, optimises
• Can see optimisations where single file cannot
• final methods and data structures can be inlined
• Structs are always final (no subclassing)
• private (same file) internal (same module)
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift and LLVM
• Swift and clang are both built on LLVM
• Originally stood for Low Level Virtual Machine
• Family of tools (compiler, debugger, linker etc.)
• Abstract assembly language
• Intermediate Representation (IR), Bitcode (BC)
• Infinite register RISC typed instruction set
• Call and return convention agnostic
Bad name, wasn't
really VMs
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Example C based IR
• The ubiquitous Hello World program…
#include <stdio.h>
!
int main() {
puts("Hello World")
}
@.str = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00", align 1
!
define i32 @main() #0 {
%1 = call i32 @puts(i8* getelementptr inbounds
([12 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
clang helloWorld.c -emit-llvm -c -S -o -
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
@.str = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00", align 1
!
define i32 @main() #0 {
%1 = call i32 @puts(i8* getelementptr inbounds
([12 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
clang helloWorld.c -emit-assembly -S -o -
_main
pushq %rbp
movq %rsp, %rbp
leaq L_.str(%rip), %rdi
callq _puts
xorl %eax, %eax
popq %rbp
retq
.section __TEXT
L_.str: ## was @.str
.asciz "Hello World"
stack management
rdi = &L_.str
puts(rdi)
eax = 0
return(eax)
L_.str = "Hello World"
main function
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Advantages of IR
• LLVM IR can still be understood when compiled
• Allows for more accurate transformations
• Inlining across method/function calls
• Elimination of unused code paths
• Optimisation phases that are language agnostic
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Example Swift based IR
• The ubiquitous Hello World program…
println("Hello World")
@0 = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00"
!
define i32 @main(i32, i8**) {
…
call void @_TFSs7printlnU__FQ_T_(⤦
%swift.opaque* %5, ⤦
%swift.type* getelementptr inbounds ⤦
(%swift.full_type* @_TMdSS, i64 0, i32 1))
ret i32 0
}
swiftc helloWorld.swift -emit-ir —o -
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Name Mangling
• Name Mangling is source → assembly identifiers
• C name mangling: main → _main
• C++ name mangling: main → __Z4mainiPPc
• __Z = C++ name
• 4 = 4 characters following for name (main)
• i = int
• PPc = pointer to pointer to char (i.e. char**)
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Name Mangling
• With the Swift symbol _TFSs7printlnU__FQ_T_
• _T = Swift symbol
• F = function
• Ss = "Swift" (module, as in Swift.println)
• 7println = "println" (function name)
• U__ = single generic type argument, unbound
• F = function
• Q_ = generic argument
• T_ = empty tuple () (return type)
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Name Mangling
• With the Swift symbol _TFSs7printlnU__FQ_T_
• _T = Swift symbol
• F = function
• Ss = "Swift" (module, as in Swift.println)
• 7println = "println" (function name)
• U__ = single generic type argument, unbound
• F = function
• Q_ = generic argument
• T_ = empty tuple () (return type)
$ xcrun swift-demangle _TFSs7printlnU__FQ_T_
_TFSs7printlnU__FQ_T_ ---> Swift.println <A>(A) -> ()
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Intermediate Language
• Similar to IL, but with some Swift specifics
println("Hello World")
sil_stage canonical
!
import Builtin
import Swift
import SwiftShims
!
// top_level_code
sil private @top_level_code : $@thin () -> () {
bb0:
// function_ref Swift.println <A>(A) -> ()
%0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦
$@thin <τ_0_0> (@in τ_0_0) -> () // user: %9
swiftc helloWorld.swift -emit-sil —o -
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift vTables
• Method lookup in Swift is like C++ with vTable
class World { func hello() {…} }
sil_stage canonical
import Builtin; import Swift; import SwiftShims
sil private @top_level_code : $@thin () -> () {
// function_ref Swift.println <A>(A) -> ()
%0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦
$@thin <τ_0_0> (@in τ_0_0) -> () // user: %9
…
sil_vtable World {
#World.hello!1: _TFC4main5World5hellofS0_FT_T_
// main.World.hello (main.World)() -> ()
#World.init!initializer.1: _TFC4main5WorldcfMS0_FT_S0_
// main.World.init (main.World.Type)() -> main.World
}
swiftc helloWorld.swift -emit-sil —o -
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
SwiftObject and ObjC
• Swift objects can also be used in Objective-C
• Swift instance in memory has an isa pointer
• Objective-C can call Swift code with no changes
• Swift classes have @objc to use dynamic dispatch
• Reduces optimisations
• Automatically applied when using ObjC
• Protocols, Superclasses
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Where is Swift going?
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Is Swift swift yet?
• Is Swift as fast as C?
• Wrong question
• Is Swift as fast, or faster than Objective-C?
• Can be as fast for Objective-C interoperability
• Can be faster for data/struct processing
• More optimisation possibilities in future
@alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift
• Being heavily developed – 3 releases in a year
• Provides a transitional mechanism from ObjC
• Existing libraries/frameworks will continue to work
• Can drop down to native calls when necessary
• Used as replacement language in LLDB
• Future of iOS development?
Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Q&A
Watch the video with slide synchronization on
InfoQ.com!
http://www.infoq.com/presentations/swift-
llvm

More Related Content

Swift - Under the Hood

  • 1. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift Under the Hood
  • 2. InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations /swift-llvm
  • 3. Presented at QCon London www.qconlondon.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  • 4. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd  ▸ About This Talk • Overview • Where did Swift come from? • What makes Swift fast? • Where is Swift going? • Alex Blewitt @alblue • NeXT owner and veteran Objective-C programmer • Author of Swift Essentials http://swiftessentials.org Based on Swift 1.1, the public release in March 2015
  • 5. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Where did Swift come from?
  • 6. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Pre-history • Story starts in 1983 with Objective-C • Created as a Smalltalk like runtime on top of C • NeXT licensed Objective-C in 1988 • NextStep released in 1989 (and NS prefix) • Apple bought NeXT in 1996 • OSX Server in 1999 • OSX 10.0 Beta in 2000, released in 2001
  • 7. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Objective-C • Originally implemented as a pre-processor for C • Rewrote Objective-C code as C code • Enhanced and merged into GCC • Compiler integrated under GPL • Runtime libraries open source (and GNUStep) http://www.opensource.apple.com/source/ objc4/objc4-208/runtime/objc.h /*! * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.! * objc.h! * Copyright 1988-1996, NeXT Software, Inc.! */!
  • 8. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Timeline C 1972 Objective-C 1983 Smalltalk 1972 Objective-C 2.0 2007 C++ 1983 C++07 2007 C++11 2011 C++14 2014 LLVM 1.0 2003 Clang 1.0 2009 Swift 1.0 2014 Static dispatch Dynamic dispatch
  • 9. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Static and Dynamic? • Static dispatch (used by C, C++, Swift) • Function calls are known precisely • Compiler generates call/callq to direct symbol • Fastest, and allows for optimisations • Dynamic dispatch (used by Objective-C, Swift) • Messages are dispatched through objc_msgSend • Effectively call(cache["methodName"]) Swift can generate Objective-C classes and use runtime
  • 10. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd objc_msgSend • Every Objective-C message calls objc_msgSend • Hand tuned assembly – fast, but still overhead 40 50 60 70 80 90 100 110 Leopard Snow Leopard Lion Mountain Lion Mavericks 107 104 47 47 44 Removal of special- case GC handling CPU, registers (_cmd, self), energy🔋
  • 11. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Static Dispatch a() -> b() -> c() a b c Dynamic Dispatch [a:] -> [b:] -> [c:] a b c objc_msgSend objc_msgSend Optimises to abc Cannot be optimised
  • 12. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd What makes Swift fast?
  • 13. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Memory optimisation • Contiguous arrays of data vs objects • NSArray • Diverse • Memory fragmentation • Limited memory load benefits for locality • Array<…> • Iteration is more performant over memory
  • 14. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Optimisations • Most optimisations rely on inlining • Instead of a() -> b(), have ab() instead • Reduces function prologue/epilog (stack/reg spill) • Reduces branch miss and memory jumps • May unlock peephole optimisations • func foo(i:Int) {if i<0 {return}…} • foo(-1) foo(negative) can be optimised away completely Increases code size
  • 15. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Link Time Optimisation • LTO performs whole-program optimisation • Instead of writing out x86 .o files, writes LLVM • LLVM linker reads all files, optimises • Can see optimisations where single file cannot • final methods and data structures can be inlined • Structs are always final (no subclassing) • private (same file) internal (same module)
  • 16. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift and LLVM • Swift and clang are both built on LLVM • Originally stood for Low Level Virtual Machine • Family of tools (compiler, debugger, linker etc.) • Abstract assembly language • Intermediate Representation (IR), Bitcode (BC) • Infinite register RISC typed instruction set • Call and return convention agnostic Bad name, wasn't really VMs
  • 17. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Example C based IR • The ubiquitous Hello World program… #include <stdio.h> ! int main() { puts("Hello World") } @.str = private unnamed_addr constant [12 x i8] ⤦ c"Hello World00", align 1 ! define i32 @main() #0 { %1 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0)) ret i32 0 } clang helloWorld.c -emit-llvm -c -S -o -
  • 18. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd @.str = private unnamed_addr constant [12 x i8] ⤦ c"Hello World00", align 1 ! define i32 @main() #0 { %1 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0)) ret i32 0 } clang helloWorld.c -emit-assembly -S -o - _main pushq %rbp movq %rsp, %rbp leaq L_.str(%rip), %rdi callq _puts xorl %eax, %eax popq %rbp retq .section __TEXT L_.str: ## was @.str .asciz "Hello World" stack management rdi = &L_.str puts(rdi) eax = 0 return(eax) L_.str = "Hello World" main function
  • 19. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Advantages of IR • LLVM IR can still be understood when compiled • Allows for more accurate transformations • Inlining across method/function calls • Elimination of unused code paths • Optimisation phases that are language agnostic
  • 20. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Example Swift based IR • The ubiquitous Hello World program… println("Hello World") @0 = private unnamed_addr constant [12 x i8] ⤦ c"Hello World00" ! define i32 @main(i32, i8**) { … call void @_TFSs7printlnU__FQ_T_(⤦ %swift.opaque* %5, ⤦ %swift.type* getelementptr inbounds ⤦ (%swift.full_type* @_TMdSS, i64 0, i32 1)) ret i32 0 } swiftc helloWorld.swift -emit-ir —o -
  • 21. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Name Mangling • Name Mangling is source → assembly identifiers • C name mangling: main → _main • C++ name mangling: main → __Z4mainiPPc • __Z = C++ name • 4 = 4 characters following for name (main) • i = int • PPc = pointer to pointer to char (i.e. char**)
  • 22. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift Name Mangling • With the Swift symbol _TFSs7printlnU__FQ_T_ • _T = Swift symbol • F = function • Ss = "Swift" (module, as in Swift.println) • 7println = "println" (function name) • U__ = single generic type argument, unbound • F = function • Q_ = generic argument • T_ = empty tuple () (return type)
  • 23. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift Name Mangling • With the Swift symbol _TFSs7printlnU__FQ_T_ • _T = Swift symbol • F = function • Ss = "Swift" (module, as in Swift.println) • 7println = "println" (function name) • U__ = single generic type argument, unbound • F = function • Q_ = generic argument • T_ = empty tuple () (return type) $ xcrun swift-demangle _TFSs7printlnU__FQ_T_ _TFSs7printlnU__FQ_T_ ---> Swift.println <A>(A) -> ()
  • 24. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift Intermediate Language • Similar to IL, but with some Swift specifics println("Hello World") sil_stage canonical ! import Builtin import Swift import SwiftShims ! // top_level_code sil private @top_level_code : $@thin () -> () { bb0: // function_ref Swift.println <A>(A) -> () %0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦ $@thin <τ_0_0> (@in τ_0_0) -> () // user: %9 swiftc helloWorld.swift -emit-sil —o -
  • 25. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift vTables • Method lookup in Swift is like C++ with vTable class World { func hello() {…} } sil_stage canonical import Builtin; import Swift; import SwiftShims sil private @top_level_code : $@thin () -> () { // function_ref Swift.println <A>(A) -> () %0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦ $@thin <τ_0_0> (@in τ_0_0) -> () // user: %9 … sil_vtable World { #World.hello!1: _TFC4main5World5hellofS0_FT_T_ // main.World.hello (main.World)() -> () #World.init!initializer.1: _TFC4main5WorldcfMS0_FT_S0_ // main.World.init (main.World.Type)() -> main.World } swiftc helloWorld.swift -emit-sil —o -
  • 26. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd SwiftObject and ObjC • Swift objects can also be used in Objective-C • Swift instance in memory has an isa pointer • Objective-C can call Swift code with no changes • Swift classes have @objc to use dynamic dispatch • Reduces optimisations • Automatically applied when using ObjC • Protocols, Superclasses
  • 27. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Where is Swift going?
  • 28. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Is Swift swift yet? • Is Swift as fast as C? • Wrong question • Is Swift as fast, or faster than Objective-C? • Can be as fast for Objective-C interoperability • Can be faster for data/struct processing • More optimisation possibilities in future
  • 29. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Swift • Being heavily developed – 3 releases in a year • Provides a transitional mechanism from ObjC • Existing libraries/frameworks will continue to work • Can drop down to native calls when necessary • Used as replacement language in LLDB • Future of iOS development?
  • 30. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd Q&A
  • 31. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations/swift- llvm