We were emitting construction v-tables with internal linkage all the time.

Emit them instead with the linkage of the VTT.

I'm actually really ambivalent about this;  it's what GCC does, but outside
of improving code size (if the linkage is coalescing), I'm not sure it's
at all relevant.  Construction vtables are naturally referenced only by the
VTT, which is itself only referenced by complete-object constructors and
destructors;  giving the construction vtables possibly-external linkage is
important if you have an optimization that drills through the VTT to a
reference to a particular construction vtable which it cannot just emit
itself.

llvm-svn: 128374
This commit is contained in:
John McCall 2011-03-27 09:00:25 +00:00
parent 83167df787
commit 358d056c14
5 changed files with 27 additions and 9 deletions

View File

@ -54,6 +54,10 @@ class VTTBuilder {
/// the VTT.
bool GenerateDefinition;
/// The linkage to use for any construction vtables required by this VTT.
/// Only required if we're building a definition.
llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables;
/// GetAddrOfVTable - Returns the address of the vtable for the base class in
/// the given vtable class.
///
@ -109,7 +113,9 @@ class VTTBuilder {
public:
VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition);
bool GenerateDefinition,
llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables
= (llvm::GlobalVariable::LinkageTypes) -1);
// getVTTComponents - Returns a reference to the VTT components.
const VTTComponentsVectorTy &getVTTComponents() const {
@ -132,10 +138,15 @@ public:
VTTBuilder::VTTBuilder(CodeGenModule &CGM,
const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition)
bool GenerateDefinition,
llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables)
: CGM(CGM), MostDerivedClass(MostDerivedClass),
MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
GenerateDefinition(GenerateDefinition) {
GenerateDefinition(GenerateDefinition),
LinkageForConstructionVTables(LinkageForConstructionVTables) {
assert(!GenerateDefinition ||
LinkageForConstructionVTables
!= (llvm::GlobalVariable::LinkageTypes) -1);
// Lay out this VTT.
LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
@ -157,6 +168,7 @@ VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
Base, BaseIsVirtual,
LinkageForConstructionVTables,
AddressPoints);
}
@ -371,7 +383,7 @@ void
CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true);
VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true, Linkage);
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
const llvm::ArrayType *ArrayType =

View File

@ -3065,6 +3065,7 @@ llvm::GlobalVariable *
CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
const BaseSubobject &Base,
bool BaseIsVirtual,
llvm::GlobalVariable::LinkageTypes Linkage,
VTableAddressPointsMapTy& AddressPoints) {
VTableBuilder Builder(*this, Base.getBase(),
CGM.getContext().toBits(Base.getBaseOffset()),
@ -3093,8 +3094,11 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Create the variable that will hold the construction vtable.
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,
llvm::GlobalValue::InternalLinkage);
CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage);
CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForConstructionVTable);
// V-tables are always unnamed_addr.
VTable->setUnnamedAddr(true);
// Add the thunks.
VTableThunksTy VTableThunks;

View File

@ -1,4 +1,4 @@
//===--- CGVTables.h - Emit LLVM Code for C++ vtables ---------------------===//
//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -260,6 +260,7 @@ public:
llvm::GlobalVariable *
GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
bool BaseIsVirtual,
llvm::GlobalVariable::LinkageTypes Linkage,
VTableAddressPointsMapTy& AddressPoints);

View File

@ -313,6 +313,7 @@ public:
enum TypeVisibilityKind {
TVK_ForVTT,
TVK_ForVTable,
TVK_ForConstructionVTable,
TVK_ForRTTI,
TVK_ForRTTIName
};

View File

@ -5,8 +5,8 @@
// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant
// CHECK: @_ZTCSd0_Si = internal constant
// CHECK: @_ZTCSd16_So = internal constant
// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant
// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant
// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant