Skip to content
Snippets Groups Projects
Commit 1fef4d1c authored by David Majnemer's avatar David Majnemer
Browse files

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
parent ca1863ee
No related branches found
No related tags found
No related merge requests found
...@@ -1325,15 +1325,13 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, ...@@ -1325,15 +1325,13 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
if (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) { if (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) {
// AvailableExternally implies that we grabbed the data from another // AvailableExternally implies that we grabbed the data from another
// executable. No need to stick the alias in a Comdat. // executable. No need to stick the alias in a Comdat.
} else if (llvm::GlobalValue::isLocalLinkage(VFTableLinkage)) { } else if (llvm::GlobalValue::isInternalLinkage(VFTableLinkage) ||
// If it's local, it means that the virtual function table can't be llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
// referenced in another translation unit. No need to stick the alias
// in a Comdat.
} else if (llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) { llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) {
// The alias is going to be dropped into a Comdat, no need to make it // The alias is going to be dropped into a Comdat, no need to make it
// weak. // weak.
VFTableLinkage = llvm::GlobalValue::ExternalLinkage; if (!llvm::GlobalValue::isInternalLinkage(VFTableLinkage))
VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
llvm::Comdat *C = llvm::Comdat *C =
CGM.getModule().getOrInsertComdat(VFTable->getName()); CGM.getModule().getOrInsertComdat(VFTable->getName());
// We must indicate which VFTable is larger to support linking between // We must indicate which VFTable is larger to support linking between
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// RTTI-DAG: $"\01??_7S@@6B@" = comdat largest // RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
// RTTI-DAG: $"\01??_7V@@6B@" = comdat largest // RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
// RTTI-DAG: $"\01??_7W@?A@@6B@" = comdat largest
struct S { struct S {
virtual ~S(); virtual ~S();
...@@ -35,7 +36,7 @@ struct W { ...@@ -35,7 +36,7 @@ struct W {
virtual ~W(); virtual ~W();
} 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) // 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*)] // NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment