Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swiftのリンク時最適化プロジェクト
Search
Yuta Saito
June 18, 2020
Programming
400
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swiftのリンク時最適化プロジェクト
わいわいswiftc #21
https://iosdiscord.connpass.com/event/177407/
Yuta Saito
June 18, 2020
More Decks by Yuta Saito
See All by Yuta Saito
Swift at Scale: Where Performance Really Comes From
kateinoigakukun
0
220
The Evolution of the CRuby Build System
kateinoigakukun
3
1.1k
Running Swift on WebAssembly Platforms
kateinoigakukun
0
240
What you can do with Ruby on WebAssembly
kateinoigakukun
1
2k
RubyGems on ruby.wasm
kateinoigakukun
1
6.1k
Building a Smaller App Binary
kateinoigakukun
2
710
The new linker in Xcode 15
kateinoigakukun
4
4.4k
Optimizing your Swift code
kateinoigakukun
0
2.6k
Ruby & WebAssembly Introduction
kateinoigakukun
0
3.1k
Other Decks in Programming
See All in Programming
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
160
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
120
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
1
1.6k
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
360
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
4
1.1k
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
320
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
220
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
180
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
660
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
240
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
150
Featured
See All Featured
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.8k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
240
The Curse of the Amulet
leimatthew05
2
14k
We Are The Robots
honzajavorek
0
300
Designing for Timeless Needs
cassininazir
1
440
Building the Perfect Custom Keyboard
takai
2
840
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.3k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
430
Transcript
SwiftͷϦϯΫ࣌࠷దԽϓϩδΣΫτ Θ͍Θ͍swiftc #21 @kateinoigakukun 1
Swiftͷ࠷దԽϨϕϧ • ϑΝΠϧ୯Ґ ( -O ) • Ϟδϡʔϧ୯Ґ ( -whole-module-optimization
) http://llvm.org/devmtg/2016-10/slides/GroffLattner-SILHighLevelIR.pdf 2
Swiftͷ࠷దԽϨϕϧ • ϑΝΠϧ୯Ґ ( -O ) • Ϟδϡʔϧ୯Ґ ( -whole-module-optimization
) • (New ➕ ) ϓϩάϥϜશମ at LLVMϨϕϧ • (New ➕ ) ϓϩάϥϜશମ at SILϨϕϧ 3
LTO (Link Time Optimization) ίϯύΠϥͰͳ͘ɼϦϯΧ͕࣮ߦ͢Δ࠷దԽɽϓϩάϥϜશ ମΛҰͭͷ୯Ґͱͯ͠࠷దԽ͢Δɽ 4
LTO (Link Time Optimization) ϝϦοτ • όΠφϦͷґଘͯ͢ͷใΛ͑Δ • ϦϯΧ෦ͷγϯϘϧςʔϒϧΛ࠶ར༻Ͱ͖Δ 5
LLVM Ϩϕϧ LTO ΦϒδΣΫτϑΝΠϧͰͳ͘ɼLLVMϏοτίʔυΛೖྗϑΝ Πϧͱͯ͠ड͚͚Δɽ 6
LLVM Ϩϕϧ LTO ಛ • நͷߴ͍࠷దԽ • LLVMͷ࠷దԽύεΛ࠶ར༻ 7
ྫ͑ // LibX.swift public func unusedPublicFunc() {} public func publicFunc()
{} // main.swift import LibX publicFunc() 8
// LibX.ll define swiftcc void @"$s4LibX16unusedPublicFuncyyF"() #0 { entry: ret
void } define swiftcc void @"$s4LibX10publicFuncyyF"() #0 { entry: ret void } // main.ll define i32 @main(i32 %0, i8** %1) #0 { entry: %2 = bitcast i8** %1 to i8* call swiftcc void @"$s4LibX10publicFuncyyF"() ret i32 0 } 9
// LibX.ll define swiftcc void @"$s4LibX16unusedPublicFuncyyF"() #0 { entry: ret
void } define swiftcc void @"$s4LibX10publicFuncyyF"() #0 { entry: ret void } // main.ll define i32 @main(i32 %0, i8** %1) #0 { entry: %2 = bitcast i8** %1 to i8* call swiftcc void @"$s4LibX10publicFuncyyF"() ret i32 0 } 9
LLVM Ϩϕϧͩͱ͍͠࠷దԽ • ݴޠʹґଘͨ͠ϝλσʔλͷऔΓѻ͍ • ܕύϥϝʔλͷεϖγϟϥΠζ • ؔςʔϒϧʹࡌͬͨؔͷDFE (Dead Function
Elimination) 10
ྫ͑ // LibX.swift public protocol P { func foo() func
unusedMethod() } public struct S: P { public func foo() {} public func unusedMethod() {} } // main.swift import LibX func useP<T: P>(_ value: T) { value.foo() } useP(S()) 11
// LibX.ll @"$s4LibX1SVAA1PAAWP" = constant [3 x i8*] [ ...,
i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP3fooyyFTW" to i8*), i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW" to i8*) ], align 8 define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP3fooyyFTW"(...) { ... } define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW"(...) { ... } // main.ll define i32 @main(i32 %0, i8** %1) #0 { entry: ... call swiftcc void @"$s4main4usePyyx4LibX1PRzlF"( %swift.opaque* noalias nocapture undef, %swift.type* @"$s4LibX1SVN", i8** @"$s4LibX1SVAA1PAAWP" ) ret i32 0 } define hidden swiftcc void @"$s4main4usePyyx4LibX1PRzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T, i8** %T.P) { entry: %1 = getelementptr inbounds i8*, i8** %T.P, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !14 %3 = bitcast i8* %2 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %T, i8** %T.P) ret void } 12
// LibX.ll @"$s4LibX1SVAA1PAAWP" = constant [3 x i8*] [ ...,
i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP3fooyyFTW" to i8*), i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW" to i8*) ], align 8 define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP3fooyyFTW"(...) { ... } define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW"(...) { ... } // main.ll define i32 @main(i32 %0, i8** %1) #0 { entry: ... call swiftcc void @"$s4main4usePyyx4LibX1PRzlF"( %swift.opaque* noalias nocapture undef, %swift.type* @"$s4LibX1SVN", i8** @"$s4LibX1SVAA1PAAWP" ) ret i32 0 } define hidden swiftcc void @"$s4main4usePyyx4LibX1PRzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T, i8** %T.P) { entry: %1 = getelementptr inbounds i8*, i8** %T.P, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !14 %3 = bitcast i8* %2 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %T, i8** %T.P) ret void } 12
// LibX.ll @"$s4LibX1SVAA1PAAWP" = constant [3 x i8*] [ ...,
i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP3fooyyFTW" to i8*), i8* bitcast (void (%T4LibX1SV*, %swift.type*, i8**)* @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW" to i8*) ], align 8 define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP3fooyyFTW"(...) { ... } define linkonce_odr hidden swiftcc void @"$s4LibX1SVAA1PA2aDP12unusedMethodyyFTW"(...) { ... } // main.ll define i32 @main(i32 %0, i8** %1) #0 { entry: ... call swiftcc void @"$s4main4usePyyx4LibX1PRzlF"( %swift.opaque* noalias nocapture undef, %swift.type* @"$s4LibX1SVN", i8** @"$s4LibX1SVAA1PAAWP" ) ret i32 0 } define hidden swiftcc void @"$s4main4usePyyx4LibX1PRzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T, i8** %T.P) { entry: %1 = getelementptr inbounds i8*, i8** %T.P, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !14 %3 = bitcast i8* %2 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %T, i8** %T.P) ret void } 12
SIL Ϩϕϧ LTO 13
SIL Ϩϕϧ LTO 14
SIL Ϩϕϧ LTO ͷ Ϟνϕʔγϣϯ • LLVM IRΑΓநͷߴ͍࠷దԽ • SwiftͷηϚϯςΟΫεΛҡ࣋ͨ͠··LTO͍ͨ͠
• Ͳ͏ͤ੩తϦϯΫ͢ΔͳΒɺABI resiliencyΛແࢹͨ͠࠷దԽ Λ͍ͨ͠ɻ • ࣮ߦ࣌ύϑΥʔϚϯεͷվળͱόΠφϦαΠζͷॖখΛظ 15
࠷దԽϙΠϯτ (ະ࣮) 16
1. Cross Module Devirtualization 17
https://speakerdeck.com/kateinoigakukun/konpairakaraniu-jie-kuswift-method-dispatch-1?slide=39 18
https://speakerdeck.com/kateinoigakukun/konpairakaraniu-jie-kuswift-method-dispatch-1?slide=55 19
20
Cross Module Devirtualization • ͯ͢ͷϞδϡʔϧ͕LTOରͳΒɺϝιου͕Φʔόʔϥ Πυ͞Ε͍ͯΔ͔ඞ͔ͣΔ • ࣮࣭finalೝఆͰ͖Δݺͼग़͕͠૿͑Δ • ABI
resiliencyͷͨΊͷςʔϒϧܦ༝ݺͼग़͠Λ੩తݺͼग़͠ ʹͰ͖Δɻ 21
// LibX.swift open class A { public func foo1() {}
open func foo2() {} } public func invokeFoo1InModule(_ a: A) { // ͜Εݱঢ়ͷ࠷దԽύεͰdevirtͰ͖Δ a.foo1() } // main.swift import LibX func invokeFoo1(_ a: A) { // [LTO] ֎෦Ϟδϡʔϧͷ͕ؔͩɺABI resiliencyແࢹͰdevirtͰ͖Δɻ a.foo1() // [LTO] ֎෦Ϟδϡʔϧͷ͕ؔͩɺ୭override͍ͯ͠ͳ͍ͷͰdevirtͰ͖Δɻ a.foo2() } 22
2. Cross Module Specialization 23
Cross Module Specialization • ϞδϡʔϧΛ·͍ͨͩεϖγϟϥΠζ • ABI resiliencyΛແࢹͯ͠ɺશͯʹ@inlinable ͕͍͍ͭͯΔ Πϝʔδ
• όΠφϦαΠζͷංେԽ͕৺ 24
// LibX.swift public protocol Animal { func bark() } public
struct Cat: Animal { func bark() { } } // main.swift import LibX public callBark<T: Animal>(_ animal: T) { animal.bark() } 25
3. Dead Table Elimination 26
Dead Table Elimination • ௨ৗɺpublicͳVTableProtocol Witness Tableৗʹग़ྗ͞ ΕΔ • LTOͷ߹ɺΫϩεϞδϡʔϧͰΘΕ͍ͯΔ߹͚ͩग़ྗ
͢Ε͍͍ɻ • devirtͱεϖγϟϥΠζͰςʔϒϧͷࢀর͕ফ͑Δͱɺ͜ͷ ύε͕ΑΓޮՌతʹͳΔ 27
4. Dead public Function Elimination 28
Dead public Function Elimination • ௨ৗͷDFEinternalͳ͕ؔର • LTOͷ߹ɺpublicؔফͤΔ • ࣮ࡍʹDead
Table Eliminationͱಉ࣌ʹΔ • main͔ؔΒґଘ͢ΔؔΛ෯༏ઌ୳ࡧͰϚʔΫ͍ͯ͘͠ 29
࡞ۀਐḿ िใΛϑΥʔϥϜʹॻ͍ͯΔ https://forums.swift.org/t/gsoc-lto-support-progress-report/ 37149 30
LTO͕ಛʹخ͍͠໘ 31
stdlibΛؙ͝ͱ੩తϦϯΫ͢ΔͨΊɺ͍ͬͯͳ͍ػೳόΠφ Ϧʹೖͬͯ͠·͏ɻ Hello, worldͰ͢Β10MBɻ·͞ʹLTOͷग़൪ 32