[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-23 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From a2393ceb54895e3f6057b649e09732ce3a156811 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 87cea9f702fe985b051028e25f77244d55f0a88c Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-23 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From da7ef0a9a45feb9669482040d34a0dd0e2edaa52 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 3f36648107b50d382f46ef60121108e4c7946406 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-23 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From fe596f4241328f36bda734b2c006aef769efb2c8 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 60f8df33a3f5a0e37cd6c1c851463b12701a825b Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From fb93a08f40800652ebe7065e8495511f9b751ec7 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 7d5affc816da4f734c06862c82053f0d46435825 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From b88dcd912f3c9d4c600fa2132dfe84eb74264d10 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 96abdb23e6b6d660c9b14dcb5cd19dd9b26a6c96 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 40658e0af6d70dbc1d8cfee026aaa36ef6287276 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From a2c3250eaa74f7db388551da04184a1956f282f1 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread via cfe-commits

AtariDreams wrote:

@rjmccall Done!

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 6c46f5be980dac3200058b694ab7fca3f6ad707e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 96 +++
 1 file changed, 96 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..c4bb1ebc9a80be 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden global i64 64
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +27,95 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr 
noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass 
intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+_intermediateProperty = 0;
+// CHECK: load i64, ptr 
@"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@property (nonatomic, assign) SubClass *subClassProperty;
+@end
+
+@implementation SubClass
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+// implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 7907980a315c86e43b14d1fc137fc655bbfd2dc3 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread John McCall via cfe-commits


@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20

rjmccall wrote:

Please add a test for the access to this.  It'll be in a synthesized method.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread John McCall via cfe-commits


@@ -17,9 +23,71 @@ @implementation StaticLayout {
 -(void)meth {
   static_layout_ivar = 0;
   // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_StaticLayout
+  // CHECK: getelementptr inbounds i8, ptr %0, i64 20
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass

rjmccall wrote:

Please add CHECK-LABEL lines for the `define` lines for each of the method 
definitions containing these ivar accesses.  You can look at 
test/CodeGenObjC/direct-methods.m for the pattern I'm looking for here.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-22 Thread John McCall via cfe-commits


@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = constant 
i64 32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = constant 
i64 40

rjmccall wrote:

Please add a test for an access to this.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 570827305ceef6b5e0832fd92faca2b4018a48e0 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From e6c7c15cd114854b1a7ff081f9b476d3fd4f2560 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 23 +++
 .../constant-non-fragile-ivar-offset.m| 28 +--
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..c7ec2370f56285 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,23 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From a2514a1b84e43e0868ddbc69296efc7912d9da2f Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 4a5e9099917d681d8b95bccd874c41b34d8abcc8 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 23 +++
 .../constant-non-fragile-ivar-offset.m| 28 +--
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..c7ec2370f56285 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,23 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 147e27730c9ce5f7baef7363480e98b08190f476 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 33bf2234948bf9b45b1590ad33f6b48f4a49b46c Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 23 +++
 .../constant-non-fragile-ivar-offset.m| 28 +--
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..c7ec2370f56285 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,23 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 147e27730c9ce5f7baef7363480e98b08190f476 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From bbaaba0c9cab9a2f09e8c0840fdcedaa1fd2bd2c Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 23 +-
 .../constant-non-fragile-ivar-offset.m| 24 +--
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..c7ec2370f56285 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,23 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 63f3ada705b69c27ca37207c6f7e8098896602b7 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 76eb88980c8ffc07b788809018f81a720de955c6 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 22 +--
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-21 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 63f3ada705b69c27ca37207c6f7e8098896602b7 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From a89a220746836a6ff0931b26fc30f60ca92f0736 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++
 .../constant-non-fragile-ivar-offset.m| 30 +--
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-20 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From efa382134783898ab2613f13f46dfc3384a3795e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From a8e4fff75d30219daa869c80d544d0cdf4f38b0b Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++
 .../constant-non-fragile-ivar-offset.m| 30 +--
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-20 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From efa382134783898ab2613f13f46dfc3384a3795e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From c323456590454c45a627aee5230165500853a8da Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 18 +++
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-20 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From efa382134783898ab2613f13f46dfc3384a3795e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 70 +++
 1 file changed, 70 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0bf3336527b0a0 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,70 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SuperClass
+// CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+- (void)intermediateClassPropertyMethod {
+self.intermediateProperty = 0;
+// CHECK: getelementptr inbounds i8, ptr %2, i64 24
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+-(void)intermediateSubclassVar
+{
+intermediateClassIvar = 3.14;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: getelementptr inbounds i8, ptr %0, i64 %ivar
+}
+
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From c29b6937345ea5a0721c201aafb483075ddaa216 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 19 
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-19 Thread John McCall via cfe-commits

https://github.com/rjmccall commented:

Thanks, the breadth of tests looks good.  Please improve the actual testing, 
though — CHECK lines are testing the IR output file at a whole, so now that 
there are multiple tests in this file, we really need to make these tests more 
specific.

- First, please add CHECK-LABEL lines for the functions you're trying to test 
so that we know that the checks are actually applying to the code in that 
function.
- Second, I know the existing test is doing this CHECK-NOT thing, but it should 
really always have been testing that the ivar access actually uses the right 
offset; please do that, both for your new tests and the existing one.
- Finally, please make sure you test at least one access for each of the ivars. 
 Putting accesses in separate methods will help with ensuring that you're 
testing each specifically.

As a procedural note, I was going to review this last week after you responded 
to the review, but then I saw that you kept uploading new versions of the 
patch, so I held off.  I certainly understand needing to update the patch a few 
times; I do that myself all the time.  Just make sure you give me a heads up 
that the patch has been updated and is actually ready for review: either hold 
your response until your patch is ready, or make a short comment like "Sorry 
about that, patch is ready for review now." when the updates are done.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-19 Thread via cfe-commits

AtariDreams wrote:

Ping

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-14 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 2cf00f6ddf7be0e51fdb1a27668f3c4c92a8 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 56 +++
 1 file changed, 56 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..44e5af28cdbe02 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,56 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 25d1bb9d4997768577dde1a7e243d2d268b342c2 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  ID 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-14 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 79ffb626e113b74d934b5322eb76f2b97e1dbee5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 56 +++
 1 file changed, 56 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..44e5af28cdbe02 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,56 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 9555bf52beb784bec384e6eb4cc781c3389762e0 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  ID 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 6917791b07ad4fe696e7d5d1e9f378eb0e5ed78d Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 56 +++
 1 file changed, 56 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..44e5af28cdbe02 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,56 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From f5b3fd7ab12b3fba488c1f352f7f567cbc8a1fad Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  ID 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 983587c37e18979552ac4ad3891b423c1897a35b Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 56 +++
 1 file changed, 56 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..44e5af28cdbe02 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,56 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 1ac10e1723e127519b03f4b53f4e678e095399c7 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  ID 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From af164727a52b49f50a71550326380e16e94e4356 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..b1b990da552394 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,58 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 1834cd44b2c771ed1876ba3b9ceffcc19e339856 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 1067d095fc6eb955f32c913a9efa42fb1b8e37d0 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..b1b990da552394 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,58 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 400f3175779a654817fb94450f3ec7dc82ce911a Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From ebaa78d07b5472cac2a1407c2dfb50f4b3f0 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..b1b990da552394 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,58 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 8eab88f8a5218e1511747c241f2248abe4b1afe9 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From c6ef77033ad34b7a5b3b1d1a5a89d18d57af0894 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..b1b990da552394 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,58 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 8e7724554de14c9f249c274b4ce655f77e49d41e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 2e249501668d1c7b18803a922bca7fb473257b0f Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 59 +++
 1 file changed, 59 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0d3a5abd2fa5b2 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,59 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From ecfac4fc0e6722ff85d144844f93595496f77fbb Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 15 ++---
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+   

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-13 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From e586ff3c73dff1f983aa4ec9838c17324e34087d Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 59 +++
 1 file changed, 59 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..0d3a5abd2fa5b2 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 
24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = global i64 
32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = global i64 
40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden 
global i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 56
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,59 @@ -(void)meth {
 }
 @end
 
+// Ivars declared in the @interface
+@interface SuperClass : NSObject
+@property (nonatomic, assign) int superClassProperty;
+@end
+
+@implementation SuperClass {
+  int superClassIvar; // Declare an ivar
+}
+
+- (void)superClassMethod {
+_superClassProperty = 42;
+superClassIvar = 10;
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+}
+
+@end
+
+// Inheritance and Ivars
+@interface IntermediateClass : SuperClass
+{
+double intermediateClassIvar;
+
+@protected
+int intermediateClassIvar2;
+}
+@property (nonatomic, strong) SuperClass *intermediateProperty;
+@end
+
+@implementation IntermediateClass
+
+@synthesize intermediateProperty = _intermediateProperty;
+- (void)intermediateClassMethod {
+intermediateClassIvar = 3.14;
+_intermediateProperty = 0;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+}
+@end
+
+@interface SubClass : IntermediateClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)subclassVar {
+intermediateClassIvar = 3.14;
+subClassIvar = 6.28;
+// CHECK: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+// CHECK: load i64, ptr @"OBJC_IVAR_$_SubClass
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 6ac8e39250b3b9e3a777ceeba21f9ae39c32a6eb Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Tue, 13 Feb 2024 14:52:49 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m| 14 ++--
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+  // If we cannot see the @implementation of a class, we cannot statically
+  // know the class layout
+  if (!ID->getImplementation())
+return false;
+
+  // Test superclass
+

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread John McCall via cfe-commits

rjmccall wrote:

> Alright. I think the LTO should be done as a follow-up PR since it will 
> likely take some time and multiple reviews to get right.

Yes, that's a fine plan.  I expect that that'll be a significant amount of work.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread John McCall via cfe-commits

https://github.com/rjmccall requested changes to this pull request.

> @rjmccall Are these tests adequate?

No.  You need to test the behavior of ivar accesses in the subclass when there 
is an intermediate superclass that has ivars declared in all the ways I 
identified.  Your test has many tests for ivar accesses in immediate subclasses 
of `NSObject`, which is an optimization that we've already been doing for 
several years.  It only tests indirect subclasses in one configuration, which 
is when the intermediate superclass has all its ivars declared in the 
`@interface`.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread via cfe-commits

AtariDreams wrote:

> I talked this over with Mike Ash. I was concerned that Objective-C might 
> allow dynamic class changes that would burn our ability to do this 
> optimization, such as adding ivars during `+initialize`. The existing 
> optimization would work even with a relatively lax runtime as long as new 
> ivars always followed existing ivars. Fortunately, Mike assures me that this 
> is impossible: the layout of a class is fixed before it's ever exposed to 
> user code, including the calls to `+load` and `+initialize`. The runtime only 
> allows ivars to be added to a class before the class is registered with the 
> runtime (i.e. never for compiler-emitted classes). It is possible to replace 
> the superclass dynamically (although this is strongly discouraged), but class 
> layout has already happened by any point where this is possible, so there is 
> an effective requirement that the new superclass's class layout matches the 
> old one's. In short, we're comfortable saying that there's an ABI rule that 
> class layout for compiled classes is solely dependent on information 
> expressed in the language, at least as far as the class's subobject is 
> concerned (that is, we can never rule out subclasses, including dynamic 
> subclasses; but that doesn't interfere with the static optimization here). So 
> this optimization is indeed possible.
> 
> The compiler is not integrated with the linker and cannot see 
> `@implementation`s for classes defined outside the current translation unit. 
> So the approach in this patch only helps in the case that you have the 
> primary `@implementation` for multiple classes in a single translation unit. 
> That's fairly uncommon in my experience; ObjC programmers tend to define 
> different classes in different `.m` files. Still, it probably does happen, 
> especially with code generation, and we ought to be able to optimize it.
> 
> We should stress to programmers that they should not change their code by 
> defining everything in a single `.m` file just to get this optimization. It 
> is not likely to be worthwhile.
> 
> In order to optimize this across translation units, we'd need a version of it 
> that worked with LTO. It should be very feasible to do this with summaries in 
> ThinLTO. That seems like it'd be a huge win; it would have three effects that 
> I can see:
> 
> * We'd be able to pre-slide offset variables in subclasses according to their 
> superclasses in the same image.  This can significantly optimize load times 
> by reducing the amount of memory that has to be dirtied.  However, I think 
> the Mach-O linker already does this, so it's probably not a big deal to do in 
> LTO.
> * We'd be able to optimize ivar accesses to use static offsets even when the 
> superclass is defined in a different TU.  This seems like the biggest win.
> * We'd be able to optimize ivar accesses to use static offsets even for 
> accesses outside of the main `@implementation`.  This would be a huge win 
> except that it's pretty unidiomatic in Objective-C, which generally strongly 
> encourages the use of properties.
> 
> I'll take another look at your patch. As Aaron said, there is no need to ping 
> me so quickly, especially on the weekend.

Alright. I think the LTO should be done as a follow-up since it will likely 
take some time and multiple reviews to get right. 

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread John McCall via cfe-commits

rjmccall wrote:

I talked this over with Mike Ash.  I was concerned that Objective-C might allow 
dynamic class changes that would burn our ability to do this optimization, such 
as adding ivars during `+initialize`.  The existing optimization would work 
even with a relatively lax runtime as long as new ivars always followed 
existing ivars.  Fortunately, Mike assures me that this is impossible: the 
layout of a class is fixed before it's ever exposed to user code, including the 
calls to `+load` and `+initialize`.  The runtime only allows ivars to be added 
to a class before the class is registered with the runtime (i.e. never for 
compiler-emitted classes).  It is possible to replace the superclass 
dynamically (although this is strongly discouraged), but class layout has 
already happened by any point where this is possible, so there is an effective 
requirement that the new superclass's class layout matches the old one's.  In 
short, we're comfortable saying that there's an ABI rule that class layout for 
compiled classes is solely dependent on information expressed in the language, 
at least as far as the class's subobject is concerned (that is, we can never 
rule out subclasses, including dynamic subclasses; but that doesn't interfere 
with the static optimization here).  So this optimization is indeed possible.

The compiler is not integrated with the linker and cannot see 
`@implementation`s for classes defined outside the current translation unit.  
So the approach in this patch only helps in the case that you have the primary 
`@implementation` for multiple classes in a single translation unit.  That's 
fairly uncommon in my experience; ObjC programmers tend to define different 
classes in different `.m` files.  Still, it probably does happen, especially 
with code generation, and we ought to be able to optimize it.

We should stress to programmers that they should not change their code by 
defining everything in a single `.m` file just to get this optimization.  It is 
not likely to be worthwhile.

In order to optimize this across translation units, we'd need a version of it 
that worked with LTO.  It should be very feasible to do this with summaries in 
ThinLTO.  That seems like it'd be a huge win; it would have three effects that 
I can see:

- We'd be able to pre-slide offset variables in subclasses according to their 
superclasses in the same image.  This can significantly optimize load times by 
reducing the amount of memory that has to be dirtied.  However, I think the 
Mach-O linker already does this, so it's probably not a big deal to do in LTO.
- We'd be able to optimize ivar accesses to use static offsets even when the 
superclass is defined in a different TU.  This seems like the biggest win.
- We'd be able to optimize ivar accesses to use static offsets even for 
accesses outside of the main `@implementation`.  This would be a huge win 
except that it's pretty unidiomatic in Objective-C, which generally strongly 
encourages the use of properties.

I'll take another look at your patch.  As Aaron said, there is no need to ping 
me so quickly, especially on the weekend.

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 498111805cc17469522bd5e8f40856b241eac799 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 380162af21f2a3699e9040d4778804b23b5e2a1e Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..b3d6c3ba314cc2 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+ 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 6103fff6c5040e70fa28bd088f8eafbe479cbab1 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 3a5cfce7c2b7c3537347ad7ec8d721f3e356a262 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+ 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-12 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> @rjmccall Are these tests adequate?

While we appreciate the enthusiasm, please only ping reviewers after about a 
week of not hearing from them on a review 
(https://llvm.org/docs/CodeReview.html#code-reviews-speed-and-reciprocity), 
thanks!

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 7ef83de2bfc13da0b317d144a38f223b3738889b Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 2d4701c44f6941ac62c649e42b4efb6b417afdbf Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+ 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 59c7138d6dce65c22170f4642d0fac6d628c6ad5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From ca9de39046819a5744bc93aaf4211f35b3581ecd Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+ 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams edited 
https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 59c7138d6dce65c22170f4642d0fac6d628c6ad5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From cb33c2a5c0eaa7e65ed46a487890298fc0751349 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  6 ++---
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  // The base class NSObject is a fixed size
+  if (ID->getName() == "NSObject")
+return true;
+
+

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 59c7138d6dce65c22170f4642d0fac6d628c6ad5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From c19fa3e4a16862b5cd2a21c911312c6f88f43af2 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Perhaps there is another way to figure this out at link-time as well, but that 
is for another time and another PR.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 56207acd7ce55b328b7c72071335b0b452c7a97b Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 9b8bb3e7d03f320884be5f9b9ba3fac57ec21524 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Perhaps there is another way to figure this out at link-time as well, but that 
is for another time and another PR.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-11 Thread via cfe-commits

AtariDreams wrote:

@rjmccall Are these tests adequate? 

https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-10 Thread via cfe-commits

https://github.com/AtariDreams edited 
https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-10 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 3287e1ddb572f73ca774e50323b037d50b600e34 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 5dfaf1dfbad2ae5fc8eb57bb320348910dcd1fb1 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said class has fixed offsets and can therefore have its memory 
layout statically known.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Perhaps there is another way to figure this out at link-time as well, but that 
is for another time and another PR.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) {
+  

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-10 Thread via cfe-commits

https://github.com/AtariDreams edited 
https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-10 Thread via cfe-commits

https://github.com/AtariDreams updated 
https://github.com/llvm/llvm-project/pull/81335

>From 3287e1ddb572f73ca774e50323b037d50b600e34 Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:51:15 -0500
Subject: [PATCH 1/2] [ObjC] Add pre-commit tests [NFC]

---
 .../constant-non-fragile-ivar-offset.m| 82 +++
 1 file changed, 82 insertions(+)

diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m 
b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..6806fbf8f435aa 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | 
FileCheck %s
 
 // CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 
20
+// CHECK: @"OBJC_IVAR_$_MyClass.myIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_MyClass._myProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.privateId" = constant i64 24
+// CHECK: @"OBJC_IVAR_$_AnotherClass.anotherPrivateId" = hidden constant i64 32
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = constant i64 20
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = global i64 24
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden 
global i64 12
 
 @interface NSObject {
@@ -20,6 +26,82 @@ -(void)meth {
 }
 @end
 
+// Scenario 1: Ivars declared in the @interface
+@interface MyClass : NSObject
+{
+int myIvar; // Declare an ivar
+}
+
+@property (nonatomic, assign) int myProperty; // Synthesize a property
+
+@end
+
+@implementation MyClass 
+
+- (void)exampleMethod {
+self.myProperty = 42; // Access the property
+myIvar = 10; // Access the ivar directly
+}
+
+@end
+
+// Scenario 2: Ivars declared directly in the @implementation
+@interface AnotherClass : NSObject
+{
+  id privateId;
+}
+
+@end
+
+@implementation AnotherClass
+{
+id anotherPrivateId; // Declare an ivar directly in the implementation
+}
+
+- (void)doSomething {
+   privateId = anotherPrivateId;
+}
+
+@end
+
+// Scenario 3: Inheritance and Ivars
+@interface SuperClass : NSObject
+{
+int superClassIvar;
+}
+@end
+
+@implementation SuperClass
+@end
+
+@interface SubClass : SuperClass
+{
+double subClassIvar;
+}
+@end
+
+@implementation SubClass
+- (void)exampleMethod {
+// CHECK: load i64, ptr @"OBJC_IVAR_$SuperClass
+superClassIvar = 100; // Access superclass ivar
+subClassIvar = 3.14; // Access subclass ivar
+}
+@end
+
+// Scenario 4: Custom Getter/Setter Methods
+@interface CustomPropertyClass : NSObject
+@property (nonatomic, strong, getter=myCustomGetter, setter=myCustomSetter:) 
id customProperty;
+@end
+
+@implementation CustomPropertyClass
+- (id) myCustomGetter {
+return 0;
+}
+
+- (void)myCustomSetter:(id)newValue {
+}
+@end
+
 @interface NotNSObject {
   int these, might, change;
 }

>From 952b90e0743ce04523287a74780b9e5a9f0a6dec Mon Sep 17 00:00:00 2001
From: Rose <83477269+ataridre...@users.noreply.github.com>
Date: Fri, 9 Feb 2024 17:47:59 -0500
Subject: [PATCH 2/2] [ObjC] Check entire chain of superclasses to see if class
 layout can be statically known

As of now, we only check if a class directly inherits from NSObject to 
determine if said lass has fixed offsets and can therefore "opt-out" from the 
non-fragile ABI for ivars.

However, if an NSObject subclass has fixed offsets, then so must the subclasses 
of that subclass, so this allows us to optimize instances of subclasses of 
subclasses that inherit from NSObject and so on.

To determine this, we need to find that the compiler can see the implementation 
of each intermediate class, as that means it is statically linked.

Perhaps there is another way to figure this out at link time as well, but that 
is for another time and another PR.

Fixes: #81369
---
 clang/lib/CodeGen/CGObjCMac.cpp   | 22 ++-
 .../constant-non-fragile-ivar-offset.m|  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 27d77e9a8a5511..ceee70a5d79b3e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   }
 
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
-// NSObject is a fixed size. If we can see the @implementation of a class
-// which inherits from NSObject then we know that all it's offsets also 
must
-// be fixed. FIXME: Can we do this if see a chain of super classes with
-// implementations leading to NSObject?
-return ID->getImplementation() && ID->getSuperClass() &&
-   ID->getSuperClass()->getName() == "NSObject";
+// Test a class by checking its superclasses up to its base class if it has
+// one
+while (ID) 

[clang] [ObjC] Check entire chain of superclasses to see if class layout can be statically known (PR #81335)

2024-02-10 Thread via cfe-commits

https://github.com/AtariDreams edited 
https://github.com/llvm/llvm-project/pull/81335
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits