Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 1d11866

Browse files
committed
Use a trivial comdat for C++ tables.
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
1 parent 8a91585 commit 1d11866

File tree

4 files changed

+38
-25
lines changed

4 files changed

+38
-25
lines changed

lib/CodeGen/CGVTT.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
9494
// Set the correct linkage.
9595
VTT->setLinkage(Linkage);
9696

97+
if (CGM.supportsCOMDAT() && VTT->isWeakForLinker())
98+
VTT->setComdat(CGM.getModule().getOrInsertComdat(VTT->getName()));
99+
97100
// Set the right visibility.
98101
CGM.setGlobalVisibility(VTT, RD);
99102
}

lib/CodeGen/CodeGenModule.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,10 @@ CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name,
18281828

18291829
OldGV->eraseFromParent();
18301830
}
1831-
1831+
1832+
if (supportsCOMDAT() && GV->isWeakForLinker())
1833+
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
1834+
18321835
return GV;
18331836
}
18341837

lib/CodeGen/ItaniumCXXABI.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,9 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
12561256
// Set the correct linkage.
12571257
VTable->setLinkage(Linkage);
12581258

1259+
if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1260+
VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1261+
12591262
// Set the right visibility.
12601263
CGM.setGlobalVisibility(VTable, RD);
12611264

@@ -2716,9 +2719,13 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
27162719

27172720
llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
27182721

2722+
llvm::Module &M = CGM.getModule();
27192723
llvm::GlobalVariable *GV =
2720-
new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
2721-
/*Constant=*/true, Linkage, Init, Name);
2724+
new llvm::GlobalVariable(M, Init->getType(),
2725+
/*Constant=*/true, Linkage, Init, Name);
2726+
2727+
if (CGM.supportsCOMDAT() && GV->isWeakForLinker())
2728+
GV->setComdat(M.getOrInsertComdat(GV->getName()));
27222729

27232730
// If there's already an old global variable, replace it with the new one.
27242731
if (OldGV) {

test/CodeGenCXX/vtable-linkage.cpp

+22-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t
1+
// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t
22
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt
33
// RUN: FileCheck --check-prefix=CHECK %s < %t
44
// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
@@ -89,10 +89,10 @@ void use_F() {
8989

9090
// C has no key function, so its vtable should have weak_odr linkage
9191
// and hidden visibility (rdar://problem/7523229).
92-
// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant
93-
// CHECK-DAG: @_ZTS1C = linkonce_odr constant
94-
// CHECK-DAG: @_ZTI1C = linkonce_odr constant
95-
// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant
92+
// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat,
93+
// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat{{$}}
94+
// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat{{$}}
95+
// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat{{$}}
9696

9797
// D has a key function that is defined in this translation unit so its vtable is
9898
// defined in the translation unit.
@@ -110,28 +110,28 @@ void use_F() {
110110
// E<short> is an explicit template instantiation with a key function
111111
// defined in this translation unit, so its vtable should have
112112
// weak_odr linkage.
113-
// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
114-
// CHECK-DAG: @_ZTS1EIsE = weak_odr constant
115-
// CHECK-DAG: @_ZTI1EIsE = weak_odr constant
113+
// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
114+
// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat{{$}}
115+
// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat{{$}}
116116

117117
// F<short> is an explicit template instantiation without a key
118118
// function, so its vtable should have weak_odr linkage
119-
// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
120-
// CHECK-DAG: @_ZTS1FIsE = weak_odr constant
121-
// CHECK-DAG: @_ZTI1FIsE = weak_odr constant
119+
// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
120+
// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat{{$}}
121+
// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat{{$}}
122122

123123
// E<long> is an implicit template instantiation with a key function
124124
// defined in this translation unit, so its vtable should have
125125
// linkonce_odr linkage.
126-
// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant
127-
// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant
128-
// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant
126+
// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
127+
// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
128+
// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat{{$}}
129129

130130
// F<long> is an implicit template instantiation with no key function,
131131
// so its vtable should have linkonce_odr linkage.
132-
// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant
133-
// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant
134-
// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant
132+
// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
133+
// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
134+
// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat{{$}}
135135

136136
// F<int> is an explicit template instantiation declaration without a
137137
// key function, so its vtable should have external linkage.
@@ -158,11 +158,11 @@ void use_F() {
158158

159159
// F<char> is an explicit specialization without a key function, so
160160
// its vtable should have linkonce_odr linkage.
161-
// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant
162-
// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant
163-
// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant
161+
// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
162+
// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
163+
// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat{{$}}
164164

165-
// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant
165+
// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
166166
template <typename T>
167167
class G {
168168
public:
@@ -178,7 +178,7 @@ void G_f0() { new G<int>(); }
178178

179179
// H<int> has a key function without a body but it's a template instantiation
180180
// so its VTable must be emitted.
181-
// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant
181+
// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
182182
template <typename T>
183183
class H {
184184
public:

0 commit comments

Comments
 (0)