/// Run internalization on \p TheModule based on symmary analysis. void llvm::thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { // Parse inline ASM and collect the list of symbols that are not defined in // the current module. StringSet<> AsmUndefinedRefs; ModuleSymbolTable::CollectAsmSymbols( Triple(TheModule.getTargetTriple()), TheModule.getModuleInlineAsm(), [&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) { if (Flags & object::BasicSymbolRef::SF_Undefined) AsmUndefinedRefs.insert(Name); }); // Declare a callback for the internalize pass that will ask for every // candidate GlobalValue if it can be internalized or not. auto MustPreserveGV = [&](const GlobalValue &GV) -> bool { // Can't be internalized if referenced in inline asm. if (AsmUndefinedRefs.count(GV.getName())) return true; // Lookup the linkage recorded in the summaries during global analysis. const auto &GS = DefinedGlobals.find(GV.getGUID()); GlobalValue::LinkageTypes Linkage; if (GS == DefinedGlobals.end()) { // Must have been promoted (possibly conservatively). Find original // name so that we can access the correct summary and see if it can // be internalized again. // FIXME: Eventually we should control promotion instead of promoting // and internalizing again. StringRef OrigName = ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName()); std::string OrigId = GlobalValue::getGlobalIdentifier( OrigName, GlobalValue::InternalLinkage, TheModule.getSourceFileName()); const auto &GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId)); if (GS == DefinedGlobals.end()) { // Also check the original non-promoted non-globalized name. In some // cases a preempted weak value is linked in as a local copy because // it is referenced by an alias (IRLinker::linkGlobalValueProto). // In that case, since it was originally not a local value, it was // recorded in the index using the original name. // FIXME: This may not be needed once PR27866 is fixed. const auto &GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName)); assert(GS != DefinedGlobals.end()); Linkage = GS->second->linkage(); } else { Linkage = GS->second->linkage(); } } else Linkage = GS->second->linkage(); return !GlobalValue::isLocalLinkage(Linkage); }; // FIXME: See if we can just internalize directly here via linkage changes // based on the index, rather than invoking internalizeModule. llvm::internalizeModule(TheModule, MustPreserveGV); }
/// Fixup WeakForLinker linkages in \p TheModule based on summary analysis. void llvm::thinLTOResolveWeakForLinkerModule( Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { auto updateLinkage = [&](GlobalValue &GV) { if (!GlobalValue::isWeakForLinker(GV.getLinkage())) return; // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); if (GS == DefinedGlobals.end()) return; auto NewLinkage = GS->second->linkage(); if (NewLinkage == GV.getLinkage()) return; DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " << GV.getLinkage() << " to " << NewLinkage << "\n"); GV.setLinkage(NewLinkage); // Remove functions converted to available_externally 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_or_null<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { assert(GO->hasAvailableExternallyLinkage() && "Expected comdat on definition (possibly available external)"); GO->setComdat(nullptr); } }; // Process functions and global now for (auto &GV : TheModule) updateLinkage(GV); for (auto &GV : TheModule.globals()) updateLinkage(GV); for (auto &GV : TheModule.aliases()) updateLinkage(GV); }
/// Fixup WeakForLinker linkages in \p TheModule based on summary analysis. void llvm::thinLTOResolveWeakForLinkerModule( Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { auto updateLinkage = [&](GlobalValue &GV) { if (!GlobalValue::isWeakForLinker(GV.getLinkage())) return; // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); if (GS == DefinedGlobals.end()) return; auto NewLinkage = GS->second->linkage(); if (NewLinkage == GV.getLinkage()) return; DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " << GV.getLinkage() << " to " << NewLinkage << "\n"); GV.setLinkage(NewLinkage); }; // Process functions and global now for (auto &GV : TheModule) updateLinkage(GV); for (auto &GV : TheModule.globals()) updateLinkage(GV); for (auto &GV : TheModule.aliases()) updateLinkage(GV); }