[clang] 7611e16 - [clang][objc][codegen] Skip emitting ObjC category metadata when the
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 12 16:25:08 PST 2021
Author: Josh Learn
Date: 2021-11-12T16:21:21-08:00
New Revision: 7611e16fce9ce36b6bd6dceda691f6bc7e754347
URL: https://github.com/llvm/llvm-project/commit/7611e16fce9ce36b6bd6dceda691f6bc7e754347
DIFF: https://github.com/llvm/llvm-project/commit/7611e16fce9ce36b6bd6dceda691f6bc7e754347.diff
LOG: [clang][objc][codegen] Skip emitting ObjC category metadata when the
category is empty
Currently, if we create a category in ObjC that is empty, we still emit
runtime metadata for that category. This is a scenario that could
commonly be run into when using __attribute__((objc_direct_members)),
which elides the need for much of the category metadata. This is
slightly wasteful and can be easily skipped by checking the category
metadata contents during CodeGen.
rdar://66177182
Differential Revision: https://reviews.llvm.org/D113455
Added:
clang/test/CodeGenObjC/category-class-empty.m
Modified:
clang/lib/CodeGen/CGObjCMac.cpp
clang/test/CodeGenObjC/non-lazy-classes.m
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 36555ce3cbd9..5b925359ac25 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -6672,33 +6672,53 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
}
}
- values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
- instanceMethods));
- values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
- classMethods));
+ auto instanceMethodList = emitMethodList(
+ listName, MethodListType::CategoryInstanceMethods, instanceMethods);
+ auto classMethodList = emitMethodList(
+ listName, MethodListType::CategoryClassMethods, classMethods);
+ values.add(instanceMethodList);
+ values.add(classMethodList);
+ // Keep track of whether we have actual metadata to emit.
+ bool isEmptyCategory =
+ instanceMethodList->isNullValue() && classMethodList->isNullValue();
const ObjCCategoryDecl *Category =
- Interface->FindCategoryDeclaration(OCD->getIdentifier());
+ Interface->FindCategoryDeclaration(OCD->getIdentifier());
if (Category) {
SmallString<256> ExtName;
- llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
- << OCD->getName();
- values.add(EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_"
- + Interface->getObjCRuntimeNameAsString() + "_$_"
- + Category->getName(),
- Category->protocol_begin(),
- Category->protocol_end()));
- values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
- OCD, Category, ObjCTypes, false));
- values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
- OCD, Category, ObjCTypes, true));
+ llvm::raw_svector_ostream(ExtName)
+ << Interface->getObjCRuntimeNameAsString() << "_$_" << OCD->getName();
+ auto protocolList =
+ EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_" +
+ Interface->getObjCRuntimeNameAsString() + "_$_" +
+ Category->getName(),
+ Category->protocol_begin(), Category->protocol_end());
+ auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
+ OCD, Category, ObjCTypes, false);
+ auto classPropertyList =
+ EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
+ Category, ObjCTypes, true);
+ values.add(protocolList);
+ values.add(propertyList);
+ values.add(classPropertyList);
+ isEmptyCategory &= protocolList->isNullValue() &&
+ propertyList->isNullValue() &&
+ classPropertyList->isNullValue();
} else {
values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
values.addNullPointer(ObjCTypes.PropertyListPtrTy);
values.addNullPointer(ObjCTypes.PropertyListPtrTy);
}
- unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
+ if (isEmptyCategory) {
+ // Empty category, don't emit any metadata.
+ values.abandon();
+ MethodDefinitions.clear();
+ return;
+ }
+
+ unsigned Size =
+ CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
values.addInt(ObjCTypes.IntTy, Size);
llvm::GlobalVariable *GCATV =
diff --git a/clang/test/CodeGenObjC/category-class-empty.m b/clang/test/CodeGenObjC/category-class-empty.m
new file mode 100644
index 000000000000..d89a3e7eac42
--- /dev/null
+++ b/clang/test/CodeGenObjC/category-class-empty.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -O0 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// PR7431
+
+// CHECK-NOT: @"OBJC_LABEL_CATEGORY_$" = private global [1 x i8*] [i8* bitcast (%struct._category_t* @"_OBJC_$_CATEGORY_A_$_foo"
+
+ at interface A
+ at end
+__attribute__((objc_direct_members))
+ at interface A(foo)
+- (void)foo_myStuff;
+ at end
+ at implementation A(foo)
+- (void)foo_myStuff {
+}
+ at end
+
diff --git a/clang/test/CodeGenObjC/non-lazy-classes.m b/clang/test/CodeGenObjC/non-lazy-classes.m
index fc861f0017c0..4d5a3c0494e3 100644
--- a/clang/test/CodeGenObjC/non-lazy-classes.m
+++ b/clang/test/CodeGenObjC/non-lazy-classes.m
@@ -42,4 +42,7 @@ @interface E @end
@implementation E @end
__attribute__((objc_nonlazy_class))
- at implementation E (MyCat) @end
+ at implementation E (MyCat)
+-(void) load {
+}
+ at end
More information about the cfe-commits
mailing list