diff options
author | Teresa Johnson <tejohnson@google.com> | 2016-05-25 14:03:11 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2016-05-25 14:03:11 +0000 |
commit | 04c9a2d63d26ea0751bb80fa6063a5b0063532ed (patch) | |
tree | d3e6c1a9e26d5ed6fa39262aee50e300ef141233 /llvm/lib/LTO/ThinLTOCodeGenerator.cpp | |
parent | c249167e9014ff6af79d4755965e1d8f79d7ae32 (diff) | |
download | llvm-04c9a2d63d26ea0751bb80fa6063a5b0063532ed.zip llvm-04c9a2d63d26ea0751bb80fa6063a5b0063532ed.tar.gz llvm-04c9a2d63d26ea0751bb80fa6063a5b0063532ed.tar.bz2 |
[ThinLTO] Refactor ODR resolution and internalization (NFC)
Move the now index-based ODR resolution and internalization routines out
of ThinLTOCodeGenerator.cpp and into either LTO.cpp (index-based
analysis) or FunctionImport.cpp (index-driven optimizations).
This is to enable usage by other linkers.
llvm-svn: 270698
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 5c74d72..8baab57 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, |