[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