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

ジェネリック型のメタタイプ

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

 ジェネリック型のメタタイプ

Avatar for omochimetaru

omochimetaru

September 12, 2018
Tweet

More Decks by omochimetaru

Other Decks in Programming

Transcript

  1. ϝλλΠϓͷྫ struct Stone { var a: Int = 0 var

    b: Bool = false var c: String = "" } 6
  2. @"$S1g5StoneVMf" = <{ i8** getelementptr inbounds ( @"$S1g5StoneVWV", i32 0,

    i32 0), i64 0x200, <{ ... }>* @"$S1g5StoneVMn", i32 0, i32 8, i32 16, [4 x i8] zeroinitializer }>, align 8 7
  3. @"$S1g5StoneVMf" = <{ i8** getelementptr inbounds ( @"$S1g5StoneVWV", i32 0,

    i32 0), i64 0x200, <{ ... }>* @"$S1g5StoneVMn", i32 0, i32 8, i32 16, [4 x i8] zeroinitializer }>, align 8 8
  4. @"$S1g5StoneVMf" = <{ i8** getelementptr inbounds ( @"$S1g5StoneVWV", i32 0,

    i32 0), i64 0x200, <{ ... }>* @"$S1g5StoneVMn", i32 0, i32 8, i32 16, [4 x i8] zeroinitializer }>, align 8 9
  5. @"$S1g5StoneVMf" = <{ i8** getelementptr inbounds ( @"$S1g5StoneVWV", i32 0,

    i32 0), i64 0x200, <{ ... }>* @"$S1g5StoneVMn", i32 0, i32 8, i32 16, [4 x i8] zeroinitializer }>, align 8 10
  6. @"$S1g5StoneVMf" = <{ i8** getelementptr inbounds ( @"$S1g5StoneVWV", i32 0,

    i32 0), i64 0x200, <{ ... }>* @"$S1g5StoneVMn", i32 0, i32 8, i32 16, [4 x i8] zeroinitializer }>, align 8 11
  7. class Cat { var a: Int = 0 var b:

    Bool = false var c: String = "" } 12
  8. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 13
  9. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 14
  10. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 15
  11. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 16
  12. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 17
  13. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 18
  14. @"$S1g3CatCMf" = <{ void (%T1g3CatC*)* @"$S1g3CatCfD", i8** @"$SBoWV", i64 ptrtoint

    (%objc_class* @"$S1g3CatCMm" to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ ... }* @_DATA__TtC1g3Cat to i64), i64 1), i32 3, i32 0, i32 48, i16 7, i16 0, i32 200, i32 16, <{ ... }>* @"$S1g3CatCMn", i8* null, i64 (%T1g3CatC*)* @"$S1g3CatC1aSivg", void (i64, %T1g3CatC*)* @"$S1g3CatC1aSivs", { i8*, %TSi* } (i8*, %T1g3CatC*)* @"$S1g3CatC1aSivM", i1 (%T1g3CatC*)* @"$S1g3CatC1bSbvg", void (i1, %T1g3CatC*)* @"$S1g3CatC1bSbvs", { i8*, %TSb* } (i8*, %T1g3CatC*)* @"$S1g3CatC1bSbvM", { %swift.bridge*, i64 } (%T1g3CatC*)* @"$S1g3CatC1cSSvg", void (%swift.bridge*, i64, %T1g3CatC*)* @"$S1g3CatC1cSSvs", { i8*, %TSS* } (i8*, %T1g3CatC*)* @"$S1g3CatC1cSSvM", %T1g3CatC* (%T1g3CatC*)* @"$S1g3CatCACycfc", i64 16, i64 24, i64 32 }>, align 8 19
  15. RefBox<T>ͷϝλλΠϓ [-2] destroy [-1] VWT (SBoWV) [ 0] isa pointer:

    %objc_class* [ 1] super: %objc_class* [ 2] %swift.opaque* [ 3] %swift.opaque* [ 4] i64 [ 5] i32, i32 [ 6] i32, i16, i16 [ 7] i32, i32 [ 8] Nominal Type Descriptor [ 9] i8* [10] T: %swift.type* -- Generic Argument Vector [11] value.getter -- VTable [12] value.setter [13] value.modify [14] init(value: T) [15] i32 16 -- Field Offset Vector 23
  16. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 24
  17. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 25
  18. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 26
  19. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 27
  20. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 28
  21. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 29
  22. define hidden swiftcc void @"$S1g6RefBoxC5valuexvg"(%swift.opaque* noalias nocapture sret, %T1g6RefBoxC* swiftself)

    #0 { entry: %access-scratch = alloca [24 x i8], align 8 %2 = bitcast %T1g6RefBoxC* %1 to %swift.type** %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1g6RefBoxC, %T1g6RefBoxC* %1, i32 0, i32 0, i32 0 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = bitcast %swift.type* %5 to i64* %7 = getelementptr inbounds i64, i64* %6, i64 15 %8 = load i64, i64* %7, align 8, !invariant.load !33 %9 = bitcast %T1g6RefBoxC* %1 to i8* %10 = getelementptr inbounds i8, i8* %9, i64 %8 %.value = bitcast i8* %10 to %swift.opaque* %11 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* %11) %12 = bitcast %swift.opaque* %.value to i8* call void @swift_beginAccess(i8* %12, [24 x i8]* %access-scratch, i64 32, i8* null) #2 %13 = bitcast %swift.type* %3 to %swift.type** %14 = getelementptr inbounds %swift.type*, %swift.type** %13, i64 10 %T = load %swift.type*, %swift.type** %14, align 8, !invariant.load !33 %15 = bitcast %swift.type* %T to i8*** %16 = getelementptr inbounds i8**, i8*** %15, i64 -1 %T.valueWitnesses = load i8**, i8*** %16, align 8, !invariant.load !33, !dereferenceable !34 %17 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 2 %18 = load i8*, i8** %17, align 8, !invariant.load !33 %initializeWithCopy = bitcast i8* %18 to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* %19 = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %.value, %swift.type* %T) #2 call void @swift_endAccess([24 x i8]* %access-scratch) #2 %20 = bitcast [24 x i8]* %access-scratch to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 30
  23. ϝλλΠϓͱNTD ϝλλΠϓ͸ίϯΫϦʔτͳܕ͝ͱʹଘࡏ for Stone, Cat, RefBox<Int>, RefBox<String>, ... NTD͸ͦͷఆٛ͝ͱʹଘࡏ for

    Stone, Cat, RefBox, ... ↓ δΣωϦοΫͳ৔߹, NTDͷ৘ใ͔ΒϝλλΠϓ Λ࣮ߦ࣌ʹੜ੒ 31
  24. Metadata Accessor define hidden swiftcc %swift.metadata_response @"$S1g6RefBoxCMa"(i64, %swift.type*) %0: ϦΫΤετ

    %1: ύϥϝʔλܕͷϝλλΠϓ ϝλλΠϓΛฦ͢ ಺෦Ͱ swift_getGenericMetadata ΛݺͿ 32
  25. swift_getGenericMetadata MetadataResponse swift_getGenericMetadata( MetadataRequest request, const void * const *arguments,

    const TypeContextDescriptor *description); request: ϦΫΤετ arguments: ύϥϝʔλܕͷϝλλΠϓͷ഑ྻ description: Nominal Type Descriptor ϝλλΠϓΛฦ͢ 33
  26. Generic Metadata Instantiation Function define internal %swift.type* @"$S1g6RefBoxCMi"(%swift.type_descriptor*, i8**, i8*)

    %0: NTD %1: ύϥϝʔλܕͷϝλλΠϓͷ഑ྻ %2: Generic Metadata Pattern ߏங్தͷϝλλΠϓΛฦ͢ ಺෦Ͱ swift_allocateGenericClassMetadata ΛݺͿ 36
  27. swift_allocateGenericClassMetadata ClassMetadata * swift_allocateGenericClassMetadata( const ClassDescriptor *description, const void *arguments,

    const GenericClassMetadataPattern *pattern); description: NTD arguments: ύϥϝʔλܕͷϝλλΠϓͷ഑ྻ pattern: Generic Metadata Pattern ߏங్தͷϝλλΠϓΛฦ͢ 37
  28. Generic Metadata Completion Function define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>",

    i8*, i8**) %0: ߏஙதͷϝλλΠϓ %1: ύϥϝʔλܕͷϝλλΠϓͷ഑ྻ %2: Generic Metadata Pattern ϝλλΠϓΛฦ͢ ಺෦Ͱ swift_initClassMetadata ΛݺͿ 38
  29. swift_initClassMetadata void swift_initClassMetadata(ClassMetadata *self, ClassMetadata *super, ClassLayoutFlags flags, size_t numFields,

    const TypeLayout * const *fieldTypes, size_t *fieldOffsets); fieldTypes: ϑΟʔϧυͷܕͷ৘ใ fieldOffsets: Field Offset Vector 39
  30. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 41
  31. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 42
  32. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 43
  33. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 44
  34. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 45
  35. define internal swiftcc %swift.metadata_response @"$S1g6RefBoxCMr"(%swift.type* %"RefBox<T>", i8*, i8**) #0 {

    entry: %classFields = alloca [1 x i8**], align 8 %T1 = alloca %swift.type*, align 8 %2 = bitcast %swift.type* %"RefBox<T>" to i64* %3 = getelementptr inbounds i64, i64* %2, i64 15 %4 = bitcast [1 x i8**]* %classFields to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %4) %5 = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 %6 = bitcast %swift.type* %"RefBox<T>" to %swift.type** %7 = getelementptr inbounds %swift.type*, %swift.type** %6, i64 10 %T = load %swift.type*, %swift.type** %7, align 8, !invariant.load !33 %8 = call swiftcc %swift.metadata_response @swift_checkMetadataState(i64 319, %swift.type* %T) %9 = extractvalue %swift.metadata_response %8, 0 %10 = extractvalue %swift.metadata_response %8, 1 %11 = icmp ule i64 %10, 63 br i1 %11, label %dependency-satisfied, label %metadata-dependencies.cont dependency-satisfied: ; preds = %entry store %swift.type* %9, %swift.type** %T1, align 8 %12 = bitcast %swift.type* %9 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses = load i8**, i8*** %13, align 8, !invariant.load !33, !dereferenceable !34 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 8 %15 = getelementptr inbounds i8**, i8*** %5, i32 0 store i8** %14, i8*** %15, align 8 call void @swift_initClassMetadata(%swift.type* %"RefBox<T>", %swift.type* null, i64 0, i64 1, i8*** %5, i64* %3) %16 = bitcast i8*** %5 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) br label %metadata-dependencies.cont metadata-dependencies.cont: ; preds = %dependency-satisfied, %entry %17 = phi %swift.type* [ %9, %entry ], [ null, %dependency-satisfied ] %18 = phi i64 [ 63, %entry ], [ 0, %dependency-satisfied ] %19 = insertvalue %swift.metadata_response undef, %swift.type* %17, 0 %20 = insertvalue %swift.metadata_response %19, i64 %18, 1 ret %swift.metadata_response %20 } 46
  36. উखʹ࢖͏ͨΊͷϋʔυΩϟετ static GenericMetadataCache &getCache( const TypeGenericContextDescriptorHeader &generics) { // Keep

    this assert even if you change the representation above. static_assert(sizeof(LazyGenericMetadataCache) <= sizeof(GenericMetadataInstantiationCache::PrivateData), "metadata cache is larger than the allowed space"); auto lazyCache = reinterpret_cast<LazyGenericMetadataCache*>( generics.getInstantiationCache()->PrivateData); return lazyCache->get(); } 52
  37. ·ͱΊ • δΣωϦοΫܕͷϨΠΞ΢τ͸ίϯΫϦʔτͳ ܕ͝ͱʹ࡞ΒΕΔ • δΣωϦοΫܕͷϝλλΠϓ͸ Metadata Accessor ʹΑΓ lazy

    ʹੜ੒͞ΕΔ • ੜ੒ʹ͓͍ͯ͸ɺ Nominal Type Descriptor, Metadata Pattern, ϥϯλΠϜؔ਺͕࢖ΘΕΔ 53