diff options
author | John McCall <rjmccall@apple.com> | 2012-10-17 04:53:31 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-10-17 04:53:31 +0000 |
commit | 0d54a17b52bfb5cd20ac39e8d9e5b0533f4aa08c (patch) | |
tree | 294032f34e34e9e41f292efdc74eac565b80e282 /clang/lib/CodeGen | |
parent | ef19dbb62031b20798badebc9d11ae0fa369a3c0 (diff) | |
download | bcm5719-llvm-0d54a17b52bfb5cd20ac39e8d9e5b0533f4aa08c.tar.gz bcm5719-llvm-0d54a17b52bfb5cd20ac39e8d9e5b0533f4aa08c.zip |
Set a special flag in class metadata when an Objective-C class
has ivars that require destruction, but none that require anything
except zero-initialization. This is common in ARC and (when true
throughout a class hierarchy) permits the elimination of an
unnecessary message-send during allocation.
llvm-svn: 166088
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 |
2 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 01179cca6b9..99548517430 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2367,7 +2367,10 @@ enum NonFragileClassFlags { NonFragileABI_Class_HasIvarReleaser = 0x00040, /// Class implementation was compiled under ARC. - NonFragileABI_Class_CompiledByARC = 0x00080 + NonFragileABI_Class_CompiledByARC = 0x00080, + + /// Class has non-trivial destructors, but zero-initialization is okay. + NonFragileABI_Class_HasCXXDestructorOnly = 0x00100 }; /* @@ -2401,7 +2404,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { Interface->all_referenced_protocol_begin(), Interface->all_referenced_protocol_end()); unsigned Flags = FragileABI_Class_Factory; - if (ID->hasCXXStructors()) + if (ID->hasNonZeroConstructors() || ID->hasDestructors()) Flags |= FragileABI_Class_HasCXXStructors; unsigned Size = CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity(); @@ -5154,12 +5157,20 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *SuperClassGV, *IsAGV; + // Build the flags for the metaclass. bool classIsHidden = ID->getClassInterface()->getVisibility() == HiddenVisibility; if (classIsHidden) flags |= NonFragileABI_Class_Hidden; - if (ID->hasCXXStructors()) + + // FIXME: why is this flag set on the metaclass? + // ObjC metaclasses have no fields and don't really get constructed. + if (ID->hasNonZeroConstructors() || ID->hasDestructors()) { flags |= NonFragileABI_Class_HasCXXStructors; + if (!ID->hasNonZeroConstructors()) + flags |= NonFragileABI_Class_HasCXXDestructorOnly; + } + if (!ID->getClassInterface()->getSuperClass()) { // class is root flags |= NonFragileABI_Class_Root; @@ -5194,9 +5205,20 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { flags = 0; if (classIsHidden) flags |= NonFragileABI_Class_Hidden; - if (ID->hasCXXStructors()) + + if (ID->hasNonZeroConstructors() || ID->hasDestructors()) { flags |= NonFragileABI_Class_HasCXXStructors; + // Set a flag to enable a runtime optimization when a class has + // fields that require destruction but which don't require + // anything except zero-initialization during construction. This + // is most notably true of __strong and __weak types, but you can + // also imagine there being C++ types with non-trivial default + // constructors that merely set all fields to null. + if (!ID->hasNonZeroConstructors()) + flags |= NonFragileABI_Class_HasCXXDestructorOnly; + } + if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) flags |= NonFragileABI_Class_Exception; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e9344a1351b..95753d540e7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2541,7 +2541,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { /*isDefined=*/false, ObjCMethodDecl::Required); D->addInstanceMethod(DTORMethod); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false); - D->setHasCXXStructors(true); + D->setHasDestructors(true); } // If the implementation doesn't have any ivar initializers, we don't need @@ -2565,7 +2565,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { ObjCMethodDecl::Required); D->addInstanceMethod(CTORMethod); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true); - D->setHasCXXStructors(true); + D->setHasNonZeroConstructors(true); } /// EmitNamespace - Emit all declarations in a namespace. |