]> granicus.if.org Git - clang/commitdiff
CodeGen: mark protocols as common data
authorSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 25 Oct 2016 14:50:44 +0000 (14:50 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 25 Oct 2016 14:50:44 +0000 (14:50 +0000)
This allows for the coalescing of the protocol declarations.  When the protocols
are declared in headers, multiple definitions of the protocol would be emitted.
Marking them as common data indicates that any one can be selected.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@285073 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/protocol-comdat.m [new file with mode: 0644]

index 201bc518f5f85561f8ad698adeb979b77e31288e..e20761ba48a8f5b8e51db41e73298418ca711d34 100644 (file)
@@ -6562,15 +6562,20 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
   const ObjCProtocolDecl *PD) {
   llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
 
-  if (!Entry)
+  if (!Entry) {
     // We use the initializer as a marker of whether this is a forward
     // reference or not. At module finalization we add the empty
     // contents for protocols which were referenced but never defined.
-    Entry =
-        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
-                                 false, llvm::GlobalValue::ExternalLinkage,
-                                 nullptr,
-                                 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
+    llvm::SmallString<64> Protocol;
+    llvm::raw_svector_ostream(Protocol) << "\01l_OBJC_PROTOCOL_$_"
+                                        << PD->getObjCRuntimeNameAsString();
+
+    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
+                                     false, llvm::GlobalValue::ExternalLinkage,
+                                     nullptr, Protocol);
+    if (!CGM.getTriple().isOSBinFormatMachO())
+      Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
+  }
 
   return Entry;
 }
@@ -6688,10 +6693,16 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
     Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
     Entry->setInitializer(Init);
   } else {
-    Entry =
-      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
-                               false, llvm::GlobalValue::WeakAnyLinkage, Init,
-                               "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
+    llvm::SmallString<64> Protocol;
+    llvm::raw_svector_ostream(Protocol) << "\01l_OBJC_PROTOCOL_$_"
+                                        << PD->getObjCRuntimeNameAsString();
+
+    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
+                                     false, llvm::GlobalValue::WeakAnyLinkage,
+                                     Init, Protocol);
+    if (!CGM.getTriple().isOSBinFormatMachO())
+      Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
+
     Entry->setAlignment(
       CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
 
@@ -6702,13 +6713,20 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
 
   // Use this protocol meta-data to build protocol list table in section
   // __DATA, __objc_protolist
+  llvm::SmallString<64> ProtocolRef;
+  llvm::raw_svector_ostream(ProtocolRef) << "\01l_OBJC_LABEL_PROTOCOL_$_"
+                                         << PD->getObjCRuntimeNameAsString();
+
   llvm::GlobalVariable *PTGV =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
                              false, llvm::GlobalValue::WeakAnyLinkage, Entry,
-                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
+                             ProtocolRef);
+  if (!CGM.getTriple().isOSBinFormatMachO())
+    PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
   PTGV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
-  PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
+  if (CGM.getTriple().isOSBinFormatMachO())
+    PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
   PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
   CGM.addCompilerUsedGlobal(PTGV);
   return Entry;
diff --git a/test/CodeGenObjC/protocol-comdat.m b/test/CodeGenObjC/protocol-comdat.m
new file mode 100644 (file)
index 0000000..65e1b9f
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang -cc1 -triple thumbv7--windows-itanium -fobjc-runtime=ios -emit-llvm -o - %s -Wno-objc-root-class | FileCheck %s
+
+@protocol P
+- (void) method;
+@end
+
+@interface I<P>
+@end
+
+@implementation I
+- (void) method { }
+@end
+
+
+// CHECK: $"\01l_OBJC_PROTOCOL_$_P" = comdat any
+// CHECK: $"\01l_OBJC_LABEL_PROTOCOL_$_P" = comdat any
+
+// CHECK: @"\01l_OBJC_PROTOCOL_$_P" = {{.*}}, comdat
+// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, comdat
+