Skip to content

Commit 79cd239

Browse files
authored
Merge pull request swiftlang#33454 from compnerd/comdat-cleanup
IRGen: be less aggressive about applying COMDAT
2 parents 53455a7 + fc164ce commit 79cd239

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)