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; }
bool ModuleLinker::run() { Module &DstM = Mover.getModule(); DenseSet<const Comdat *> ReplacedDstComdats; for (const auto &SMEC : SrcM->getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; Comdat::SelectionKind SK; bool LinkFromSrc; if (getComdatResult(&C, SK, LinkFromSrc)) return true; ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); if (!LinkFromSrc) continue; Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); if (DstCI == ComdatSymTab.end()) continue; // The source comdat is replacing the dest one. const Comdat *DstC = &DstCI->second; ReplacedDstComdats.insert(DstC); } // Alias have to go first, since we are not able to find their comdats // otherwise. for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { GlobalAlias &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { GlobalVariable &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (auto I = DstM.begin(), E = DstM.end(); I != E;) { Function &GV = *I++; dropReplacedComdat(GV, ReplacedDstComdats); } for (GlobalVariable &GV : SrcM->globals()) if (GV.hasLinkOnceLinkage()) if (const Comdat *SC = GV.getComdat()) LazyComdatMembers[SC].push_back(&GV); for (Function &SF : *SrcM) if (SF.hasLinkOnceLinkage()) if (const Comdat *SC = SF.getComdat()) LazyComdatMembers[SC].push_back(&SF); for (GlobalAlias &GA : SrcM->aliases()) if (GA.hasLinkOnceLinkage()) if (const Comdat *SC = GA.getComdat()) LazyComdatMembers[SC].push_back(&GA); // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (GlobalVariable &GV : SrcM->globals()) if (linkIfNeeded(GV)) return true; for (Function &SF : *SrcM) if (linkIfNeeded(SF)) return true; for (GlobalAlias &GA : SrcM->aliases()) if (linkIfNeeded(GA)) return true; for (unsigned I = 0; I < ValuesToLink.size(); ++I) { GlobalValue *GV = ValuesToLink[I]; const Comdat *SC = GV->getComdat(); if (!SC) continue; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return true; if (LinkFromSrc) ValuesToLink.insert(GV2); } } if (shouldInternalizeLinkedSymbols()) { for (GlobalValue *GV : ValuesToLink) Internalize.insert(GV->getName()); } // FIXME: Propagate Errors through to the caller instead of emitting // diagnostics. bool HasErrors = false; if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), [this](GlobalValue &GV, IRMover::ValueAdder Add) { addLazyFor(GV, Add); }, !isPerformingImport())) { handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); HasErrors = true; }); } if (HasErrors) return true; for (auto &P : Internalize) { GlobalValue *GV = DstM.getNamedValue(P.first()); GV->setLinkage(GlobalValue::InternalLinkage); } return false; }
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { ValueInfo VI; if (GV.hasName()) { VI = ImportIndex.getValueInfo(GV.getGUID()); // Set synthetic function entry counts. if (VI && ImportIndex.hasSyntheticEntryCounts()) { if (Function *F = dyn_cast<Function>(&GV)) { if (!F->isDeclaration()) { for (auto &S : VI.getSummaryList()) { FunctionSummary *FS = dyn_cast<FunctionSummary>(S->getBaseObject()); if (FS->modulePath() == M.getModuleIdentifier()) { F->setEntryCount(Function::ProfileCount(FS->entryCount(), Function::PCT_Synthetic)); break; } } } } } // Check the summaries to see if the symbol gets resolved to a known local // definition. if (VI && VI.isDSOLocal()) { GV.setDSOLocal(true); if (GV.hasDLLImportStorageClass()) GV.setDLLStorageClass(GlobalValue::DefaultStorageClass); } } // Mark read-only variables which can be imported with specific attribute. // We can't internalize them now because IRMover will fail to link variable // definitions to their external declarations during ThinLTO import. We'll // internalize read-only variables later, after import is finished. // See internalizeImmutableGVs. // // If global value dead stripping is not enabled in summary then // propagateConstants hasn't been run. We can't internalize GV // in such case. if (!GV.isDeclaration() && VI && ImportIndex.withGlobalValueDeadStripping()) { const auto &SL = VI.getSummaryList(); auto *GVS = SL.empty() ? nullptr : dyn_cast<GlobalVarSummary>(SL[0].get()); if (GVS && GVS->isReadOnly()) cast<GlobalVariable>(&GV)->addAttribute("thinlto-internalize"); } bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { // Save the original name string before we rename GV below. auto Name = GV.getName().str(); // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, // use DoPromote result saved above. GV.setName(getName(&GV, DoPromote)); GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); // If we are renaming a COMDAT leader, ensure that we record the COMDAT // for later renaming as well. This is required for COFF. if (const auto *C = GV.getComdat()) if (C->getName() == Name) RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName())); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); // Remove functions imported as available externally defs from comdats, // as this is a declaration for the linker, and will be dropped eventually. // It is illegal for comdats to contain declarations. auto *GO = dyn_cast<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { // The IRMover should not have placed any imported declarations in // a comdat, so the only declaration that should be in a comdat // at this point would be a definition imported as available_externally. assert(GO->hasAvailableExternallyLinkage() && "Expected comdat on definition (possibly available external)"); GO->setComdat(nullptr); } }
bool ModuleLinker::run() { for (const auto &SMEC : SrcM.getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; Comdat::SelectionKind SK; bool LinkFromSrc; if (getComdatResult(&C, SK, LinkFromSrc)) return true; ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); } for (GlobalVariable &GV : SrcM.globals()) if (const Comdat *SC = GV.getComdat()) ComdatMembers[SC].push_back(&GV); for (Function &SF : SrcM) if (const Comdat *SC = SF.getComdat()) ComdatMembers[SC].push_back(&SF); for (GlobalAlias &GA : SrcM.aliases()) if (const Comdat *SC = GA.getComdat()) ComdatMembers[SC].push_back(&GA); // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (GlobalVariable &GV : SrcM.globals()) if (linkIfNeeded(GV)) return true; for (Function &SF : SrcM) if (linkIfNeeded(SF)) return true; for (GlobalAlias &GA : SrcM.aliases()) if (linkIfNeeded(GA)) return true; if (ImportIndex) { ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex, FunctionsToImport); if (ThinLTOProcessing.run()) return true; for (auto *GV : ThinLTOProcessing.getNewExportedValues()) ValuesToLink.insert(GV); } for (unsigned I = 0; I < ValuesToLink.size(); ++I) { GlobalValue *GV = ValuesToLink[I]; const Comdat *SC = GV->getComdat(); if (!SC) continue; for (GlobalValue *GV2 : ComdatMembers[SC]) ValuesToLink.insert(GV2); } if (shouldInternalizeLinkedSymbols()) { for (GlobalValue *GV : ValuesToLink) Internalize.insert(GV->getName()); } if (Mover.move(SrcM, ValuesToLink.getArrayRef(), [this](GlobalValue &GV, IRMover::ValueAdder Add) { addLazyFor(GV, Add); }, ValIDToTempMDMap, false)) return true; Module &DstM = Mover.getModule(); for (auto &P : Internalize) { GlobalValue *GV = DstM.getNamedValue(P.first()); GV->setLinkage(GlobalValue::InternalLinkage); } return false; }