Skip to content

Commit fc164ce

Browse files
committed
IRGen: be less aggressive about applying COMDAT
COMDAT can only be applied to definitions, not declarations. This manifested in builds of llbuild with SwiftPM on Windows. The nominal type descriptor accessor declaration was marked as COMDAT.
1 parent 142aa5f commit fc164ce

File tree

7 files changed

+40
-12
lines changed

7 files changed

+40
-12
lines changed

include/swift/IRGen/Linking.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,7 @@ class ApplyIRLinkage {
12311231
IRLinkage IRL;
12321232
public:
12331233
ApplyIRLinkage(IRLinkage IRL) : IRL(IRL) {}
1234-
void to(llvm::GlobalValue *GV) const {
1234+
void to(llvm::GlobalValue *GV, bool definition = true) const {
12351235
llvm::Module *M = GV->getParent();
12361236
const llvm::Triple Triple(M->getTargetTriple());
12371237

@@ -1244,11 +1244,14 @@ class ApplyIRLinkage {
12441244
if (Triple.isOSBinFormatELF())
12451245
return;
12461246

1247-
if (IRL.Linkage == llvm::GlobalValue::LinkOnceODRLinkage ||
1248-
IRL.Linkage == llvm::GlobalValue::WeakODRLinkage)
1249-
if (Triple.supportsCOMDAT())
1250-
if (llvm::GlobalObject *GO = dyn_cast<llvm::GlobalObject>(GV))
1251-
GO->setComdat(M->getOrInsertComdat(GV->getName()));
1247+
// COMDATs cannot be applied to declarations. If we have a definition,
1248+
// apply the COMDAT.
1249+
if (definition)
1250+
if (IRL.Linkage == llvm::GlobalValue::LinkOnceODRLinkage ||
1251+
IRL.Linkage == llvm::GlobalValue::WeakODRLinkage)
1252+
if (Triple.supportsCOMDAT())
1253+
if (llvm::GlobalObject *GO = dyn_cast<llvm::GlobalObject>(GV))
1254+
GO->setComdat(M->getOrInsertComdat(GV->getName()));
12521255
}
12531256
};
12541257

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,8 +2024,10 @@ llvm::Function *irgen::createFunction(IRGenModule &IGM,
20242024
IGM.Module.getFunctionList().push_back(fn);
20252025
}
20262026

2027-
ApplyIRLinkage({linkInfo.getLinkage(), linkInfo.getVisibility(), linkInfo.getDLLStorage()})
2028-
.to(fn);
2027+
ApplyIRLinkage({linkInfo.getLinkage(),
2028+
linkInfo.getVisibility(),
2029+
linkInfo.getDLLStorage()})
2030+
.to(fn, linkInfo.isForDefinition());
20292031

20302032
llvm::AttrBuilder initialAttrs;
20312033
IGM.constructInitialFnAttributes(initialAttrs, FuncOptMode);
@@ -2082,7 +2084,7 @@ llvm::GlobalVariable *swift::irgen::createVariable(
20822084
ApplyIRLinkage({linkInfo.getLinkage(),
20832085
linkInfo.getVisibility(),
20842086
linkInfo.getDLLStorage()})
2085-
.to(var);
2087+
.to(var, linkInfo.isForDefinition());
20862088
var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
20872089

20882090
// Everything externally visible is considered used in Swift.
@@ -4742,7 +4744,7 @@ IRGenModule::getAddrOfWitnessTableLazyAccessFunction(
47424744
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
47434745
entry = createFunction(*this, link, signature);
47444746
ApplyIRLinkage({link.getLinkage(), link.getVisibility(), link.getDLLStorage()})
4745-
.to(entry);
4747+
.to(entry, link.isForDefinition());
47464748
return entry;
47474749
}
47484750

lib/IRGen/GenKeyPath.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ void IRGenModule::emitSILProperty(SILProperty *prop) {
13291329
ApplyIRLinkage({linkInfo.getLinkage(),
13301330
linkInfo.getVisibility(),
13311331
llvm::GlobalValue::DLLExportStorageClass})
1332-
.to(GA);
1332+
.to(GA, linkInfo.isForDefinition());
13331333
}
13341334
return;
13351335
}

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3635,7 +3635,7 @@ static void emitObjCClassSymbol(IRGenModule &IGM,
36353635
ptrTy->getElementType(), ptrTy->getAddressSpace(), link.getLinkage(),
36363636
link.getName(), metadata, &IGM.Module);
36373637
ApplyIRLinkage({link.getLinkage(), link.getVisibility(), link.getDLLStorage()})
3638-
.to(alias);
3638+
.to(alias, link.isForDefinition());
36393639
}
36403640

36413641
/// Emit the type metadata or metadata template for a class.

test/IRGen/Inputs/comdat1.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
private final class C {}
2+
public func f() {
3+
var cs: [C] = []
4+
cs.append(C())
5+
}

test/IRGen/Inputs/comdat2.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public func g() {
2+
var a: [Int] = []
3+
a.append(1)
4+
}

test/IRGen/comdat.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-ir %S/Inputs/comdat1.swift %S/Inputs/comdat2.swift -O -num-threads 1 -module-name comdat -o %t/comdat1.ll -o %t/comdat2.ll
3+
// RUN: %FileCheck -check-prefix CHECK-1 %s < %t/comdat1.ll
4+
// RUN: %FileCheck -check-prefix CHECK-2 %s < %t/comdat2.ll
5+
6+
// REQUIRES: OS=windows-msvc
7+
8+
// Ensure that the definition is marked as COMDAT
9+
// CHECK-1: "$s6comdat1C33_{{.*}}LLCMa" = comdat any
10+
// CHECK-1: "$s6comdat1C33_{{.*}}LLCMn" = comdat any
11+
12+
// Ensure that no foward declaration is emitted
13+
// CHECK-2-NOT: "$s6comdat1C33_{{.*}}LLCMa" = comdat any
14+
// CHECK-2-NOT: "$s6comdat1C33_{{.*}}LLCMn" = comdat any

0 commit comments

Comments
 (0)