r202872 - Objective-C IRGen. Fix up the hueristics for determining

Fariborz Jahanian fjahanian at apple.com
Tue Mar 4 10:34:53 PST 2014


Author: fjahanian
Date: Tue Mar  4 12:34:52 2014
New Revision: 202872

URL: http://llvm.org/viewvc/llvm-project?rev=202872&view=rev
Log:
Objective-C IRGen. Fix up the hueristics for determining
if an ivar offset load is invariant iff inside an instance method
and ivar belongs to instance method's class and one of its super class.
// rdar://16095748

Added:
    cfe/trunk/test/CodeGenObjC/optimize-ivar-offset-load.m
Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=202872&r1=202871&r2=202872&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Mar  4 12:34:52 2014
@@ -1442,11 +1442,10 @@ private:
   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
+    // Annotate the load as an invariant load iff inside an instance method
+    // and ivar belongs to instance method's class and one of its super class.
+    // 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.
     //
@@ -1454,9 +1453,12 @@ private:
     // 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 (CGF.CurFuncDecl && isa<ObjCMethodDecl>(CGF.CurFuncDecl))
-      if (IV->getContainingInterface()->isSuperClassOf(ID))
-        return true;
+    if (const ObjCMethodDecl *MD =
+          dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
+      if (MD->isInstanceMethod() &&
+          !isa<ObjCProtocolDecl>(MD->getDeclContext()))
+        if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
+          return IV->getContainingInterface()->isSuperClassOf(ID);
     return false;
   }
 
@@ -6479,7 +6481,7 @@ LValue CGObjCNonFragileABIMac::EmitObjCV
   ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
   llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
 
-  if (IsIvarOffsetKnownIdempotent(CGF, ID, Ivar))
+  if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
     if (llvm::LoadInst *LI = cast<llvm::LoadInst>(Offset))
       LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
                       llvm::MDNode::get(VMContext, ArrayRef<llvm::Value*>()));

Added: cfe/trunk/test/CodeGenObjC/optimize-ivar-offset-load.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/optimize-ivar-offset-load.m?rev=202872&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/optimize-ivar-offset-load.m (added)
+++ cfe/trunk/test/CodeGenObjC/optimize-ivar-offset-load.m Tue Mar  4 12:34:52 2014
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -Os -emit-llvm %s -o -  | FileCheck %s
+// rdar://16095748
+
+ at interface NSObject 
+ at end
+
+ at interface SampleClass : NSObject {
+    @public
+    int _value;
+}
++ (SampleClass*) new;
+ at end
+
+ at interface AppDelegate  : NSObject
+ at end
+
+extern void foo(int);
+
+ at implementation AppDelegate
+- (void)application
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+ at end
+// CHECK: [[IVAR:%.*]]  = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8
+// CHECK: [[THREE:%.*]] = bitcast [[ONE:%.*]]* [[CALL:%.*]] to i8*
+// CHECK: [[ADDPTR:%.*]] = getelementptr inbounds i8* [[THREE]], i64 [[IVAR]]
+// CHECK: [[FOUR:%.*]] = bitcast i8* [[ADDPTR]] to i32*
+// CHECK: [[FIVE:%.*]] = load i32* [[FOUR]], align 4
+// CHECK:   tail call void @foo(i32 [[FIVE]])
+
+ at implementation SampleClass
++ (SampleClass*) new { return 0; }
+- (void) SampleClassApplication
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+ at end
+// CHECK: [[ZERO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8, !invariant.load
+
+ at interface Sample : SampleClass @end
+
+ at implementation Sample
+- (void) SampleApplication
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+ at end
+// CHECK: [[ZERO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load 
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8, !invariant.load
+





More information about the cfe-commits mailing list