1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
// RUN: %empty-directory(%t)
// RUN: %{python} %utils/chex.py < %s > %t/generic_structs.sil
// RUN: %target-swift-frontend -disable-type-layout -disable-generic-metadata-prespecialization %t/generic_structs.sil -emit-ir | %FileCheck %t/generic_structs.sil
// REQUIRES: CPU=x86_64
import Builtin
// -- Generic structs with fixed layout should have no completion function
// and emit the field offset vector as part of the pattern.
// CHECK: [[PATTERN:@.*]] = internal constant <{ i32, i32, i32, [4 x i8] }> <{ i32 0, i32 1, i32 8, [4 x i8] zeroinitializer }>, align 8
// CHECK-LABEL: @"$s15generic_structs18FixedLayoutGenericVMP" = internal constant <{ {{.*}} }> <{
// -- instantiation function
// CHECK-SAME: ptr @"$s15generic_structs18FixedLayoutGenericVMi"
// -- completion function
// CHECK-SAME: i32 0,
// -- pattern flags
// CHECK-SAME: <i32 0x4000_0001>,
// -- vwtable pointer
// CHECK-SAME: @"$s15generic_structs18FixedLayoutGenericVWV"
// -- extra data pattern
// CHECK-SAME: ptr [[PATTERN]]
// CHECK-SAME: i16 1,
// CHECK-SAME: i16 2 }>
// -- Generic structs with dynamic layout contain the vwtable pattern as part
// of the metadata pattern, and no independent vwtable symbol
// CHECK: @"$s15generic_structs13SingleDynamicVWV" = internal constant
// CHECK-SAME: ptr @"$s15generic_structs13SingleDynamicVwCP",
// -- ...
// -- placeholder for size, stride, flags
// CHECK-SAME: i64 0,
// CHECK-SAME: i64 0,
// CHECK-SAME: i32 4194304,
// CHECK-SAME: i32 0 }
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
// CHECK: [[SINGLEDYNAMIC_NAME:@.*]] = private constant [14 x i8] c"SingleDynamic\00"
// CHECK: @"$s15generic_structs13SingleDynamicVMn" = hidden constant
// -- flags: struct, unique, generic
// CHECK-SAME: <i32 0x0000_00D1>
// -- name
// CHECK-SAME: ptr [[SINGLEDYNAMIC_NAME]]
// -- field count
// CHECK-SAME: i32 1,
// -- field offset vector offset
// CHECK-SAME: i32 3,
// -- generic instantiation info
// CHECK-SAME: ptr @"$s15generic_structs13SingleDynamicVMI"
// CHECK-SAME: @"$s15generic_structs13SingleDynamicVMP"
// -- generic params, requirements, key args, extra args
// CHECK-SAME: i16 1, i16 0, i16 1, i16 0
// -- generic parameters
// CHECK-SAME: <i8 0x80>
// CHECK-SAME: }>
// CHECK: @"$s15generic_structs13SingleDynamicVMP" = internal constant <{ {{.*}} }> <{
// -- instantiation function
// CHECK-SAME: ptr @"$s15generic_structs13SingleDynamicVMi"
// -- vwtable pointer
// CHECK-SAME: @"$s15generic_structs13SingleDynamicVWV"
// -- Nominal type descriptor for generic struct with protocol requirements
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
// CHECK: [[DYNAMICWITHREQUIREMENTS_NAME:@.*]] = private constant [24 x i8] c"DynamicWithRequirements\00"
// CHECK: @"$s15generic_structs23DynamicWithRequirementsVMn" = hidden constant <{ {{.*}} i32 }> <{
// -- flags: struct, unique, generic
// CHECK-SAME: <i32 0x0000_00D1>
// -- name
// CHECK-SAME: ptr [[DYNAMICWITHREQUIREMENTS_NAME]]
// -- field count
// CHECK-SAME: i32 2,
// -- field offset vector offset
// CHECK-SAME: i32 6,
// -- generic params, requirements, key args, extra args
// CHECK-SAME: i16 2, i16 2, i16 4, i16 0,
// -- generic parameters
// CHECK-SAME: <i8 0x80>, <i8 0x80>,
// -- generic requirement
// -- protocol requirement with key arg
// CHECK-SAME: i32 128
// -- param 0
// CHECK-SAME: i32 0
// -- protocol Req1
// CHECK-SAME: @"$s15generic_structs4Req1Mp"
// -- protocol requirement with key arg
// CHECK-SAME: i32 128
// -- param 1
// CHECK-SAME: i32 2
// -- protocol Req2
// CHECK-SAME: @"$s15generic_structs4Req2Mp"
// CHECK-SAME: }>
// CHECK: @"$s15generic_structs23DynamicWithRequirementsVMP" = internal constant <{ {{.*}} }> <{
// -- Fixed-layout struct metadata contains fixed field offsets
// CHECK: @"$s15generic_structs6IntishVMf" = internal constant <{ {{.*}} i32, [4 x i8] }> <{
// CHECK-SAME: i32 0
// CHECK-SAME: }>
// CHECK: @"$s15generic_structs7CharethVMf" = internal constant <{ {{.*}} i32, [4 x i8] }> <{
// CHECK-SAME: i32 0
// CHECK-SAME: }>
// CHECK: @"$s15generic_structs8StringlyVMf" = internal constant <{ {{.*}} i32, i32, i32, [4 x i8] }> <{
// CHECK-SAME: i32 0, i32 8, i32 16, [4 x i8] zeroinitializer
// CHECK-SAME: }>
struct FixedLayoutGeneric<T> {
var x: Byteful
var y: Byteful
var z: Intish
}
struct SingleDynamic<T> {
var x : T
}
protocol Req1 { associatedtype Assoc1 }
protocol Req2 {}
struct DynamicWithRequirements<T: Req1, U: Req2> {
var x : T
var y : U
}
struct Intish { var value : Builtin.Int64 }
struct Chareth { var value : Builtin.Int21 }
struct Byteful { var value : Builtin.Int8 }
struct Stringly {
var owner : Builtin.NativeObject
var base : Builtin.RawPointer
var size : Builtin.Int64
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i32 } @concrete_instances(i64 %0, i32 %1) {{.*}} {
// CHECK: entry:
// CHECK: %2 = trunc i32 %1 to i21
// CHECK: %3 = zext i21 %2 to i32
// CHECK: %4 = insertvalue { i64, i32 } undef, i64 %0, 0
// CHECK: %5 = insertvalue { i64, i32 } %4, i32 %3, 1
// CHECK: ret { i64, i32 } %5
// CHECK: }
sil @concrete_instances : $(SingleDynamic<Intish>, SingleDynamic<Chareth>) -> (Intish, Chareth) {
entry(%0 : $SingleDynamic<Intish>, %1 : $SingleDynamic<Chareth>):
%a = struct_extract %0 : $SingleDynamic<Intish>, #SingleDynamic.x
%b = struct_extract %1 : $SingleDynamic<Chareth>, #SingleDynamic.x
%c = tuple (%a : $Intish, %b : $Chareth)
return %c : $(Intish, Chareth)
}
struct ComplexDynamic<U, V> {
var a, a2 : Byteful
var b : U
var c : SingleDynamic<V>
var d : Chareth
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @explode_complex_dynamic
sil @explode_complex_dynamic : $<A, B> (@in ComplexDynamic<A, B>, @inout Byteful, @inout A, @inout B, @inout Chareth) -> () {
entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Chareth):
%a = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.a2
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 10
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
%b = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.b
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 11
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
%5 = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.c
%c = struct_element_addr %5 : $*SingleDynamic<B>, #SingleDynamic.x
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 12
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
%d = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.d
copy_addr %a to %1 : $*Byteful
copy_addr %b to %2 : $*A
copy_addr %c to %3 : $*B
copy_addr %d to %4 : $*Chareth
%v = tuple ()
return %v : $()
}
// CHECK-LABEL: define{{( protected)?}} internal ptr @"$s15generic_structs13SingleDynamicVMi"(ptr %0, ptr %1, ptr %2)
// CHECK: %T = load ptr, ptr %1, align 8
// CHECK: [[METADATA:%.*]] = call ptr @swift_allocateGenericValueMetadata(ptr %0, ptr %1, ptr %2, i64 16)
// CHECK-NEXT: ret ptr [[METADATA]]
// CHECK: }
// CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$s15generic_structs13SingleDynamicVMr"
// CHECK-SAME: (ptr [[METADATA:%.*]], ptr %0, ptr %1) {{.*}} {
// Lay out fields.
// CHECK: [[T1:%.*]] = getelementptr inbounds i32, ptr [[METADATA]], i64 6
// CHECK: [[T2:%.*]] = getelementptr inbounds ptr, ptr [[TYPES:%.*]], i32 0
// CHECK: call void @swift_initStructMetadata(ptr [[METADATA]], i64 0, i64 1, ptr [[TYPES]], ptr [[T1]])
// CHECK: ret %swift.metadata_response
// CHECK: }
// Check that we directly delegate buffer witnesses to a single dynamic field:
// initializeBufferWithCopyOfBuffer
// CHECK-LABEL: define internal ptr @"$s15generic_structs13SingleDynamicVwCP"(ptr noalias %dest, ptr noalias %src, ptr %"SingleDynamic<T>") {{.*}} {
// CHECK: %T = load ptr,
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %T, i64 -1
// CHECK-NEXT: %T.valueWitnesses = load ptr, ptr [[T1]]
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr %T.valueWitnesses,
// CHECK-NEXT: [[T0:%.*]] = call ptr [[T1]](ptr noalias %dest, ptr noalias %src, ptr %T)
// CHECK-NEXT: ret ptr [[T0]]
protocol HasAssociatedType {
associatedtype Assoc
}
protocol ParentHasAssociatedType : HasAssociatedType {
associatedtype Assoc : HasAssociatedType
}
struct GenericLayoutWithAssocType<T: ParentHasAssociatedType> {
var x: T.Assoc
var y: T.Assoc.Assoc
}
// CHECK-LABEL: define internal ptr @"$s15generic_structs26GenericLayoutWithAssocTypeVMi"(
// CHECK: %T = load ptr, ptr %1, align 8
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %1, i32 1
// CHECK: %T.ParentHasAssociatedType = load ptr, ptr [[T1]],
// CHECK: [[METADATA:%.*]] = call ptr @swift_allocateGenericValueMetadata
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s15generic_structs26GenericLayoutWithAssocTypeVMr"(
// CHECK: [[T0_GEP:%.*]] = getelementptr inbounds ptr, ptr %T.ParentHasAssociatedType, i32 1
// CHECK: [[T0:%.*]] = load ptr, ptr [[T0_GEP]]
// CHECK: [[T4:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, ptr %T.HasAssociatedType, ptr %T, ptr @"$s15generic_structs17HasAssociatedTypeTL", ptr @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
// CHECK: %T.Assoc = extractvalue %swift.metadata_response [[T4]], 0
// CHECK: %T.Assoc.HasAssociatedType = call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr %T.ParentHasAssociatedType, ptr %T, ptr %T.Assoc,
// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, ptr %T.Assoc.HasAssociatedType, ptr %T.Assoc, ptr @"$s15generic_structs17HasAssociatedTypeTL", ptr @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
// CHECK: %T.Assoc.Assoc = extractvalue %swift.metadata_response [[T2]], 0
|