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

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

omochimetaru
September 12, 2018

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

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