/// Make sure GV is visible from both modules. Delete is true if it is /// being deleted from this module. /// This also makes sure GV cannot be dropped so that references from /// the split module remain valid. static void makeVisible(GlobalValue &GV, bool Delete) { bool Local = GV.hasLocalLinkage(); if (Local) GV.setVisibility(GlobalValue::HiddenVisibility); if (Local || Delete) { GV.setLinkage(GlobalValue::ExternalLinkage); return; } if (!GV.hasLinkOnceLinkage()) { assert(!GV.isDiscardableIfUnused()); return; } // Map linkonce* to weak* so that llvm doesn't drop this GV. switch(GV.getLinkage()) { default: llvm_unreachable("Unexpected linkage"); case GlobalValue::LinkOnceAnyLinkage: GV.setLinkage(GlobalValue::WeakAnyLinkage); return; case GlobalValue::LinkOnceODRLinkage: GV.setLinkage(GlobalValue::WeakODRLinkage); return; } }
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; }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { if (!shouldLinkReferencedLinkOnce()) // For ThinLTO we don't import more than what was required. // The client has to guarantee that the linkonce will be availabe at link // time (by promoting it to weak for instance). return; // Add these to the internalize list if (!GV.hasLinkOnceLinkage() && !shouldLinkOnlyNeeded()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return; if (!LinkFromSrc) continue; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
/// Make sure GV is visible from both modules. Delete is true if it is /// being deleted from this module. /// This also makes sure GV cannot be dropped so that references from /// the split module remain valid. static void makeVisible(GlobalValue &GV, bool Delete, bool IsDeletePass) { bool Local = GV.hasLocalLinkage(); if (Local || Delete) { // This changes members from private -> hidden -> causes linker errors when using llvm-link if (!IsDeletePass) GV.setLinkage(GlobalValue::ExternalLinkage); if (Local) GV.setVisibility(GlobalValue::HiddenVisibility); return; } if (!GV.hasLinkOnceLinkage()) { assert(!GV.isDiscardableIfUnused()); return; } // Map linkonce* to weak* so that llvm doesn't drop this GV. switch(GV.getLinkage()) { default: llvm_unreachable("Unexpected linkage"); case GlobalValue::LinkOnceAnyLinkage: GV.setLinkage(GlobalValue::WeakAnyLinkage); return; case GlobalValue::LinkOnceODRLinkage: GV.setLinkage(GlobalValue::WeakODRLinkage); return; } }
static char TypeCharForSymbol(GlobalValue &GV) { if (GV.isDeclaration()) return 'U'; if (GV.hasLinkOnceLinkage()) return 'C'; if (GV.hasCommonLinkage()) return 'C'; if (GV.hasWeakLinkage()) return 'W'; if (isa<Function>(GV) && GV.hasInternalLinkage()) return 't'; if (isa<Function>(GV)) return 'T'; if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage()) return 'd'; if (isa<GlobalVariable>(GV)) return 'D'; if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) { const GlobalValue *AliasedGV = GA->getAliasedGlobal(); if (isa<Function>(AliasedGV)) return 'T'; if (isa<GlobalVariable>(AliasedGV)) return 'D'; } return '?'; }
JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) { JITSymbolFlags Flags = JITSymbolFlags::None; if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage()) Flags |= JITSymbolFlags::Weak; if (GV.hasCommonLinkage()) Flags |= JITSymbolFlags::Common; if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) Flags |= JITSymbolFlags::Exported; if (isa<Function>(GV)) Flags |= JITSymbolFlags::Callable; else if (isa<GlobalAlias>(GV) && isa<Function>(cast<GlobalAlias>(GV).getAliasee())) Flags |= JITSymbolFlags::Callable; return Flags; }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { // Add these to the internalize list if (!GV.hasLinkOnceLinkage()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : ComdatMembers[SC]) { if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { // Add these to the internalize list if (!GV.hasLinkOnceLinkage()) return; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV.getName()); Add(GV); const Comdat *SC = GV.getComdat(); if (!SC) return; for (GlobalValue *GV2 : LazyComdatMembers[SC]) { GlobalValue *DGV = getLinkedToGlobal(GV2); bool LinkFromSrc = true; if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) return; if (!LinkFromSrc) continue; if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } }
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::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { // Should we unconditionally use the Src? if (shouldOverrideFromSrc()) { LinkFromSrc = true; return false; } // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { // Should have prevented importing for appending linkage in linkIfNeeded. assert(!isPerformingImport()); LinkFromSrc = true; return false; } if (isPerformingImport()) { // LinkFromSrc iff this is a global requested for importing. LinkFromSrc = GlobalsToImport->count(&Src); return false; } bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. if (Src.hasDLLImportStorageClass()) { // If one of GVs is marked as DLLImport, result should be dllimport'ed. LinkFromSrc = DestIsDeclaration; return false; } // If the Dest is weak, use the source linkage. if (Dest.hasExternalWeakLinkage()) { LinkFromSrc = true; return false; } // Link an available_externally over a declaration. LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); return false; } if (DestIsDeclaration) { // If Dest is external but Src is not: LinkFromSrc = true; return false; } if (Src.hasCommonLinkage()) { if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { LinkFromSrc = true; return false; } if (!Dest.hasCommonLinkage()) { LinkFromSrc = false; return false; } const DataLayout &DL = Dest.getParent()->getDataLayout(); uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } if (Src.isWeakForLinker()) { assert(!Dest.hasExternalWeakLinkage()); assert(!Dest.hasAvailableExternallyLinkage()); if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { LinkFromSrc = true; return false; } LinkFromSrc = false; return false; } if (Dest.isWeakForLinker()) { assert(Src.hasExternalLinkage()); LinkFromSrc = true; return false; } assert(!Src.hasExternalWeakLinkage()); assert(!Dest.hasExternalWeakLinkage()); assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && "Unexpected linkage type!"); return emitError("Linking globals named '" + Src.getName() + "': symbol multiply defined!"); }
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { // Should we unconditionally use the Src? if (shouldOverrideFromSrc()) { LinkFromSrc = true; return false; } // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { // Should have prevented importing for appending linkage in linkIfNeeded. assert(!isPerformingImport()); LinkFromSrc = true; return false; } bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); if (isPerformingImport()) { if (isa<Function>(&Src)) { // For functions, LinkFromSrc iff this is a function requested // for importing. For variables, decide below normally. LinkFromSrc = GlobalsToImport->count(&Src); return false; } // Check if this is an alias with an already existing definition // in Dest, which must have come from a prior importing pass from // the same Src module. Unlike imported function and variable // definitions, which are imported as available_externally and are // not definitions for the linker, that is not a valid linkage for // imported aliases which must be definitions. Simply use the existing // Dest copy. if (isa<GlobalAlias>(&Src) && !DestIsDeclaration) { assert(isa<GlobalAlias>(&Dest)); LinkFromSrc = false; return false; } } if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. if (Src.hasDLLImportStorageClass()) { // If one of GVs is marked as DLLImport, result should be dllimport'ed. LinkFromSrc = DestIsDeclaration; return false; } // If the Dest is weak, use the source linkage. if (Dest.hasExternalWeakLinkage()) { LinkFromSrc = true; return false; } // Link an available_externally over a declaration. LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); return false; } if (DestIsDeclaration) { // If Dest is external but Src is not: LinkFromSrc = true; return false; } if (Src.hasCommonLinkage()) { if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { LinkFromSrc = true; return false; } if (!Dest.hasCommonLinkage()) { LinkFromSrc = false; return false; } const DataLayout &DL = Dest.getParent()->getDataLayout(); uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } if (Src.isWeakForLinker()) { assert(!Dest.hasExternalWeakLinkage()); assert(!Dest.hasAvailableExternallyLinkage()); if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { LinkFromSrc = true; return false; } LinkFromSrc = false; return false; } if (Dest.isWeakForLinker()) { assert(Src.hasExternalLinkage()); LinkFromSrc = true; return false; } assert(!Src.hasExternalWeakLinkage()); assert(!Dest.hasExternalWeakLinkage()); assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && "Unexpected linkage type!"); return emitError("Linking globals named '" + Src.getName() + "': symbol multiply defined!"); }