diff options
Diffstat (limited to 'llvm/lib/LTO/ThinLTOCodeGenerator.cpp')
-rw-r--r-- | llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 5c74d72c25a..8baab57a796 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -128,112 +128,6 @@ static void computePrevailingCopies( } } -static void thinLTOResolveWeakForLinkerGUID( - GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, - DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, - std::function<bool(GlobalValue::GUID, const GlobalValueSummary *)> - isPrevailing, - std::function<bool(StringRef, GlobalValue::GUID)> isExported, - std::function<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> - recordNewLinkage) { - auto HasMultipleCopies = GVSummaryList.size() > 1; - - for (auto &S : GVSummaryList) { - if (GlobalInvolvedWithAlias.count(S.get())) - continue; - GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); - if (!GlobalValue::isWeakForLinker(OriginalLinkage)) - continue; - // We need to emit only one of these, the first module will keep it, - // but turned into a weak, while the others will drop it when possible. - if (!HasMultipleCopies) { - // Exported Linkonce needs to be promoted to not be discarded. - // FIXME: This should handle LinkOnceAny as well, but that should be a - // follow-on to the NFC restructuring: - // if (GlobalValue::isLinkOnceLinkage(OriginalLinkage) && - // isExported(S->modulePath(), GUID)) - // S->setLinkage(GlobalValue::getWeakLinkage( - // GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); - if (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) && - isExported(S->modulePath(), GUID)) - S->setLinkage(GlobalValue::WeakODRLinkage); - } else if (isPrevailing(GUID, S.get())) { - // FIXME: This should handle LinkOnceAny as well, but that should be a - // follow-on to the NFC restructuring: - // if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) - // S->setLinkage(GlobalValue::getWeakLinkage( - // GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); - if (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)) - S->setLinkage(GlobalValue::WeakODRLinkage); - } - // Alias can't be turned into available_externally. - else if (!isa<AliasSummary>(S.get()) && - (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) || - GlobalValue::isWeakODRLinkage(OriginalLinkage))) - S->setLinkage(GlobalValue::AvailableExternallyLinkage); - if (S->linkage() != OriginalLinkage) - recordNewLinkage(S->modulePath(), GUID, S->linkage()); - } -} - -// Resolve Weak and LinkOnce values in the \p Index. -// -// We'd like to drop these functions if they are no longer referenced in the -// current module. However there is a chance that another module is still -// referencing them because of the import. We make sure we always emit at least -// one copy. -void thinLTOResolveWeakForLinkerInIndex( - ModuleSummaryIndex &Index, - std::function<bool(GlobalValue::GUID, const GlobalValueSummary *)> - isPrevailing, - std::function<bool(StringRef, GlobalValue::GUID)> isExported, - std::function<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> - recordNewLinkage) { - if (Index.modulePaths().size() == 1) - // Nothing to do if we don't have multiple modules - return; - - // We won't optimize the globals that are referenced by an alias for now - // Ideally we should turn the alias into a global and duplicate the definition - // when needed. - DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; - for (auto &I : Index) - for (auto &S : I.second) - if (auto AS = dyn_cast<AliasSummary>(S.get())) - GlobalInvolvedWithAlias.insert(&AS->getAliasee()); - - for (auto &I : Index) - thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias, - isPrevailing, isExported, recordNewLinkage); -} - -/// Fixup WeakForLinker linkages in \p TheModule based on summary analysis. -void 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); -} - static StringMap<MemoryBufferRef> generateModuleMap(const std::vector<MemoryBufferRef> &Modules) { StringMap<MemoryBufferRef> ModuleMap; @@ -284,74 +178,6 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM) { PM.run(TheModule); } -static void thinLTOInternalizeAndPromoteGUID( - GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, - std::function<bool(StringRef, GlobalValue::GUID)> isExported) { - for (auto &S : GVSummaryList) { - if (isExported(S->modulePath(), GUID)) { - if (GlobalValue::isLocalLinkage(S->linkage())) - S->setLinkage(GlobalValue::ExternalLinkage); - } else if (!GlobalValue::isLocalLinkage(S->linkage())) - S->setLinkage(GlobalValue::InternalLinkage); - } -} - -// Update the linkages in the given \p Index to mark exported values -// as external and non-exported values as internal. -void thinLTOInternalizeAndPromoteInIndex( - ModuleSummaryIndex &Index, - std::function<bool(StringRef, GlobalValue::GUID)> isExported) { - for (auto &I : Index) - thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); -} - -// Run internalization on \p TheModule based on symmary analysis. -void 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; - object::IRObjectFile::CollectAsmUndefinedRefs( - 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)); - assert(GS != DefinedGlobals.end()); - 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); -} - // Convert the PreservedSymbols map from "Name" based to "GUID" based. static DenseSet<GlobalValue::GUID> computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols, |