Skip to content

Commit e19f40a

Browse files
committed
Use getMetadataLayout offset instead of manual gep
1 parent 46bc50d commit e19f40a

File tree

4 files changed

+54
-70
lines changed

4 files changed

+54
-70
lines changed

lib/IRGen/GenStruct.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -413,17 +413,11 @@ namespace {
413413
}
414414

415415
llvm::Value *getOffsetForIndex(IRGenFunction &IGF, unsigned index) override {
416-
// TODO: do this with StructMetadataLayout::getFieldOffset
417-
418-
// Get the field offset vector from the struct metadata.
419-
llvm::Value *metadata = IGF.emitTypeMetadataRefForLayout(TheStruct);
420-
Address fieldVector = emitAddressOfFieldOffsetVector(IGF, metadata,
421-
TheStruct.getStructOrBoundGenericStruct());
422-
423-
// Grab the indexed offset.
424-
fieldVector = IGF.Builder.CreateConstArrayGEP(fieldVector, index,
425-
IGF.IGM.getPointerSize());
426-
return IGF.Builder.CreateLoad(fieldVector);
416+
auto &structLayout =
417+
IGF.IGM.getMetadataLayout(TheStruct.getStructOrBoundGenericStruct());
418+
auto offset =
419+
structLayout.getFieldOffsetVectorOffset().offsetBy(IGF, Size(index));
420+
return offset.getAsValue(IGF);
427421
}
428422

429423
MemberAccessStrategy getFieldAccessStrategy(IRGenModule &IGM,

test/IRGen/generic_structs.sil

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -157,34 +157,29 @@ struct ComplexDynamic<U, V> {
157157
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @explode_complex_dynamic
158158
sil @explode_complex_dynamic : $<A, B> (@in ComplexDynamic<A, B>, @inout Byteful, @inout A, @inout B, @inout Chareth) -> () {
159159
entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Chareth):
160-
%a = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.a2
160+
// CHECK: [[A:%.*]] = getelementptr inbounds %T15generic_structs14ComplexDynamicV, %T15generic_structs14ComplexDynamicV* %0
161+
// CHECK: [[PTR1:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0
162+
// CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i8, i8* [[PTR1]]
163+
// CHECK-NEXT: [[B:%.*]] = bitcast i8* [[EL]] to %swift.opaque*
161164

162-
// CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32*
163-
// CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 8
164-
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[FIELD_OFFSET_VECTOR]], i32 2
165-
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8
166-
// CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
167-
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]]
168-
// CHECK: bitcast i8* [[BYTE_OFFSET]] to %swift.opaque*
165+
%a = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.a2
169166
%b = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.b
170-
171-
// CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32*
172-
// CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 8
173-
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[FIELD_OFFSET_VECTOR]], i32 3
174-
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8
175-
// CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
176-
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]]
177-
// CHECK: bitcast i8* [[BYTE_OFFSET]] to %T15generic_structs13SingleDynamicV
167+
168+
// CHECK: [[PTR2:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0
169+
// CHECK-NEXT: [[C_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR2]], i64 35
170+
// CHECK-NEXT: [[C:%.*]] = bitcast i8* [[C_PTR]] to %T15generic_structs13SingleDynamicV*
171+
// CHECK-NEXT: [[C_X:%.*]] = bitcast %T15generic_structs13SingleDynamicV* [[C]] to %swift.opaque*
172+
173+
// CHECK: [[PTR3:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0
174+
// CHECK-NEXT: [[D_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR3]], i64 36
175+
// CHECK-NEXT: [[D:%.*]] = bitcast i8* [[D_PTR]] to %T15generic_structs7CharethV*
176+
177+
// CHECK: call %T15generic_structs7BytefulV* @"$s15generic_structs7BytefulVWOf"(%T15generic_structs7BytefulV* [[A]], %T15generic_structs7BytefulV* %1)
178+
// CHECK: call %swift.opaque* %assignWithCopy(%swift.opaque* %2, %swift.opaque* [[B]], %swift.type* %A)
179+
// CHECK: call %swift.opaque* %assignWithCopy3(%swift.opaque* %3, %swift.opaque* [[C_X]], %swift.type* %B)
180+
// CHECK: call %T15generic_structs7CharethV* @"$s15generic_structs7CharethVWOf"(%T15generic_structs7CharethV* [[D]], %T15generic_structs7CharethV* %4)
178181
%5 = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.c
179182
%c = struct_element_addr %5 : $*SingleDynamic<B>, #SingleDynamic.x
180-
181-
// CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32*
182-
// CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 8
183-
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[FIELD_OFFSET_VECTOR]], i32 4
184-
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8
185-
// CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
186-
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]]
187-
// CHECK: bitcast i8* [[BYTE_OFFSET]] to %T15generic_structs7CharethV
188183
%d = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.d
189184
copy_addr %a to %1 : $*Byteful
190185
copy_addr %b to %2 : $*A

