static bool shouldInternalize(const GlobalValue &GV, const std::set<std::string> &ExternalNames, const std::set<std::string> &DSONames) { // Function must be defined here if (GV.isDeclaration()) return false; // Available externally is really just a "declaration with a body". if (GV.hasAvailableExternallyLinkage()) return false; // Already has internal linkage if (GV.hasLocalLinkage()) return false; // Marked to keep external? if (ExternalNames.count(GV.getName())) return false; // Not needed for the symbol table? if (!DSONames.count(GV.getName())) return true; // Not a linkonce. Someone can depend on it being on the symbol table. if (!GV.hasLinkOnceLinkage()) return false; // The address is not important, we can hide it. if (GV.hasUnnamedAddr()) return true; // FIXME: Check if the address is used. return false; }
bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { GlobalValue *DGV = getLinkedToGlobal(&GV); if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) return false; if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { auto *DGVar = dyn_cast<GlobalVariable>(DGV); auto *SGVar = dyn_cast<GlobalVariable>(&GV); if (DGVar && SGVar) { if (DGVar->isDeclaration() && SGVar->isDeclaration() && (!DGVar->isConstant() || !SGVar->isConstant())) { DGVar->setConstant(false); SGVar->setConstant(false); } if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment()); SGVar->setAlignment(Align); DGVar->setAlignment(Align); } } GlobalValue::VisibilityTypes Visibility = getMinVisibility(DGV->getVisibility(), GV.getVisibility()); DGV->setVisibility(Visibility); GV.setVisibility(Visibility); bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr(); DGV->setUnnamedAddr(HasUnnamedAddr); GV.setUnnamedAddr(HasUnnamedAddr); } // Don't want to append to global_ctors list, for example, when we // are importing for ThinLTO, otherwise the global ctors and dtors // get executed multiple times for local variables (the latter causing // double frees). if (GV.hasAppendingLinkage() && isPerformingImport()) return false; if (isPerformingImport()) { if (!doImportAsDefinition(&GV)) return false; } else if (!DGV && !shouldOverrideFromSrc() && (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || GV.hasAvailableExternallyLinkage())) return false; if (GV.isDeclaration()) return false; if (const Comdat *SC = GV.getComdat()) { bool LinkFromSrc; Comdat::SelectionKind SK; std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; if (!LinkFromSrc) return false; } bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) return true; if (LinkFromSrc) ValuesToLink.insert(&GV); return false; }