From: Fariborz Jahanian Date: Tue, 4 Mar 2014 18:34:52 +0000 (+0000) Subject: Objective-C IRGen. Fix up the hueristics for determining X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ddd9310babd350f208166ed1f01f2bfab8a81e60;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202872 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index f558412f71..ebbd7007c1 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -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(CGF.CurFuncDecl)) - if (IV->getContainingInterface()->isSuperClassOf(ID)) - return true; + if (const ObjCMethodDecl *MD = + dyn_cast_or_null(CGF.CurFuncDecl)) + if (MD->isInstanceMethod() && + !isa(MD->getDeclContext())) + if (const ObjCInterfaceDecl *ID = MD->getClassInterface()) + return IV->getContainingInterface()->isSuperClassOf(ID); return false; } @@ -6479,7 +6481,7 @@ LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( ObjCInterfaceDecl *ID = ObjectTy->getAs()->getInterface(); llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar); - if (IsIvarOffsetKnownIdempotent(CGF, ID, Ivar)) + if (IsIvarOffsetKnownIdempotent(CGF, Ivar)) if (llvm::LoadInst *LI = cast(Offset)) LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), llvm::MDNode::get(VMContext, ArrayRef())); diff --git a/test/CodeGenObjC/optimize-ivar-offset-load.m b/test/CodeGenObjC/optimize-ivar-offset-load.m new file mode 100644 index 0000000000..d34ac13758 --- /dev/null +++ b/test/CodeGenObjC/optimize-ivar-offset-load.m @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Os -emit-llvm %s -o - | FileCheck %s +// rdar://16095748 + +@interface NSObject +@end + +@interface SampleClass : NSObject { + @public + int _value; +} ++ (SampleClass*) new; +@end + +@interface AppDelegate : NSObject +@end + +extern void foo(int); + +@implementation AppDelegate +- (void)application +{ + // Create set of objects in loop + for(int i = 0; i < 2; i++) { + SampleClass *sample = [SampleClass new]; + foo (sample->_value); + } +} +@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]]) + +@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); + } +} +@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 + +@interface Sample : SampleClass @end + +@implementation Sample +- (void) SampleApplication +{ + // Create set of objects in loop + for(int i = 0; i < 2; i++) { + SampleClass *sample = [SampleClass new]; + foo (sample->_value); + } +} +@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 +