Skip to content

Commit 0572dd0

Browse files
committed
[ObjC] Expand isClassLayoutKnownStatically to base classes as long as the implementation of it is known
Only NSObject we can trust the layout of won't change even though we cannot directly see its @implementation.
1 parent 1e0e416 commit 0572dd0

16 files changed

+91
-53
lines changed

clang/lib/CodeGen/CGObjCMac.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,9 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
15561556
if (!ID->getImplementation())
15571557
return false;
15581558
}
1559-
return false;
1559+
1560+
// We know the layout of all the intermediate classes and superclasses.
1561+
return true;
15601562
}
15611563

15621564
public:

clang/test/CodeGenObjC/arc-blocks.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,16 +422,16 @@ @interface Test12
422422
@implementation Test12
423423
@synthesize ablock, nblock;
424424
// CHECK: define internal ptr @"\01-[Test12 ablock]"(
425-
// CHECK: call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, i1 noundef zeroext true)
425+
// CHECK: call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, i1 noundef zeroext true)
426426

427427
// CHECK: define internal void @"\01-[Test12 setAblock:]"(
428-
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
428+
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
429429

430430
// CHECK: define internal ptr @"\01-[Test12 nblock]"(
431-
// CHECK: %add.ptr = getelementptr inbounds i8, ptr %0, i64 %ivar
431+
// CHECK: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
432432

433433
// CHECK: define internal void @"\01-[Test12 setNblock:]"(
434-
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
434+
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 8, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
435435
@end
436436

437437
void test13(id x) {

clang/test/CodeGenObjC/arc-property.m

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,14 @@ @implementation Test1
2222
@end
2323
// The getter should be a simple load.
2424
// CHECK: define internal ptr @"\01-[Test1 pointer]"(
25-
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
26-
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 [[OFFSET]]
25+
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 0
2726
// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T1]], align 8
2827
// CHECK-NEXT: ret ptr [[T3]]
2928

3029
// The setter should be using objc_setProperty.
3130
// CHECK: define internal void @"\01-[Test1 setPointer:]"(
32-
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
33-
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
34-
// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext false, i1 noundef zeroext false)
31+
// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
32+
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext false)
3533
// CHECK-NEXT: ret void
3634

3735

@@ -52,26 +50,22 @@ - (void) test {
5250
// CHECK: define internal void @"\01-[Test2 test]"(
5351
// CHECK: [[T0:%.*]] = load ptr, ptr @theGlobalClass, align 8
5452
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr
55-
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
56-
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[OFFSET]]
53+
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
5754
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T3]], ptr [[T0]]) [[NUW:#[0-9]+]]
5855
// CHECK-NEXT: ret void
5956

6057
// CHECK: define internal ptr @"\01-[Test2 theClass]"(
61-
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
62-
// CHECK-NEXT: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef [[OFFSET]], i1 noundef zeroext true)
58+
// CHECK: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef 0, i1 noundef zeroext true)
6359
// CHECK-NEXT: ret ptr [[T0]]
6460

6561
// CHECK: define internal void @"\01-[Test2 setTheClass:]"(
66-
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
67-
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
68-
// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext true, i1 noundef zeroext true)
62+
// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
63+
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
6964
// CHECK-NEXT: ret void
7065

7166
// CHECK: define internal void @"\01-[Test2 .cxx_destruct]"(
7267
// CHECK: [[T0:%.*]] = load ptr, ptr
73-
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
74-
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[OFFSET]]
68+
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
7569
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T2]], ptr null) [[NUW]]
7670
// CHECK-NEXT: ret void
7771

clang/test/CodeGenObjC/arc-weak-property.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
22

3-
@interface WeakPropertyTest {
3+
@interface SuperClass
4+
@end
5+
6+
@interface WeakPropertyTest : SuperClass {
47
__weak id PROP;
58
}
69
@property () __weak id PROP;

clang/test/CodeGenObjC/arc.m

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,7 @@ @interface Test26 { id x[4]; } @end
577577
@implementation Test26 @end
578578
// CHECK: define internal void @"\01-[Test26 .cxx_destruct]"(
579579
// CHECK: [[SELF:%.*]] = load ptr, ptr
580-
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test26.x"
581-
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
580+
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
582581
// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x ptr], ptr [[T1]], i32 0, i32 0
583582
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 4
584583
// CHECK-NEXT: br label
@@ -616,8 +615,7 @@ @implementation Test28
616615
@end
617616
// CHECK: define internal void @"\01-[Test28 .cxx_destruct]"
618617
// CHECK: [[SELF:%.*]] = load ptr, ptr
619-
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test28.prop"
620-
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
618+
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
621619
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null)
622620
// CHECK-NEXT: ret void
623621