test/IRGen/generic_structs.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,19 @@ public struct GenericStruct<T : Proto> {
3939
}
4040

4141
// CHECK-LABEL: define{{.*}} swiftcc void @"$s15generic_structs13GenericStructVACyxGycfC"
42-
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s15generic_structs13GenericStructVMa"([[INT]] 0, %swift.type* %T, i8** %T.Proto)
43-
// CHECK: [[TYPE:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
44-
// CHECK: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to [[INT_32]]*
45-
// CHECK: [[FIELDOFFSETS:%.*]] = getelementptr inbounds [[INT_32]], [[INT_32]]* [[PTR]], [[INT]] [[IDX:4|8]]
46-
// CHECK: [[FIELDOFFSET:%.*]] = getelementptr inbounds [[INT_32]], [[INT_32]]* [[FIELDOFFSETS]], i32 2
47-
// CHECK: [[OFFSET:%.*]] = load [[INT_32]], [[INT_32]]* [[FIELDOFFSET]]
48-
// CHECK: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, [[INT_32]] [[OFFSET]]
49-
// CHECK: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
50-
// CHECK: call %TSq* @"$sxSg15generic_structs5ProtoRzlWOb"(%TSq* {{.*}}, %TSq* [[OPTPTR]]
42+
// CHECK: [[VTABLE:%.*]] = bitcast i8** %.valueWitnesses to %swift.vwtable*
43+
// CHECK-NEXT: [[SIZE_PTR:%.*]] = getelementptr inbounds %swift.vwtable, %swift.vwtable* [[VTABLE]]
44+
// CHECK-NEXT: [[SIZE:%.*]] = load i64, i64* [[SIZE_PTR]]
45+
// CHECK-NEXT: [[EMPTY_PTR:%.*]] = alloca i8, i64 [[SIZE]]
46+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8({{.*}} [[EMPTY_PTR]])
47+
// CHECK-NEXT: [[EMPTY:%.*]] = bitcast i8* [[EMPTY_PTR]] to %TSq*
48+
49+
// CHECK: [[SELF_PTR:%.*]] = bitcast i8* %self to %T15generic_structs13GenericStructV*
50+
51+
// CHECK: [[SELF_RAW_PTR:%.*]] = bitcast %T15generic_structs13GenericStructV* [[SELF_PTR]] to i8*
52+
// CHECK-NEXT: [[OPT_PTR:%.*]] = getelementptr inbounds i8, i8* [[SELF_RAW_PTR]]
53+
// CHECK-NEXT: [[OPTIONAL:%.*]] = bitcast i8* [[OPT_PTR]] to %TSq*
54+
// CHECK-NEXT: [[METADATA:%.*]] = call swiftcc %swift.metadata_response @"$sSqMa"(i64 0, %swift.type* %T)
55+
// CHECK-NEXT: [[META_VAL:%.*]] = extractvalue %swift.metadata_response [[METADATA]], 0
56+
// CHECK: %26 = call %TSq* @"$sxSg15generic_structs5ProtoRzlWOb"(%TSq* [[EMPTY]], %TSq* [[OPTIONAL]]
57+
// CHECK: %27 = call %T15generic_structs13GenericStructV* @"$s15generic_structs13GenericStructVyxGAA5ProtoRzlWOb"(%T15generic_structs13GenericStructV* [[SELF_PTR]], %T15generic_structs13GenericStructV* %0

