]> granicus.if.org Git - clang/commitdiff
MS ABI: Stick internal vftables in a comdat if they have RTTI data
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 13 Jul 2014 05:19:56 +0000 (05:19 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 13 Jul 2014 05:19:56 +0000 (05:19 +0000)
Previously, we would have a private backing variable and an internal
alias pointing at it.

However, -fdata-sections only fires if a global variable has non-private
linkage.  This means that an unreferenced vftable wouldn't get
discarded, bloating the object file.

Instead, stick the backing variable in a comdat even if the alias has
internal linkage.  This will allow the linker to drop the vftable if it
is unused.

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

lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-vftables.cpp

index 52438644baaa77bfc526e56ca9c91838f14520b8..41b7574e34c26c3a6b1dd39fae7a8d891158d4d2 100644 (file)
@@ -1325,15 +1325,13 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
         if (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) {
           // AvailableExternally implies that we grabbed the data from another
           // executable.  No need to stick the alias in a Comdat.
-        } else if (llvm::GlobalValue::isLocalLinkage(VFTableLinkage)) {
-          // If it's local, it means that the virtual function table can't be
-          // referenced in another translation unit. No need to stick the alias
-          // in a Comdat.
-        } else if (llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
+        } else if (llvm::GlobalValue::isInternalLinkage(VFTableLinkage) ||
+                   llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
                    llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) {
           // The alias is going to be dropped into a Comdat, no need to make it
           // weak.
-          VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
+          if (!llvm::GlobalValue::isInternalLinkage(VFTableLinkage))
+            VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
           llvm::Comdat *C =
               CGM.getModule().getOrInsertComdat(VFTable->getName());
           // We must indicate which VFTable is larger to support linking between
index 4368cc71a49365d5fdb55aa5af952b183476e0f8..825aba010f125378114e60a1884c35edb40bcce7 100644 (file)
@@ -3,6 +3,7 @@
 
 // RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
 // RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
+// RTTI-DAG: $"\01??_7W@?A@@6B@" = comdat largest
 
 struct S {
   virtual ~S();
@@ -35,7 +36,7 @@ struct W {
   virtual ~W();
 } w;
 }
-// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)], comdat $"\01??_7W@?A@@6B@"
 // RTTI-DAG: @"\01??_7W@?A@@6B@" = unnamed_addr alias internal getelementptr inbounds ([2 x i8*]* @1, i32 0, i32 1)
 
 // NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]