Skip to content

Commit f6abffc

Browse files
committed
[IRGen] Stop registering protocol property accessors twice in JIT mode
We visited them twice, which led to registering them twice. Add a test for this feature so that we don't regress on this or on the use of non-extended types in the future (see previous commits).
1 parent c34fe93 commit f6abffc

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ class ObjCProtocolInitializerVisitor
388388
void visitMissingMemberDecl(MissingMemberDecl *placeholder) {}
389389

390390
void visitAbstractFunctionDecl(AbstractFunctionDecl *method) {
391+
if (isa<AccessorDecl>(method)) {
392+
// Accessors are handled as part of their AbstractStorageDecls.
393+
return;
394+
}
395+
391396
llvm::Constant *name, *imp, *types;
392397
emitObjCMethodDescriptorParts(IGM, method, /*concrete*/false,
393398
name, types, imp);

test/IRGen/objc_protocol_extended_method_types.swift

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %build-irgen-test-overlays
33
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir | %FileCheck %s
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir -use-jit | %FileCheck -check-prefix=CHECK-JIT %s
45

5-
// REQUIRES: CPU=x86_64
6+
// REQUIRES: OS=macosx
67
// REQUIRES: objc_interop
78

89
import Foundation
910

11+
// CHECK-JIT-DAG: [[PROTOCOL_NAME:@.+]] = private unnamed_addr constant [45 x i8] c"_TtP35objc_protocol_extended_method_types1P_\00"
12+
13+
1014
// CHECK-DAG: [[INIT:@.*]] = private unnamed_addr constant [8 x i8] c"@16@0:8\00"
1115
// CHECK-DAG: [[NSNUMBER:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSNumber\2224@0:8@\22NSNumber\2216\00"
1216
// CHECK-DAG: [[NSMUTABLEARRAY_GET:@.*]] = private unnamed_addr constant [24 x i8] c"@\22NSMutableArray\2216@0:8\00"
@@ -16,6 +20,12 @@ import Foundation
1620
// CHECK-DAG: [[NSOBJECT:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSObject\2224@0:8@\22NSObject\2216\00"
1721
// CHECK-DAG: [[NSMUTABLESTRING:@.*]] = private unnamed_addr constant [28 x i8] c"v24@0:8@\22NSMutableString\2216\00"
1822

23+
// The JIT registration logic doesn't use extended types.
24+
// CHECK-JIT-DAG: [[TY_ID_ID:@.*]] = private unnamed_addr constant [11 x i8] c"@24@0:8@16\00"
25+
// CHECK-JIT-DAG: [[TY_VOID_ID:@.*]] = private unnamed_addr constant [11 x i8] c"v24@0:8@16\00"
26+
// CHECK-JIT-DAG: [[TY_ID:@.*]] = private unnamed_addr constant [8 x i8] c"@16@0:8\00"
27+
// CHECK-JIT-DAG: [[TY_INT_INT:@.*]] = private unnamed_addr constant [11 x i8] c"q24@0:8q16\00"
28+
1929
// CHECK-LABEL: @_PROTOCOL_METHOD_TYPES__TtP35objc_protocol_extended_method_types1P_ = private constant [16 x i8*] [
2030
// -- required instance methods:
2131
// -- requiredInstanceMethod
@@ -75,3 +85,81 @@ import Foundation
7585
init()
7686
}
7787

88+
print(P.self)
89+
90+
// CHECK-JIT-LABEL: define private void @runtime_registration
91+
// CHECK-JIT: [[EXISTING_PROTOCOL:%.+]] = call %swift.protocol* @objc_getProtocol(i8* getelementptr inbounds ([45 x i8], [45 x i8]* [[PROTOCOL_NAME]], i64 0, i64 0))
92+
// CHECK-JIT: [[EXISTS:%.+]] = icmp eq %swift.protocol* [[EXISTING_PROTOCOL]], null
93+
// CHECK-JIT: br i1 [[EXISTS]], label %[[NEW_PROTOCOL_LABEL:[^ ]+]], label %[[EXISTING_PROTOCOL_LABEL:[^ ]+]]
94+
95+
// CHECK-JIT: [[EXISTING_PROTOCOL_LABEL]]:
96+
// CHECK-JIT: br label %[[FINISH_LABEL:[^ ]+]]
97+
98+
// CHECK-JIT: [[NEW_PROTOCOL_LABEL]]:
99+
// CHECK-JIT: [[NEW_PROTOCOL:%.+]] = call %swift.protocol* @objc_allocateProtocol(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @2, i64 0, i64 0))
100+
// -- requiredInstanceMethod:
101+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod:)", i64 0, i64 0))
102+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1)
103+
// -- optionalInstanceMethod:
104+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod:)", i64 0, i64 0))
105+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1)
106+
// -- requiredClassMethod:
107+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod:)", i64 0, i64 0))
108+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0)
109+
// -- optionalClassMethod:
110+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod:)", i64 0, i64 0))
111+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0)
112+
// -- requiredInstanceProperty
113+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty)", i64 0, i64 0))
114+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
115+
116+
// Make sure we don't emit storage accessors multiple times.
117+
// CHECK-JIT-NOT: requiredInstanceProperty
118+
119+
// -- setRequiredInstanceProperty:
120+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty:)", i64 0, i64 0))
121+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1)
122+
123+
// Make sure we don't emit storage accessors multiple times.
124+
// CHECK-JIT-NOT: requiredInstanceProperty
125+
// CHECK-JIT-NOT: setRequiredInstanceProperty
126+
127+
// -- requiredROInstanceProperty
128+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty)", i64 0, i64 0))
129+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
130+
// -- requiredInstanceMethod2:
131+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod2:)", i64 0, i64 0))
132+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1)
133+
// -- optionalInstanceMethod2:
134+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod2:)", i64 0, i64 0))
135+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1)
136+
// -- requiredClassMethod2:
137+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod2:)", i64 0, i64 0))
138+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0)
139+
// -- optionalClassMethod2:
140+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod2:)", i64 0, i64 0))
141+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0)
142+
// -- requiredInstanceProperty2
143+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty2)", i64 0, i64 0))
144+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
145+
// -- setRequiredInstanceProperty2:
146+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty2:)", i64 0, i64 0))
147+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1)
148+
// -- requiredROInstanceProperty2
149+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty2)", i64 0, i64 0))
150+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
151+
// -- objectAtIndexedSubscript:
152+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(objectAtIndexedSubscript:)", i64 0, i64 0))
153+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_INT_INT]], i64 0, i64 0), i8 1, i8 1)
154+
// -- init
155+
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(init)", i64 0, i64 0))
156+
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
157+
// CHECK-JIT: call void @objc_registerProtocol(%swift.protocol* [[NEW_PROTOCOL]])
158+
// CHECK-JIT: br label %[[FINISH_LABEL]]
159+
160+
// CHECK-JIT: [[FINISH_LABEL]]:
161+
// CHECK-JIT: [[RESOLVED_PROTOCOL:%.+]] = phi %swift.protocol* [ [[EXISTING_PROTOCOL]], %[[EXISTING_PROTOCOL_LABEL]] ], [ [[NEW_PROTOCOL]], %[[NEW_PROTOCOL_LABEL]] ]{{$}}
162+
// CHECK-JIT: store %swift.protocol* [[RESOLVED_PROTOCOL]], %swift.protocol** bitcast (i8** @"\01l_OBJC_PROTOCOL_REFERENCE_$__TtP35objc_protocol_extended_method_types1P_" to %swift.protocol**), align 8
163+
// CHECK-JIT: ret void
164+
// CHECK-JIT-NEXT: {{^}$}}
165+

0 commit comments

Comments
 (0)