[PATCH] [CodeGen] tighten objc ivar invariant.load attribution

Saleem Abdulrasool compnerd at compnerd.org
Thu Feb 14 09:37:40 PST 2013


  Add a few test cases and fix an inverted check.

Hi rjmccall,

http://llvm-reviews.chandlerc.com/D406

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D406?vs=976&id=982#toc

Files:
  lib/CodeGen/CGObjCMac.cpp
  test/CodeGenObjC/ivar-invariant-unimplemented.m
  test/CodeGenObjC/ivar-invariant.m

Index: lib/CodeGen/CGObjCMac.cpp
===================================================================
--- lib/CodeGen/CGObjCMac.cpp
+++ lib/CodeGen/CGObjCMac.cpp
@@ -6449,10 +6449,23 @@
                                                unsigned CVRQualifiers) {
   ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
   llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
+
+  // Annotate the load as an invariant load iff the object type is the type, or
+  // a derived type, of the class containing the ivar within an ObjC method.
+  // This check is needed because the ivar offset is a lazily initialised value
+  // that may depend on objc_msgSend to perform a fixup on the first message
+  // dispatch.
+  //
+  // An additional opportunity to mark the load as invariant arises when the
+  // base of the ivar access is a parameter to an Objective C method.  However,
+  // because the parameters are not available in the current interface, we
+  // cannot perform this check.
   if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset))
-    LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 
-                   llvm::MDNode::get(VMContext,
-                   ArrayRef<llvm::Value*>()));
+    if (dyn_cast<ObjCMethodDecl>(CGF.CurFuncDecl))
+      if (Ivar->getContainingInterface()->isSuperClassOf(ID))
+        LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
+                        llvm::MDNode::get(VMContext, ArrayRef<llvm::Value*>()));
+
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   Offset);
 }
Index: test/CodeGenObjC/ivar-invariant-unimplemented.m
===================================================================
--- /dev/null
+++ test/CodeGenObjC/ivar-invariant-unimplemented.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -x objective-c %s -o - | FileCheck %s
+// XFAIL: *
+
+ at interface NSObject
++ (id) new;
+- (id) init;
+ at end
+
+ at interface C : NSObject
+{
+    @public int member;
+}
+- (void *) invariant_load_1;
+ at end
+
+ at implementation C
+- (void *) invariant_load_1
+{
+    return &self->member;
+}
+ at end
+
+// CHECK: %ivar = load i64* @"OBJC_IVAR_$_C.member", !invariant.load
+
+void * invariant_load_2(void) {
+    C *c = [C new];
+    [c invariant_load_1];
+    return &c->member;
+}
+
+// CHECK: %ivar = load i64* @"OBJC_IVAR_$_C.member", !invariant.load
+
Index: test/CodeGenObjC/ivar-invariant.m
===================================================================
--- /dev/null
+++ test/CodeGenObjC/ivar-invariant.m
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c %s -o - | FileCheck %s
+
+ at interface NSObject
++ (id) new;
+- (id) init;
+ at end
+
+ at interface Base : NSObject @end
+
+// @implementation Base
+// {
+//     int dummy;
+// }
+// @end
+
+ at interface Derived : Base
+{
+    @public int member;
+}
+ at end
+
+ at implementation Derived
+- (id) init
+{
+    self = [super init];
+    member = 42;
+    return self;
+}
+ at 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"
+// CHECK-NOT: %ivar = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+
+ at interface Container : Derived @end
+ at implementation Container
+- (void *) invariant_load_1
+{
+    return &self->member;
+}
+ at end
+
+// CHECK: %ivar = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+// CHECK-NOT %ivar = load i64* @"OBJC_IVAR_$_Derived.member"
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D406.2.patch
Type: text/x-patch
Size: 3693 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130214/506a8ab8/attachment.bin>


More information about the cfe-commits mailing list