test/IRGen/struct_resilience.swift

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,14 @@ public func functionWithResilientTypesSize(_ s: __owned Size, f: (__owned Size)
6060
// Make sure we use a type metadata accessor function, and load indirect
6161
// field offsets from it.
6262

63-
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s17struct_resilience35functionWithResilientTypesRectangleyy010resilient_A00G0VF"(%T16resilient_struct9RectangleV* noalias nocapture)
63+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s17struct_resilience35functionWithResilientTypesRectangleyy010resilient_A00G0VF"
6464
public func functionWithResilientTypesRectangle(_ r: Rectangle) {
65-
// CHECK: entry:
66-
// CHECK-NEXT: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s16resilient_struct9RectangleVMa"([[INT]] 0)
67-
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
68-
// CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to i32*
69-
// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i32, i32* [[METADATA_ADDR]], [[INT]] [[IDX:2|4]]
70-
// CHECK-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds i32, i32* [[FIELD_OFFSET_VECTOR]], i32 2
71-
// CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_PTR]]
72-
// CHECK-NEXT: [[STRUCT_ADDR:%.*]] = bitcast %T16resilient_struct9RectangleV* %0 to i8*
73-
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[STRUCT_ADDR]], i32 [[FIELD_OFFSET]]
74-
// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %TSi*
75-
// CHECK-NEXT: [[FIELD_PAYLOAD_PTR:%.*]] = getelementptr inbounds %TSi, %TSi* [[FIELD_PTR]], i32 0, i32 0
76-
// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = load [[INT]], [[INT]]* [[FIELD_PAYLOAD_PTR]]
77-
65+
// CHECK: entry:
66+
// CHECK-NEXT: [[PTR:%.*]] = bitcast %T16resilient_struct9RectangleV* %0
67+
// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds {{.*}} [[PTR]]
68+
// CHECK-NEXT: [[COLOR_PTR:%.*]] = bitcast {{.*}} [[E]]
69+
// CHECK-NEXT: [[COLOR_VAL:%.*]] = getelementptr inbounds %TSi, %TSi* [[COLOR_PTR]]
70+
// CHECK-NEXT: [[COLOR:%.*]] = load {{.*}} [[COLOR_VAL]]
7871
_ = r.color
7972

8073
// CHECK-NEXT: ret void
@@ -145,18 +138,13 @@ public struct StructWithResilientStorage {
145138
// metadata when accessing stored properties.
146139

147140
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc {{i32|i64}} @"$s17struct_resilience26StructWithResilientStorageV1nSivg"(%T17struct_resilience26StructWithResilientStorageV* {{.*}})
148-
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s17struct_resilience26StructWithResilientStorageVMa"([[INT]] 0)
149-
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
150-
// CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to i32*
151-
// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i32, i32* [[METADATA_ADDR]], [[INT]] [[IDX:2|4]]
152-
// CHECK-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds i32, i32* [[FIELD_OFFSET_VECTOR]], i32 2
153-
// CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_PTR]]
154-
// CHECK-NEXT: [[STRUCT_ADDR:%.*]] = bitcast %T17struct_resilience26StructWithResilientStorageV* %0 to i8*
155-
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[STRUCT_ADDR]], i32 [[FIELD_OFFSET]]
156-
// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %TSi*
157-
// CHECK-NEXT: [[FIELD_PAYLOAD_PTR:%.*]] = getelementptr inbounds %TSi, %TSi* [[FIELD_PTR]], i32 0, i32 0
158-
// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = load [[INT]], [[INT]]* [[FIELD_PAYLOAD_PTR]]
159-
// CHECK-NEXT: ret [[INT]] [[FIELD_PAYLOAD]]
141+
// CHECK: entry:
142+
// CHECK-NEXT: [[PTR:%.*]] = bitcast %T17struct_resilience26StructWithResilientStorageV* %0
143+
// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds {{.*}} [[PTR]]
144+
// CHECK-NEXT: [[N:%.*]] = bitcast {{.*}} [[E]]
145+
// CHECK-NEXT: [[N_VAL_PTR:%.*]] = getelementptr inbounds %TSi, %TSi* [[N]]
146+
// CHECK-NEXT: [[N_VAL:%.*]] = load [[INT]], [[INT]]* [[N_VAL_PTR]]
147+
// CHECK-NEXT: ret [[INT]] [[N_VAL]]
160148

161149

162150
// Indirect enums with resilient payloads are still fixed-size.

0 commit comments

Comments
 (0)