aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp
index 2f5fac4951f2..4fe1f1a0f518 100644
--- a/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp
+++ b/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp
@@ -462,6 +462,7 @@ void ModuleLinker::dropReplacedComdat(
bool ModuleLinker::run() {
Module &DstM = Mover.getModule();
DenseSet<const Comdat *> ReplacedDstComdats;
+ DenseSet<const Comdat *> NonPrevailingComdats;
for (const auto &SMEC : SrcM->getComdatSymbolTable()) {
const Comdat &C = SMEC.getValue();
@@ -473,6 +474,9 @@ bool ModuleLinker::run() {
return true;
ComdatsChosen[&C] = std::make_pair(SK, From);
+ if (From == LinkFrom::Dst)
+ NonPrevailingComdats.insert(&C);
+
if (From != LinkFrom::Src)
continue;
@@ -497,6 +501,23 @@ bool ModuleLinker::run() {
for (Function &GV : llvm::make_early_inc_range(DstM))
dropReplacedComdat(GV, ReplacedDstComdats);
+ if (!NonPrevailingComdats.empty()) {
+ DenseSet<GlobalObject *> AliasedGlobals;
+ for (auto &GA : SrcM->aliases())
+ if (GlobalObject *GO = GA.getAliaseeObject(); GO && GO->getComdat())
+ AliasedGlobals.insert(GO);
+ for (const Comdat *C : NonPrevailingComdats) {
+ SmallVector<GlobalObject *> ToUpdate;
+ for (GlobalObject *GO : C->getUsers())
+ if (GO->hasPrivateLinkage() && !AliasedGlobals.contains(GO))
+ ToUpdate.push_back(GO);
+ for (GlobalObject *GO : ToUpdate) {
+ GO->setLinkage(GlobalValue::AvailableExternallyLinkage);
+ GO->setComdat(nullptr);
+ }
+ }
+ }
+
for (GlobalVariable &GV : SrcM->globals())
if (GV.hasLinkOnceLinkage())
if (const Comdat *SC = GV.getComdat())