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

SwiftのGenericsとProtocolの実装

omochimetaru
November 17, 2018

 SwiftのGenericsとProtocolの実装

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