@@ -738,8 +736,7 @@ - (id) init {
738736

739737
// Assignment.
740738
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]]
741-
// CHECK-NEXT: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test30.helper"
742-
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[IVAR]]
739+
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
743740
// CHECK-NEXT#: [[T5:%.*]] = load ptr, ptr [[T3]]
744741
// CHECK-NEXT#: [[T6:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]])
745742
// CHECK-NEXT#: call void @llvm.objc.release(ptr [[T5]])
@@ -1137,23 +1134,20 @@ @implementation Test57
11371134
@end
11381135
// CHECK: define internal ptr @"\01-[Test57 strong]"(
11391136
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
1140-
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.strong"
1141-
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
1137+
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
11421138
// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
11431139
// CHECK-NEXT: ret ptr [[T5]]
11441140

11451141
// CHECK: define internal ptr @"\01-[Test57 weak]"(
11461142
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
1147-
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.weak"
1148-
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
1143+
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8
11491144
// CHECK-NEXT: [[T5:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T3]])
11501145
// CHECK-NEXT: [[T6:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T5]])
11511146
// CHECK-NEXT: ret ptr [[T6]]
11521147

11531148
// CHECK: define internal ptr @"\01-[Test57 unsafe]"(
11541149
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
1155-
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.unsafe"
1156-
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
1150+
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 16
11571151
// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
11581152
// CHECK-NEXT: ret ptr [[T5]]
11591153

clang/test/CodeGenObjC/arm64-int32-ivar.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
// CHECK: @"OBJC_IVAR_$_I.IVAR2" = global i32 8
44
// CHECK: @"OBJC_IVAR_$_I.IVAR1" = global i32 0
5-
@interface I
5+
@interface SuperClass
6+
@end
7+
8+
@interface I : SuperClass
69
{
710
id IVAR1;
811
id IVAR2;

clang/test/CodeGenObjC/bitfield-ivar-offsets.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
// RUN: grep -F '@"OBJC_IVAR_$_I0._b4" = global i64 7, section "__DATA, __objc_ivar", align 8' %t
99
// RUN: not grep -F '@"OBJC_IVAR_$_I0." = global' %t
1010

11-
@interface I0 {
11+
@interface SuperClass
12+
@end
13+
14+
@interface I0 : SuperClass {
1215
unsigned _b0:4;
1316
unsigned _b1:5;
1417
unsigned _b2:5;

clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden constant i64 48
99
// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = constant i64 56
1010
// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden constant i64 64
11+
12+
// CHECK: @"OBJC_IVAR_$_RootClass.these" = constant i64 0
13+
// CHECK: @"OBJC_IVAR_$_RootClass.never" = constant i64 4
14+
// CHECK: @"OBJC_IVAR_$_RootClass.change" = constant i64 8
15+
// CHECK: @"OBJC_IVAR_$_StillStaticLayout.static_layout_ivar" = hidden constant i64 12
16+
1117
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
1218
// CHECK: @"OBJC_IVAR_$_SuperClass2._superClassProperty2" = hidden constant i64 20
1319
// CHECK: @"OBJC_IVAR_$_IntermediateClass2._IntermediateClass2Property" = hidden constant i64 24
@@ -123,12 +129,34 @@ -(void)intermediateSubclassVar {
123129
// CHECK: getelementptr inbounds i8, ptr %1, i64 64
124130
@end
125131

126-
@interface NotNSObject {
127-
int these, might, change;
132+
__attribute((objc_root_class)) @interface RootClass {
133+
int these, never, change;
128134
}
129135
@end
130136

131-
@interface NotStaticLayout : NotNSObject
137+
@implementation RootClass
138+
@end
139+
140+
@interface StillStaticLayout : RootClass
141+
@end
142+
143+
@implementation StillStaticLayout {
144+
int static_layout_ivar;
145+
}
146+
147+
// CHECK-LABEL: define internal void @"\01-[StillStaticLayout meth]"
148+
-(void)meth {
149+
static_layout_ivar = 0;
150+
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$StillStaticLayout.static_layout_ivar
151+
}
152+
@end
153+
154+
@interface NotNSObject
155+
@end
156+
157+
@interface NotStaticLayout : NotNSObject {
158+
int these, might, change;
159+
}
132160
@end
133161

134162
@implementation NotStaticLayout {

clang/test/CodeGenObjC/direct-method.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,7 @@ - (void)accessCmd __attribute__((objc_direct)) {
167167
// CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(
168168
// CHECK-LABEL: objc_direct_method.cont:
169169
// CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,
170-
// CHECK-NEXT: [[IVAR:%.*]] = load {{.*}} @"OBJC_IVAR_$_Root._objectProperty",
171-
// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef [[IVAR]], {{.*}})
170+
// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef 8, {{.*}})
172171

173172
@interface Foo : Root {
174173
id __strong _cause_cxx_destruct;

clang/test/CodeGenObjC/hidden-visibility.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple i386-apple-macosx -fvisibility=hidden -emit-llvm -o - %s | FileCheck %s
2-
// CHECK: @"OBJC_IVAR_$_I.P" = hidden
32
// CHECK: @"OBJC_CLASS_$_I" = hidden
43
// CHECK: @"OBJC_METACLASS_$_I" = hidden
4+
// CHECK: @"OBJC_IVAR_$_I.P" = hidden
55
// CHECK: @"_OBJC_PROTOCOL_$_Prot0" = weak hidden
66

77
@interface I {

0 commit comments

Comments
 (0)