]> granicus.if.org Git - clang/commitdiff
Use a trivial comdat for C++ tables.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 15 Jan 2015 23:18:01 +0000 (23:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 15 Jan 2015 23:18:01 +0000 (23:18 +0000)
This produces comdats for vtables, typeinfo, typeinfo names, and vtts.

When combined with llvm not producing implicit comdats, not doing this would
cause code bloat on ELF and link errors on COFF.

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

lib/CodeGen/CGVTT.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/vtable-linkage.cpp

index bd280ea14e8d630aec39097d4ccad4d51e812f1e..81bd65179b709cf0a0db7f58159e6dc3c8970e6b 100644 (file)
@@ -94,6 +94,9 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
   // Set the correct linkage.
   VTT->setLinkage(Linkage);
 
+  if (CGM.supportsCOMDAT() && VTT->isWeakForLinker())
+    VTT->setComdat(CGM.getModule().getOrInsertComdat(VTT->getName()));
+
   // Set the right visibility.
   CGM.setGlobalVisibility(VTT, RD);
 }
index 7a97aa64ea9bad5509b3ed8f77e395425a70b2cb..72d7a6cd8e068b5a19d3b47463f34276176dc142 100644 (file)
@@ -1828,7 +1828,10 @@ CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name,
     
     OldGV->eraseFromParent();
   }
-  
+
+  if (supportsCOMDAT() && GV->isWeakForLinker())
+    GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
+
   return GV;
 }
 
index 7d8ad465bf3ef76e3296e9f100951abed33ecc0f..29d922c68e3ec8a2e33e4cbebc1020fd7424d707 100644 (file)
@@ -1256,6 +1256,9 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
   // Set the correct linkage.
   VTable->setLinkage(Linkage);
 
+  if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
+    VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
+
   // Set the right visibility.
   CGM.setGlobalVisibility(VTable, RD);
 
@@ -2716,9 +2719,13 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
 
   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
 
+  llvm::Module &M = CGM.getModule();
   llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
-                             /*Constant=*/true, Linkage, Init, Name);
+      new llvm::GlobalVariable(M, Init->getType(),
+                               /*Constant=*/true, Linkage, Init, Name);
+
+  if (CGM.supportsCOMDAT() && GV->isWeakForLinker())
+    GV->setComdat(M.getOrInsertComdat(GV->getName()));
 
   // If there's already an old global variable, replace it with the new one.
   if (OldGV) {
index 9c08b3037ca1a702ae47839b4270e0b84ab0a945..5cbd3897a1ffd195a3af03f701acddef0679abc1 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt
 // RUN: FileCheck --check-prefix=CHECK %s < %t
 // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
@@ -89,10 +89,10 @@ void use_F() {
 
 // C has no key function, so its vtable should have weak_odr linkage
 // and hidden visibility (rdar://problem/7523229).
-// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1C = linkonce_odr constant
-// CHECK-DAG: @_ZTI1C = linkonce_odr constant
-// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat{{$}}
 
 // D has a key function that is defined in this translation unit so its vtable is
 // defined in the translation unit.
@@ -110,28 +110,28 @@ void use_F() {
 // E<short> is an explicit template instantiation with a key function
 // defined in this translation unit, so its vtable should have
 // weak_odr linkage.
-// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1EIsE = weak_odr constant
-// CHECK-DAG: @_ZTI1EIsE = weak_odr constant
+// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat{{$}}
 
 // F<short> is an explicit template instantiation without a key
 // function, so its vtable should have weak_odr linkage
-// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1FIsE = weak_odr constant
-// CHECK-DAG: @_ZTI1FIsE = weak_odr constant
+// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat{{$}}
 
 // E<long> is an implicit template instantiation with a key function
 // defined in this translation unit, so its vtable should have
 // linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant
+// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
 
 // F<long> is an implicit template instantiation with no key function,
 // so its vtable should have linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant
+// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
 
 // F<int> is an explicit template instantiation declaration without a
 // key function, so its vtable should have external linkage.
@@ -158,11 +158,11 @@ void use_F() {
 
 // F<char> is an explicit specialization without a key function, so
 // its vtable should have linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant
+// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
+// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
 
-// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
 template <typename T>
 class G {
 public:
@@ -178,7 +178,7 @@ void G_f0()  { new G<int>(); }
 
 // H<int> has a key function without a body but it's a template instantiation
 // so its VTable must be emitted.
-// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
 template <typename T>
 class H {
 public: