aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CodeGenObjC/ivar-invariant.m
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2013-02-17 04:03:34 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2013-02-17 04:03:34 +0000
commit5f25bc30d17719806a1df3e1805f528a65289cca (patch)
tree85f1ff810783a4bdabac342de067cd318fa6490d /clang/test/CodeGenObjC/ivar-invariant.m
parent1286ef9c896d69b6f146e7edeb68d11a2308796a (diff)
downloadllvm-5f25bc30d17719806a1df3e1805f528a65289cca.zip
llvm-5f25bc30d17719806a1df3e1805f528a65289cca.tar.gz
llvm-5f25bc30d17719806a1df3e1805f528a65289cca.tar.bz2
[CodeGen] tighten objc ivar invariant.load attribution
An ivar ofset cannot be marked as invariant load in all cases. The ivar offset is a lazily initialised constant, which is dependent on an objc_msgSend invocation to perform a fixup of the offset. If the load is being performed on a method implemented by the class then this load can safely be marked as an inviarant because a message must have been passed to the class at some point, forcing the ivar offset to be resolved. An additional heuristic that can be used to identify an invariant load would be if the ivar offset base is a parameter to an objc method. However, without the parameters available at hand, this is currently not possible. Reviewed-by: John McCall <rjmccall@apple.com> Signed-off-by: Saleem Abdulrasool <compnerd@compnerd.org> llvm-svn: 175386
Diffstat (limited to 'clang/test/CodeGenObjC/ivar-invariant.m')
-rw-r--r--clang/test/CodeGenObjC/ivar-invariant.m53
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/test/CodeGenObjC/ivar-invariant.m b/clang/test/CodeGenObjC/ivar-invariant.m
new file mode 100644
index 0000000..f592654
--- /dev/null
+++ b/clang/test/CodeGenObjC/ivar-invariant.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c %s -o - | FileCheck %s
+
+@interface NSObject
++ (id) new;
+- (id) init;
+@end
+
+@interface Base : NSObject @end
+
+// @implementation Base
+// {
+// int dummy;
+// }
+// @end
+
+@interface Derived : Base
+{
+ @public int member;
+}
+@end
+
+@implementation Derived
+- (id) init
+{
+ self = [super init];
+ member = 42;
+ return self;
+}
+@end
+
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+
+void * variant_load_1(int i) {
+ void *ptr;
+ while (i--) {
+ Derived *d = [Derived new];
+ ptr = &d->member;
+ }
+ return ptr;
+}
+
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member"{{$}}
+
+@interface Container : Derived @end
+@implementation Container
+- (void *) invariant_load_1
+{
+ return &self->member;
+}
+@end
+
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+