diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp | 21 | 
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())  | 
