From: David Majnemer Date: Sun, 13 Jul 2014 05:19:56 +0000 (+0000) Subject: MS ABI: Stick internal vftables in a comdat if they have RTTI data X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1fef4d1c6aa1c8a8995888693237fe20cfa3245a;p=clang MS ABI: Stick internal vftables in a comdat if they have RTTI data 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 --- diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 52438644ba..41b7574e34 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -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 diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp index 4368cc71a4..825aba010f 100644 --- a/test/CodeGenCXX/microsoft-abi-vftables.cpp +++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp @@ -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*)]