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

SwiftのGenericsとProtocolの実装

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for omochimetaru omochimetaru
November 17, 2018

 SwiftのGenericsとProtocolの実装

Avatar for omochimetaru

omochimetaru

November 17, 2018
Tweet

More Decks by omochimetaru

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • omochimetaru • Qoncept, Inc. • iOS, Mac, Web

    Frontend, Unity, Android • Swift, C++, TypeScript, Kotlin • Twitter, GitHub, Qiita, Qrunch • ήʔϜ, SwiftίϯύΠϥ 2
  2. ࢀরܕ class Cat { var name: String = "ͨ·" }

    let a = Cat() let b = a b.name = "Έ͚" print(a.name) // Έ͚ TraceGC͸ແ͠ɻࢀরΧ΢ϯλΛ࢖͏ɻ 7
  3. ஋ܕ let a = [10, 20, 30] var b =

    a b[0] = 999 print(a) // [10, 20, 30] print(b) // [999, 20, 30] 8
  4. struct Stone { var weight: Int = 5 } let

    size = MemoryLayout<Stone>.size print(size) // 8 9
  5. struct BigStone { var weight: Int = 5 var blob1:

    Int = 999 var blob2: Int = 999 var blob3: Int = 999 } let size = MemoryLayout<BigStone>.size print(size) // 32 10
  6. Generics // Array<Element> let a: [Int] = [10, 20, 30]

    let b: [String] = a.map { String($0) } print(b) // ["10", "20", "30"] 11
  7. func wrapArray<X>(_ x: X) -> Array<X> { return [x] }

    let a = wrapArray(Stone()) print(a[0].weight) // 5 12
  8. define hidden swiftcc void @"$s1a6takeX1yyxlF"( %swift.opaque* noalias nocapture, %swift.type* %X)

    #0 { entry: %X1 = alloca %swift.type*, align 8 store %swift.type* %X, %swift.type** %X1, align 8 ret void } define hidden swiftcc void @"$s1a4mainyyF"() #0 { entry: %0 = alloca %TSi, align 8 %1 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %1) %._value = getelementptr inbounds %TSi, %TSi* %0, i32 0, i32 0 store i64 4, i64* %._value, align 8 %2 = bitcast %TSi* %0 to %swift.opaque* call swiftcc void @"$s1a6takeX1yyxlF"( %swift.opaque* noalias nocapture %2, %swift.type* @"$sSiN") %3 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %3) ret void } 17
  9. Metatype let t1: Int.Type = Int.self let t2 = type(of:

    3) print(t1 == t2) // true // static member access print(Int.bitWidth) // 64 print(t1.bitWidth) // 64 19
  10. ୈ1Ҿ਺ͷߏங define hidden swiftcc void @"$s1a4mainyyF"() #0 { entry: %0

    = alloca %TSi, align 8 %1 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %1) %._value = getelementptr inbounds %TSi, %TSi* %0, i32 0, i32 0 store i64 4, i64* %._value, align 8 %2 = bitcast %TSi* %0 to %swift.opaque* call swiftcc void @"$s1a6takeX1yyxlF"( %swift.opaque* noalias nocapture %2, %swift.type* @"$sSiN") %3 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %3) ret void } 20
  11. ୈ2Ҿ਺ͷߏங define hidden swiftcc void @"$s1a4mainyyF"() #0 { entry: %0

    = alloca %TSi, align 8 %1 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %1) %._value = getelementptr inbounds %TSi, %TSi* %0, i32 0, i32 0 store i64 4, i64* %._value, align 8 %2 = bitcast %TSi* %0 to %swift.opaque* call swiftcc void @"$s1a6takeX1yyxlF"( %swift.opaque* noalias nocapture %2, %swift.type* @"$sSiN") %3 = bitcast %TSi* %0 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %3) ret void } 21
  12. ܕ͕ෆ໌ͳ஋ͷૢ࡞ func takeX2<X>(_ x: X) { let a = x

    } • ม਺aͷετϨʔδ֬อ • x͔Βaʹ஋ͷίϐʔ • aͷഁغ, ετϨʔδղ์ 27
  13. include/swift/ABI/Metadata.h template <typename Runtime> struct TargetValueWitnessTable; using ValueWitnessTable = TargetValueWitnessTable<InProcess>;

    template <typename Runtime> struct TargetValueWitnessTable { #define WANT_ONLY_REQUIRED_VALUE_WITNESSES #define VALUE_WITNESS(LOWER_ID, UPPER_ID) \ typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID; #include "swift/ABI/ValueWitness.def" } 33
  14. template <typename Runtime> struct TargetValueWitnessTable { typename TargetValueWitnessTypes<Runtime>::initializeBufferWithCopyOfBuffer initializeBufferWithCopyOfBuffer; typename

    TargetValueWitnessTypes<Runtime>::destroy destroy; typename TargetValueWitnessTypes<Runtime>::initializeWithCopy initializeWithCopy; typename TargetValueWitnessTypes<Runtime>::assignWithCopy assignWithCopy; typename TargetValueWitnessTypes<Runtime>::initializeWithTake initializeWithTake; typename TargetValueWitnessTypes<Runtime>::assignWithTake assignWithTake; typename TargetValueWitnessTypes<Runtime>::getEnumTagSinglePayload getEnumTagSinglePayload; typename TargetValueWitnessTypes<Runtime>::storeEnumTagSinglePayload storeEnumTagSinglePayload; typename TargetValueWitnessTypes<Runtime>::size size; typename TargetValueWitnessTypes<Runtime>::flags flags; typename TargetValueWitnessTypes<Runtime>::stride stride; } 34
  15. define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type* %X)

    #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 40
  16. VWTͷऔΓग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 41
  17. VWT͔ΒsizeͷऔΓग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 42
  18. [8] = size struct TargetValueWitnessTable { initializeBufferWithCopyOfBuffer; destroy; initializeWithCopy; assignWithCopy;

    initializeWithTake; assignWithTake; getEnumTagSinglePayload; storeEnumTagSinglePayload; size; flags; stride; } 43
  19. ετϨʔδͷ֬อ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 44
  20. VWT͔ΒinitializeWithCopyͷऔΓग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 45
  21. [2] = initializeWithCopy struct TargetValueWitnessTable { initializeBufferWithCopyOfBuffer; destroy; initializeWithCopy; assignWithCopy;

    initializeWithTake; assignWithTake; getEnumTagSinglePayload; storeEnumTagSinglePayload; size; flags; stride; } 46
  22. initializeWithCopyͷݺͼग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 47
  23. VWT͔ΒdestroyͷऔΓग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 48
  24. [1] = destroy struct TargetValueWitnessTable { initializeBufferWithCopyOfBuffer; destroy; initializeWithCopy; assignWithCopy;

    initializeWithTake; assignWithTake; getEnumTagSinglePayload; storeEnumTagSinglePayload; size; flags; stride; } 49
  25. destroyͷݺͼग़͠ define hidden swiftcc void @"$s1b6takeX2yyxlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X) #0 { entry: %X1 = alloca %swift.type*, align 8 %a.debug = alloca i8*, align 8 %1 = bitcast i8** %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %swift.type* %X, %swift.type** %X1, align 8 %2 = bitcast %swift.type* %X to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %X.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 8 %5 = load i8*, i8** %4, align 8, !invariant.load !13 %size = ptrtoint i8* %5 to i64 %a = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a) %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 %10 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 1 %11 = load i8*, i8** %10, align 8, !invariant.load !13 %destroy = bitcast i8* %11 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %6, %swift.type* %X) #3 %12 = bitcast %swift.opaque* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 50
  26. ࠶ܝ Swift → SIL → LLVM IR → ࣮ߦϑΝΠϧ LLVM

    IRͷੜ੒͸SIL͔Βͷม׵ͱ࣮ͯ͠૷͞Εͯ ͍Δɻ 53
  27. // takeX2<A>(_:) sil hidden @$s1b6takeX2yyxlF : $@convention(thin) <X> (@in_guaranteed X)

    -> () { // %0 // users: %3, %1 bb0(%0 : $*X): debug_value_addr %0 : $*X, let, name "x", argno 1 // id: %1 %2 = alloc_stack $X, let, name "a" // users: %5, %4, %3 copy_addr %0 to [initialization] %2 : $*X // id: %3 destroy_addr %2 : $*X // id: %4 dealloc_stack %2 : $*X // id: %5 %6 = tuple () // user: %7 return %6 : $() // id: %7 } // end sil function '$s1b6takeX2yyxlF' 55
  28. copy_addr Λݟ͍ͯ͘ // takeX2<A>(_:) sil hidden @$s1b6takeX2yyxlF : $@convention(thin) <X>

    (@in_guaranteed X) -> () { // %0 // users: %3, %1 bb0(%0 : $*X): debug_value_addr %0 : $*X, let, name "x", argno 1 // id: %1 %2 = alloc_stack $X, let, name "a" // users: %5, %4, %3 copy_addr %0 to [initialization] %2 : $*X // id: %3 destroy_addr %2 : $*X // id: %4 dealloc_stack %2 : $*X // id: %5 %6 = tuple () // user: %7 return %6 : $() // id: %7 } // end sil function '$s1b6takeX2yyxlF' 56
  29. ରԠ͢ΔLLVM-IR %6 = bitcast i8* %a to %swift.opaque* store i8*

    %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 57
  30. template <typename ImplClass, typename RetTy = void, typename... ArgTys> class

    SILInstructionVisitor { public: RetTy visit(SILInstruction *inst, ArgTys... args) { asImpl().beforeVisit(inst, args...); switch (inst->getKind()) { #define INST(CLASS, PARENT) \ case SILInstructionKind::CLASS: \ return asImpl().visit##CLASS(static_cast<CLASS*>(inst), \ std::forward<ArgTys>(args)...); #include "swift/SIL/SILNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } } 61
  31. copy_addr໋ྩͷॲཧதͳͷͰvisitCopyAddrInst ͕ݺ͹ΕΔ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) { SILType addrTy = i->getSrc()->getType();

    const TypeInfo &addrTI = getTypeInfo(addrTy); Address src = getLoweredAddress(i->getSrc()); // See whether we have a deferred fixed-size buffer initialization. auto &loweredDest = getLoweredValue(i->getDest()); assert(!loweredDest.isUnallocatedAddressInBuffer()); Address dest = loweredDest.getAnyAddress(); if (i->isInitializationOfDest()) { if (i->isTakeOfSrc()) { addrTI.initializeWithTake(*this, dest, src, addrTy, false); } else { addrTI.initializeWithCopy(*this, dest, src, addrTy, false); } } else { if (i->isTakeOfSrc()) { addrTI.assignWithTake(*this, dest, src, addrTy, false); } else { addrTI.assignWithCopy(*this, dest, src, addrTy, false); } } } 62
  32. ίϐʔݩͷίϯύΠϧ࣌ܕ৘ใ(TypeInfo)ΛऔΓग़ ͢ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) { SILType addrTy = i->getSrc()->getType();

    const TypeInfo &addrTI = getTypeInfo(addrTy); Address src = getLoweredAddress(i->getSrc()); // See whether we have a deferred fixed-size buffer initialization. auto &loweredDest = getLoweredValue(i->getDest()); assert(!loweredDest.isUnallocatedAddressInBuffer()); Address dest = loweredDest.getAnyAddress(); if (i->isInitializationOfDest()) { if (i->isTakeOfSrc()) { addrTI.initializeWithTake(*this, dest, src, addrTy, false); } else { addrTI.initializeWithCopy(*this, dest, src, addrTy, false); } } else { if (i->isTakeOfSrc()) { addrTI.assignWithTake(*this, dest, src, addrTy, false); } else { addrTI.assignWithCopy(*this, dest, src, addrTy, false); } } } 63
  33. ܕ৘ใͷϝιουʹసૹ͢Δ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) { SILType addrTy = i->getSrc()->getType(); const

    TypeInfo &addrTI = getTypeInfo(addrTy); Address src = getLoweredAddress(i->getSrc()); // See whether we have a deferred fixed-size buffer initialization. auto &loweredDest = getLoweredValue(i->getDest()); assert(!loweredDest.isUnallocatedAddressInBuffer()); Address dest = loweredDest.getAnyAddress(); if (i->isInitializationOfDest()) { if (i->isTakeOfSrc()) { addrTI.initializeWithTake(*this, dest, src, addrTy, false); } else { addrTI.initializeWithCopy(*this, dest, src, addrTy, false); } } else { if (i->isTakeOfSrc()) { addrTI.assignWithTake(*this, dest, src, addrTy, false); } else { addrTI.assignWithCopy(*this, dest, src, addrTy, false); } } } 64
  34. ਌ΫϥεͷResilientTypeInfoͷ࣮૷͕ݺ͹ΕΔ lib/IRGen/ResilientTypeInfo.h template <class Impl> class ResilientTypeInfo : public WitnessSizedTypeInfo<Impl>

    { void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src, SILType T, bool isOutlined) const override { emitInitializeWithCopyCall(IGF, T, dest, src); } }; 66
  35. lib/IRGen/GenOpaque.cpp void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF, SILType T, Address dest, Address src)

    { llvm::Value *metadata; auto fn = IGF.emitValueWitnessFunctionRef(T, metadata, ValueWitness::InitializeWithCopy); auto destPtr = emitCastToOpaquePtr(IGF, dest); auto srcPtr = emitCastToOpaquePtr(IGF, src); IGF.Builder.CreateCall(fn, {destPtr, srcPtr, metadata}); } 67
  36. void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF, SILType T, Address dest, Address src) {

    llvm::Value *metadata; auto fn = IGF.emitValueWitnessFunctionRef(T, metadata, ValueWitness::InitializeWithCopy); auto destPtr = emitCastToOpaquePtr(IGF, dest); auto srcPtr = emitCastToOpaquePtr(IGF, src); IGF.Builder.CreateCall(fn, {destPtr, srcPtr, metadata}); } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 68
  37. void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF, SILType T, Address dest, Address src) {

    llvm::Value *metadata; auto fn = IGF.emitValueWitnessFunctionRef(T, metadata, ValueWitness::InitializeWithCopy); auto destPtr = emitCastToOpaquePtr(IGF, dest); auto srcPtr = emitCastToOpaquePtr(IGF, src); IGF.Builder.CreateCall(fn, {destPtr, srcPtr, metadata}); } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 69
  38. void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF, SILType T, Address dest, Address src) {

    llvm::Value *metadata; auto fn = IGF.emitValueWitnessFunctionRef(T, metadata, ValueWitness::InitializeWithCopy); auto destPtr = emitCastToOpaquePtr(IGF, dest); auto srcPtr = emitCastToOpaquePtr(IGF, src); IGF.Builder.CreateCall(fn, {destPtr, srcPtr, metadata}); } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 70
  39. lib/IRGen/GenOpaque.cpp // index = ValueWitness::InitializeWithCopy FunctionPointer IRGenFunction::emitValueWitnessFunctionRef(SILType type, llvm::Value *&metadataSlot,

    ValueWitness index) { assert(isValueWitnessFunction(index)); auto key = LocalTypeDataKind::forValueWitness(index); if (auto witness = tryGetLocalTypeDataForLayout(type, key)) { metadataSlot = emitTypeMetadataRefForLayout(type); auto signature = IGM.getValueWitnessSignature(index); return FunctionPointer(witness, signature); } auto vwtable = emitValueWitnessTableRef(type, &metadataSlot); auto witness = emitLoadOfValueWitnessFunction(*this, vwtable, index); setScopedLocalTypeDataForLayout(type, key, witness.getPointer()); return witness; } 71
  40. // index = ValueWitness::InitializeWithCopy FunctionPointer IRGenFunction::emitValueWitnessFunctionRef(SILType type, llvm::Value *&metadataSlot, ValueWitness

    index) { assert(isValueWitnessFunction(index)); auto key = LocalTypeDataKind::forValueWitness(index); if (auto witness = tryGetLocalTypeDataForLayout(type, key)) { metadataSlot = emitTypeMetadataRefForLayout(type); auto signature = IGM.getValueWitnessSignature(index); return FunctionPointer(witness, signature); } auto vwtable = emitValueWitnessTableRef(type, &metadataSlot); auto witness = emitLoadOfValueWitnessFunction(*this, vwtable, index); setScopedLocalTypeDataForLayout(type, key, witness.getPointer()); return witness; } 72
  41. // index = ValueWitness::InitializeWithCopy static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF, llvm::Value *table,

    ValueWitness index) { assert(isValueWitnessFunction(index)); llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, index); auto label = getValueWitnessLabel(index); auto signature = IGF.IGM.getValueWitnessSignature(index); auto type = signature.getType()->getPointerTo(); witness = IGF.Builder.CreateBitCast(witness, type, label); return FunctionPointer(witness, signature); } 73
  42. // index = ValueWitness::InitializeWithCopy static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF, llvm::Value *table,

    ValueWitness index) { assert(isValueWitnessFunction(index)); llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, index); auto label = getValueWitnessLabel(index); auto signature = IGF.IGM.getValueWitnessSignature(index); auto type = signature.getType()->getPointerTo(); witness = IGF.Builder.CreateBitCast(witness, type, label); return FunctionPointer(witness, signature); } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 74
  43. // index = ValueWitness::InitializeWithCopy static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF, llvm::Value *table,

    ValueWitness index) { assert(isValueWitnessFunction(index)); llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, index); auto label = getValueWitnessLabel(index); auto signature = IGF.IGM.getValueWitnessSignature(index); auto type = signature.getType()->getPointerTo(); witness = IGF.Builder.CreateBitCast(witness, type, label); return FunctionPointer(witness, signature); } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 75
  44. // index = ValueWitness::InitializeWithCopy llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, WitnessIndex

    index) { assert(table->getType() == IGF.IGM.WitnessTablePtrTy); // GEP to the appropriate index, avoiding spurious IR in the trivial case. llvm::Value *slot = table; if (index.getValue() != 0) slot = IGF.Builder.CreateConstInBoundsGEP1_32( /*Ty=*/nullptr, table, index.getValue()); auto witness = IGF.Builder.CreateLoad(Address(slot, IGF.IGM.getPointerAlignment())); IGF.setInvariantLoad(witness); return witness; } 76
  45. // index = ValueWitness::InitializeWithCopy llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, WitnessIndex

    index) { assert(table->getType() == IGF.IGM.WitnessTablePtrTy); // GEP to the appropriate index, avoiding spurious IR in the trivial case. llvm::Value *slot = table; if (index.getValue() != 0) slot = IGF.Builder.CreateConstInBoundsGEP1_32( /*Ty=*/nullptr, table, index.getValue()); auto witness = IGF.Builder.CreateLoad(Address(slot, IGF.IGM.getPointerAlignment())); IGF.setInvariantLoad(witness); return witness; } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 77
  46. // index = ValueWitness::InitializeWithCopy llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, WitnessIndex

    index) { assert(table->getType() == IGF.IGM.WitnessTablePtrTy); // GEP to the appropriate index, avoiding spurious IR in the trivial case. llvm::Value *slot = table; if (index.getValue() != 0) slot = IGF.Builder.CreateConstInBoundsGEP1_32( /*Ty=*/nullptr, table, index.getValue()); auto witness = IGF.Builder.CreateLoad(Address(slot, IGF.IGM.getPointerAlignment())); IGF.setInvariantLoad(witness); return witness; } %6 = bitcast i8* %a to %swift.opaque* store i8* %a, i8** %a.debug, align 8 %7 = getelementptr inbounds i8*, i8** %X.valueWitnesses, i32 2 %8 = load i8*, i8** %7, align 8, !invariant.load !13 %initializeWithCopy = bitcast i8* %8 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %9 = call %swift.opaque* %initializeWithCopy( %swift.opaque* noalias %6, %swift.opaque* noalias %0, %swift.type* %X) #3 78
  47. ϝιουͷఆٛ protocol Animal { func speak() -> String } class

    Cat : Animal { func speak() -> String { return "ʹΌʔ" } } class Dog : Animal { func speak() -> String { return "ΘΜ" } } 80
  48. staticϝιουͷఆٛ protocol Animal { static func label() -> String }

    class Cat : Animal { static func label() -> String { return "ೣ" } } class Dog : Animal { static func label() -> String { return "ݘ" } } 81
  49. associated type protocol Animal { associatedtype Food func eat(food: Food)

    } struct CatFood {} class Cat : Animal { typealias Food = CatFood func eat(food: CatFood) { } } struct DogFood {} class Dog : Animal { typealias Food = DogFood func eat(food: DogFood) { } } 82
  50. Selfܕ protocol Animal { func spawn() -> Self } final

    class Cat : Animal { func spawn() -> Cat { return Cat() } } final class Dog : Animal { func spawn() -> Dog { return Dog() } } 83
  51. Genericsͱ૊Έ߹ΘͤΔ protocol Animal { func speak() -> String } class

    Cat : Animal { func speak() -> String { return "ʹΌʔ" } } func invokeSpeak<X: Animal>(animal: X) -> String { return animal.speak() } print(invokeSpeak(animal: Cat())) // ʹΌʔ 84
  52. ܕΫϥε෩ protocol Addable { static var zero: Self { get

    } static func +(a: Self, b: Self) -> Self } extension Int : Addable { static var zero: Int { return 0 } } extension Sequence where Element : Addable { func sum() -> Element { return reduce(Element.zero) { $0 + $1 } } } let a = [1, 2, 3] // Array (struct) ͸ Sequence (protocol) print(a.sum()) // 6 85
  53. protocol Animal { func speak() -> Int } class Cat

    : Animal { func speak() -> Int { return 28 } } struct Stone : Animal { func speak() -> Int { return 14 } } 88
  54. SILͰݟΔͱɺCatͱStoneͦΕͧΕʹɺ Animalͷwitness table͕͋Δ sil_witness_table hidden Cat: Animal module c {

    method #Animal.speak!1: <Self where Self : Animal> (Self) -> () -> Int : @$s1c3CatCAA6AnimalA2aDP5speakSiyFTW // protocol witness for Animal.speak() in conformance Cat } sil_witness_table hidden Stone: Animal module c { method #Animal.speak!1: <Self where Self : Animal> (Self) -> () -> Int : @$s1c5StoneVAA6AnimalA2aDP5speakSiyFTW // protocol witness for Animal.speak() in conformance Stone } 89
  55. SILͰݟΔ // invokeSpeak<A>(animal:) sil hidden @$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF : $@convention(thin) <X where

    X : Animal> (@in_guaranteed X) -> Int { // %0 // users: %3, %1 bb0(%0 : $*X): debug_value_addr %0 : $*X, let, name "animal", argno 1 // id: %1 %2 = witness_method $X, #Animal.speak!1 : <Self where Self : Animal> (Self) -> () -> Int : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %3 %3 = apply %2<X>(%0) : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %4 return %3 : $Int // id: %4 } // end sil function '$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF' 92
  56. witnessϝιουͷऔΓग़͠ // invokeSpeak<A>(animal:) sil hidden @$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF : $@convention(thin) <X where

    X : Animal> (@in_guaranteed X) -> Int { // %0 // users: %3, %1 bb0(%0 : $*X): debug_value_addr %0 : $*X, let, name "animal", argno 1 // id: %1 %2 = witness_method $X, #Animal.speak!1 : <Self where Self : Animal> (Self) -> () -> Int : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %3 %3 = apply %2<X>(%0) : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %4 return %3 : $Int // id: %4 } // end sil function '$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF' 93
  57. ؔ਺ͷݺͼग़͠ // invokeSpeak<A>(animal:) sil hidden @$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF : $@convention(thin) <X where

    X : Animal> (@in_guaranteed X) -> Int { // %0 // users: %3, %1 bb0(%0 : $*X): debug_value_addr %0 : $*X, let, name "animal", argno 1 // id: %1 %2 = witness_method $X, #Animal.speak!1 : <Self where Self : Animal> (Self) -> () -> Int : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %3 %3 = apply %2<X>(%0) : $@convention(witness_method: Animal) <τ_0_0 where τ_0_0 : Animal> (@in_guaranteed τ_0_0) -> Int // user: %4 return %3 : $Int // id: %4 } // end sil function '$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF' 94
  58. LLVM-IRͰͷPWT @"$s1c3CatCAA6AnimalAAWP" = hidden constant [2 x i8*] [ i8*

    bitcast (%swift.protocol_conformance_descriptor* @"$s1c3CatCAA6AnimalAAMc" to i8*), i8* bitcast (i64 (%T1c3CatC**, %swift.type*, i8**)* @"$s1c3CatCAA6AnimalA2aDP5speakSiyFTW" to i8*) ], align 8 @"$s1c5StoneVAA6AnimalAAWP" = hidden constant [2 x i8*] [ i8* bitcast (%swift.protocol_conformance_descriptor* @"$s1c5StoneVAA6AnimalAAMc" to i8*), i8* bitcast (i64 (%T1c5StoneV*, %swift.type*, i8**)* @"$s1c5StoneVAA6AnimalA2aDP5speakSiyFTW" to i8*) ], align 8 95
  59. LLVM-IRͰͷར༻ଆ define hidden swiftcc i64 @"$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X, i8** %X.Animal) #0 { entry: %X1 = alloca %swift.type*, align 8 store %swift.type* %X, %swift.type** %X1, align 8 %1 = getelementptr inbounds i8*, i8** %X.Animal, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !29 %3 = bitcast i8* %2 to i64 (%swift.opaque*, %swift.type*, i8**)* %4 = call swiftcc i64 %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %X, i8** %X.Animal) ret i64 %4 } 96
  60. Signature func invokeSpeak<X: Animal>(animal: X) -> Int define hidden swiftcc

    i64 @"$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF"( %swift.opaque* noalias nocapture, %swift.type* %X, i8** %X.Animal) <X: Animal> → opaque pointer + meta type + witness table 97
  61. witnessϝιουͷऔΓग़͠ define hidden swiftcc i64 @"$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X, i8** %X.Animal) #0 { entry: %X1 = alloca %swift.type*, align 8 store %swift.type* %X, %swift.type** %X1, align 8 %1 = getelementptr inbounds i8*, i8** %X.Animal, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !29 %3 = bitcast i8* %2 to i64 (%swift.opaque*, %swift.type*, i8**)* %4 = call swiftcc i64 %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %X, i8** %X.Animal) ret i64 %4 } 98
  62. @"$s1c3CatCAA6AnimalAAWP" = hidden constant [2 x i8*] [ i8* bitcast

    (%swift.protocol_conformance_descriptor* @"$s1c3CatCAA6AnimalAAMc" to i8*), i8* bitcast (i64 (%T1c3CatC**, %swift.type*, i8**)* @"$s1c3CatCAA6AnimalA2aDP5speakSiyFTW" to i8*) ], align 8 @"$s1c5StoneVAA6AnimalAAWP" = hidden constant [2 x i8*] [ i8* bitcast (%swift.protocol_conformance_descriptor* @"$s1c5StoneVAA6AnimalAAMc" to i8*), i8* bitcast (i64 (%T1c5StoneV*, %swift.type*, i8**)* @"$s1c5StoneVAA6AnimalA2aDP5speakSiyFTW" to i8*) ], align 8 99
  63. witnessϝιουͷݺͼग़͠ define hidden swiftcc i64 @"$s1c11invokeSpeak6animalSix_tAA6AnimalRzlF"( %swift.opaque* noalias nocapture, %swift.type*

    %X, i8** %X.Animal) #0 { entry: %X1 = alloca %swift.type*, align 8 store %swift.type* %X, %swift.type** %X1, align 8 %1 = getelementptr inbounds i8*, i8** %X.Animal, i32 1 %2 = load i8*, i8** %1, align 8, !invariant.load !29 %3 = bitcast i8* %2 to i64 (%swift.opaque*, %swift.type*, i8**)* %4 = call swiftcc i64 %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %X, i8** %X.Animal) ret i64 %4 } 100
  64. ܕΫϥε෩ͷྫ protocol Addable { static var zero: Self { get

    } static func +(a: Self, b: Self) -> Self } extension Int : Addable { static var zero: Int { return 0 } } extension Sequence where Element : Addable { func sum() -> Element { return reduce(Element.zero) { $0 + $1 } } } let a = [1, 2, 3] // Array (struct) ͸ Sequence (protocol) print(a.sum()) // 6 101
  65. IntͷAddable @"$sSi1d7AddableAAWP" = hidden constant [3 x i8*] [ i8*

    bitcast (%swift.protocol_conformance_descriptor* @"$sSi1d7AddableAAMc" to i8*), i8* bitcast ( void (%TSi*, %swift.type*, %swift.type*, i8**)* @"$sSi1d7AddableA2aBP4zeroxvgZTW" to i8*), i8* bitcast ( void (%TSi*, %TSi*, %TSi*, %swift.type*, %swift.type*, i8**)* @"$sSi1d7AddableA2aBP1poiyxx_xtFZTW" to i8*) ], align 8 102
  66. sumϝιου define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr inbounds ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* call swiftcc void @"$sSTsE6reduceyqd__qd___qd__qd___7ElementQztKXEtKlF"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %8, i8* bitcast ( void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.refcounted*)* @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA" to i8*), %swift.opaque* %21, %swift.type* %Self, %swift.type* %Self.Element, i8** %Self.Sequence, %swift.opaque* noalias nocapture swiftself %1, %swift.error** noalias nocapture swifterror dereferenceable(8) %swifterror) %22 = load %swift.error*, %swift.error** %swifterror, align 8 %23 = icmp ne %swift.error* %22, null br i1 %23, label %28, label %24 ; <label>:24: ; preds = %entry call void @swift_release(%swift.refcounted* %12) #5 call void @swift_release(%swift.refcounted* %12) #5 %25 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 1 %26 = load i8*, i8** %25, align 8, !invariant.load !23 %destroy = bitcast i8* %26 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %8, %swift.type* %Self.Element) #5 %27 = bitcast %swift.opaque* %8 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %27) ret void ; <label>:28: ; preds = %entry %29 = phi %swift.error* [ %22, %entry ] store %swift.error* null, %swift.error** %swifterror, align 8 call void @swift_release(%swift.refcounted* %12) #5 unreachable } 103
  67. େ·͔ͳྲྀΕ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: ; Element.zeroͷ༻ҙ ; Ϋϩʔδϟ؀ڥͷ༻ҙ ; Sequence.reduceͷݺͼग़͠ ; ྫ֎ϋϯυϦϯά ; <label>:24: ; ਖ਼ৗܥ, ΫϦϯφοϓ ; <label>:28: ; ҟৗܥ } 104
  68. Signature define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( ; ฦΓ஋ %swift.opaque* noalias

    nocapture sret, ; Array metatype %swift.type* %Self, ; Sequence PWT of Array i8** %Self.Sequence, ; Addable PWT of Int i8** %Self.Element.Addable, ; self (Array) %swift.opaque* noalias nocapture swiftself) 105
  69. Element.zeroͷ༻ҙ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 106
  70. Array<Int>.Type͔ΒInt.TypeͷऔΓग़͠ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 107
  71. IntͷVWTͷऔΓग़͠ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 108
  72. VWT͔ΒsizeͷऔΓग़͠ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 109
  73. zeroͷྖҬ֬อ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 110
  74. PWT͔Βstatic funcͷऔΓग़͠ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture

    sret, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 111
  75. zeroͷݺͼग़͠ͱ֨ೲ define hidden swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyF"( %swift.opaque* noalias nocapture sret,

    %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable, %swift.opaque* noalias nocapture swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 %swifterror = alloca swifterror %swift.error*, align 8 store %swift.error* null, %swift.error** %swifterror, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %2 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %2, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %3 = bitcast %swift.type* %Self.Element to i8*** %4 = getelementptr inbounds i8**, i8*** %3, i64 -1 %Self.Element.valueWitnesses = load i8**, i8*** %4, align 8, !invariant.load !23, !dereferenceable !24 %5 = getelementptr inbounds i8*, i8** %Self.Element.valueWitnesses, i32 8 %6 = load i8*, i8** %5, align 8, !invariant.load !23 %size = ptrtoint i8* %6 to i64 %7 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) %8 = bitcast i8* %7 to %swift.opaque* %9 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !23 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %11( %swift.opaque* noalias nocapture sret %8, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) 112
  76. Ϋϩʔδϟ؀ڥͷ༻ҙ %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr inbounds

    ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* 113
  77. 3ϫʔυͷstorageΛ࣋ͭΦϒδΣΫτͷੜ੒ %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr inbounds

    ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* 114
  78. [0]ʹArray.TypeΛ֨ೲ %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr inbounds

    ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* 115
  79. [1]ʹArrayͷSequence PWTΛ֨ೲ %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr

    inbounds ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* 116
  80. [2]ʹIntͷAddable PWTΛ֨ೲ %12 = call noalias %swift.refcounted* @swift_allocObject( %swift.type* getelementptr

    inbounds ( %swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), i64 40, i64 7) #5 %13 = bitcast %swift.refcounted* %12 to <{ %swift.refcounted, [24 x i8] }>* %14 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %13, i32 0, i32 1 %15 = bitcast [24 x i8]* %14 to %swift.type** store %swift.type* %Self, %swift.type** %15, align 8 %16 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 1 %17 = bitcast %swift.type** %16 to i8*** store i8** %Self.Sequence, i8*** %17, align 8 %18 = getelementptr inbounds %swift.type*, %swift.type** %15, i32 2 %19 = bitcast %swift.type** %18 to i8*** store i8** %Self.Element.Addable, i8*** %19, align 8 %20 = call %swift.refcounted* @swift_retain(%swift.refcounted* returned %12) #5 %21 = bitcast %swift.refcounted* %12 to %swift.opaque* 117
  81. Sequence.reduceͷݺͼग़͠ call swiftcc void @"$sSTsE6reduceyqd__qd___qd__qd___7ElementQztKXEtKlF"( %swift.opaque* noalias nocapture sret %0,

    %swift.opaque* noalias nocapture %8, i8* bitcast ( void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.refcounted*)* @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA" to i8*), %swift.opaque* %21, %swift.type* %Self, %swift.type* %Self.Element, i8** %Self.Sequence, %swift.opaque* noalias nocapture swiftself %1, %swift.error** noalias nocapture swifterror dereferenceable(8) %swifterror) 118
  82. call swiftcc void @"$sSTsE6reduceyqd__qd___qd__qd___7ElementQztKXEtKlF"( ; ฦΓ஋ %swift.opaque* noalias nocapture sret

    %0, ; ࡞ͬͨzero %swift.opaque* noalias nocapture %8, ; Ϋϩʔδϟͷؔ਺ϙΠϯλ i8* bitcast ( void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.refcounted*)* @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA" to i8*), ; ࡞ͬͨΫϩʔδϟ؀ڥ %swift.opaque* %21, ; Array.Type %swift.type* %Self, ; Int.Type %swift.type* %Self.Element, ; ArrayͷSequence PWT i8** %Self.Sequence, ; self (Array) %swift.opaque* noalias nocapture swiftself %1, ; ྫ֎ %swift.error** noalias nocapture swifterror dereferenceable(8) %swifterror) 119
  83. ౉ͯ͠ΔΫϩʔδϟ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.refcounted* swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %4 = bitcast %swift.refcounted* %3 to <{ %swift.refcounted, [24 x i8] }>* %5 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %4, i32 0, i32 1 %6 = bitcast [24 x i8]* %5 to %swift.type** %Self = load %swift.type*, %swift.type** %6, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 1 %8 = bitcast %swift.type** %7 to i8*** %Self.Sequence = load i8**, i8*** %8, align 8 %9 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 2 %10 = bitcast %swift.type** %9 to i8*** %Self.Element.Addable = load i8**, i8*** %10, align 8 tail call swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) ret void } 120
  84. Signature define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( ; ฦΓ஋ %swift.opaque* noalias

    nocapture sret, ; Ҿ਺1 %swift.opaque* noalias nocapture, ; Ҿ਺2 %swift.opaque* noalias nocapture, ; Ϋϩʔδϟ؀ڥ %swift.refcounted* swiftself) 121
  85. ؀ڥ͔ΒArray.TypeͷऔΓग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.refcounted* swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %4 = bitcast %swift.refcounted* %3 to <{ %swift.refcounted, [24 x i8] }>* %5 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %4, i32 0, i32 1 %6 = bitcast [24 x i8]* %5 to %swift.type** %Self = load %swift.type*, %swift.type** %6, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 1 %8 = bitcast %swift.type** %7 to i8*** %Self.Sequence = load i8**, i8*** %8, align 8 %9 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 2 %10 = bitcast %swift.type** %9 to i8*** %Self.Element.Addable = load i8**, i8*** %10, align 8 tail call swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) ret void } 122
  86. ؀ڥ͔ΒArrayͷSequence PWTͷऔΓग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( %swift.opaque* noalias nocapture

    sret, %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.refcounted* swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %4 = bitcast %swift.refcounted* %3 to <{ %swift.refcounted, [24 x i8] }>* %5 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %4, i32 0, i32 1 %6 = bitcast [24 x i8]* %5 to %swift.type** %Self = load %swift.type*, %swift.type** %6, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 1 %8 = bitcast %swift.type** %7 to i8*** %Self.Sequence = load i8**, i8*** %8, align 8 %9 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 2 %10 = bitcast %swift.type** %9 to i8*** %Self.Element.Addable = load i8**, i8*** %10, align 8 tail call swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) ret void } 123
  87. ؀ڥ͔ΒIntͷAddable PWTͷऔΓग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( %swift.opaque* noalias nocapture

    sret, %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.refcounted* swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %4 = bitcast %swift.refcounted* %3 to <{ %swift.refcounted, [24 x i8] }>* %5 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %4, i32 0, i32 1 %6 = bitcast [24 x i8]* %5 to %swift.type** %Self = load %swift.type*, %swift.type** %6, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 1 %8 = bitcast %swift.type** %7 to i8*** %Self.Sequence = load i8**, i8*** %8, align 8 %9 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 2 %10 = bitcast %swift.type** %9 to i8*** %Self.Element.Addable = load i8**, i8*** %10, align 8 tail call swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) ret void } 124
  88. Ϋϩʔδϟຊମͷݺͼग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_TA"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.refcounted* swiftself) #0 { entry: %Self1 = alloca %swift.type*, align 8 %4 = bitcast %swift.refcounted* %3 to <{ %swift.refcounted, [24 x i8] }>* %5 = getelementptr inbounds <{ %swift.refcounted, [24 x i8] }>, <{ %swift.refcounted, [24 x i8] }>* %4, i32 0, i32 1 %6 = bitcast [24 x i8]* %5 to %swift.type** %Self = load %swift.type*, %swift.type** %6, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 1 %8 = bitcast %swift.type** %7 to i8*** %Self.Sequence = load i8**, i8*** %8, align 8 %9 = getelementptr inbounds %swift.type*, %swift.type** %6, i32 2 %10 = bitcast %swift.type** %9 to i8*** %Self.Element.Addable = load i8**, i8*** %10, align 8 tail call swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) ret void } 125
  89. Ϋϩʔδϟຊମ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %3 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %3, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %4 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 2 %5 = load i8*, i8** %4, align 8, !invariant.load !23 %6 = bitcast i8* %5 to void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %6( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) ret void } 126
  90. Array.Type͔ΒInt.TypeͷऔΓग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %3 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %3, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %4 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 2 %5 = load i8*, i8** %4, align 8, !invariant.load !23 %6 = bitcast i8* %5 to void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %6( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) ret void } 127
  91. PWT͔Β+ͷऔΓग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %3 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %3, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %4 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 2 %5 = load i8*, i8** %4, align 8, !invariant.load !23 %6 = bitcast i8* %5 to void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %6( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) ret void } 128
  92. +ͷݺͼग़͠ define internal swiftcc void @"$sST1dAA7Addable7ElementRpzrlE3sumADyFA2D_ADtXEfU_"( %swift.opaque* noalias nocapture sret,

    %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %Self, i8** %Self.Sequence, i8** %Self.Element.Addable) #0 { entry: %Self1 = alloca %swift.type*, align 8 %Self.Element2 = alloca %swift.type*, align 8 store %swift.type* %Self, %swift.type** %Self1, align 8 %3 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %Self.Sequence, %swift.type* %Self, %swift.protocol_requirement* @"$sSTTL", %swift.protocol_requirement* @"$s7ElementSTTl") #6 %Self.Element = extractvalue %swift.metadata_response %3, 0 store %swift.type* %Self.Element, %swift.type** %Self.Element2, align 8 %4 = getelementptr inbounds i8*, i8** %Self.Element.Addable, i32 2 %5 = load i8*, i8** %4, align 8, !invariant.load !23 %6 = bitcast i8* %5 to void (%swift.opaque*, %swift.opaque*, %swift.opaque*, %swift.type*, %swift.type*, i8**)* call swiftcc void %6( %swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.opaque* noalias nocapture %2, %swift.type* swiftself %Self.Element, %swift.type* %Self.Element, i8** %Self.Element.Addable) ret void } 129