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

Saleem Abdulrasool compnerd at compnerd.org
Thu Feb 14 15:16:06 PST 2013


  Fix CHECKs, address some comments.

Hi rjmccall,

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

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

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

Index: lib/CodeGen/CGObjCMac.cpp
===================================================================
--- lib/CodeGen/CGObjCMac.cpp
+++ lib/CodeGen/CGObjCMac.cpp
@@ -1432,6 +1432,25 @@
   /// class implementation is "non-lazy".
   bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
 
+  bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
+                                   const ObjCInterfaceDecl *ID,
+                                   const ObjCIvarDecl *IV) {
+    // 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 (dyn_cast<ObjCMethodDecl>(CGF.CurFuncDecl))
+        if (IV->getContainingInterface()->isSuperClassOf(ID))
+          return true;
+    return false;
+  }
+
 public:
   CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
   // FIXME. All stubs for now!
@@ -6449,10 +6468,12 @@
                                                unsigned CVRQualifiers) {
   ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
   llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
-  if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset))
-    LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 
-                   llvm::MDNode::get(VMContext,
-                   ArrayRef<llvm::Value*>()));
+
+  if (IsIvarOffsetKnownIdempotent(CGF, ID, Ivar))
+    if (llvm::LoadInst *LI = cast<llvm::LoadInst>(Offset))
+      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.m
===================================================================
--- /dev/null
+++ test/CodeGenObjC/ivar-invariant.m
@@ -0,0 +1,53 @@
+// 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"{{$}}
+
+ 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
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D406.3.patch
Type: text/x-patch
Size: 3373 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130214/0f1504e8/attachment.bin>


More information about the cfe-commits mailing list