diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 656ea4f4654..c3535b921c4 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -259,7 +259,15 @@ LLGlobalValue::LinkageTypes DtoLinkageOnly(Dsymbol *sym) { } LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) { - return {DtoLinkageOnly(sym), needsCOMDAT()}; + bool hasCOMDAT = needsCOMDAT(); + auto appliedLinkage = DtoLinkageOnly(sym); + + // generate COMDAT for templates to enable linking data culling + // See https://github.com/ldc-developers/ldc/issues/3589 . + if (sym->isInstantiated()) + hasCOMDAT |= appliedLinkage != LLGlobalValue::InternalLinkage; + + return {appliedLinkage, hasCOMDAT && supportsCOMDAT()}; } bool needsCOMDAT() { @@ -274,6 +282,18 @@ bool needsCOMDAT() { return global.params.targetTriple->isOSBinFormatCOFF(); } +bool supportsCOMDAT() { + const auto &triple = *global.params.targetTriple; + return !(triple.isOSBinFormatMachO() || +#if LDC_LLVM_VER >= 500 + triple.isOSBinFormatWasm() +#else + triple.getArch() == llvm::Triple::wasm32 || + triple.getArch() == llvm::Triple::wasm64 +#endif + ); +} + void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj) { obj->setLinkage(lwc.first); obj->setComdat(lwc.second ? gIR->module.getOrInsertComdat(obj->getName()) diff --git a/gen/tollvm.h b/gen/tollvm.h index f8e195d2ace..fa77f164dc6 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -68,6 +68,7 @@ typedef std::pair LinkageWithCOMDAT; LinkageWithCOMDAT DtoLinkage(Dsymbol *sym); bool needsCOMDAT(); +bool supportsCOMDAT(); void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj); // Sets linkage and visibility of the specified IR symbol based on the specified // D symbol.