diff options
author | Fangrui Song <i@maskray.me> | 2021-01-27 10:43:51 -0800 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2021-01-27 10:43:51 -0800 |
commit | 54fb3ca96e261f7107cb1b5778c34cb0e0808be6 (patch) | |
tree | 8d6091e77327a0695d974602db03808433461666 /llvm/lib/LTO/LTO.cpp | |
parent | 0b50fa99452f7f3077e62348b6cf6850a65930af (diff) | |
download | llvm-54fb3ca96e261f7107cb1b5778c34cb0e0808be6.zip llvm-54fb3ca96e261f7107cb1b5778c34cb0e0808be6.tar.gz llvm-54fb3ca96e261f7107cb1b5778c34cb0e0808be6.tar.bz2 |
[ThinLTO] Add Visibility bits to GlobalValueSummary::GVFlags
Imported functions and variable get the visibility from the module supplying the
definition. However, non-imported definitions do not get the visibility from
(ELF) the most constraining visibility among all modules (Mach-O) the visibility
of the prevailing definition.
This patch
* adds visibility bits to GlobalValueSummary::GVFlags
* computes the result visibility and propagates it to all definitions
Protected/hidden can imply dso_local which can enable some optimizations (this
is stronger than GVFlags::DSOLocal because the implied dso_local can be
leveraged for ELF -shared while default visibility dso_local has to be cleared
for ELF -shared).
Note: we don't have summaries for declarations, so for ELF if a declaration has
the most constraining visibility, the result visibility may not be that one.
Differential Revision: https://reviews.llvm.org/D92900
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 9103d11..363a1e6 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -203,6 +203,7 @@ void llvm::computeLTOCacheKey( auto AddUsedThings = [&](GlobalValueSummary *GS) { if (!GS) return; + AddUnsigned(GS->getVisibility()); AddUnsigned(GS->isLive()); AddUnsigned(GS->canAutoHide()); for (const ValueInfo &VI : GS->refs()) { @@ -315,12 +316,16 @@ void llvm::computeLTOCacheKey( } static void thinLTOResolvePrevailingGUID( - ValueInfo VI, DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, + const Config &C, ValueInfo VI, + DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { + GlobalValue::VisibilityTypes Visibility = + C.VisibilityScheme == Config::ELF ? VI.getELFVisibility() + : GlobalValue::DefaultVisibility; for (auto &S : VI.getSummaryList()) { GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); // Ignore local and appending linkage values since the linker @@ -352,14 +357,33 @@ static void thinLTOResolvePrevailingGUID( S->setCanAutoHide(VI.canAutoHide() && !GUIDPreservedSymbols.count(VI.getGUID())); } + if (C.VisibilityScheme == Config::FromPrevailing) + Visibility = S->getVisibility(); } // Alias and aliasee can't be turned into available_externally. else if (!isa<AliasSummary>(S.get()) && !GlobalInvolvedWithAlias.count(S.get())) S->setLinkage(GlobalValue::AvailableExternallyLinkage); + + // For ELF, set visibility to the computed visibility from summaries. We + // don't track visibility from declarations so this may be more relaxed than + // the most constraining one. + if (C.VisibilityScheme == Config::ELF) + S->setVisibility(Visibility); + if (S->linkage() != OriginalLinkage) recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage()); } + + if (C.VisibilityScheme == Config::FromPrevailing) { + for (auto &S : VI.getSummaryList()) { + GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); + if (GlobalValue::isLocalLinkage(OriginalLinkage) || + GlobalValue::isAppendingLinkage(S->linkage())) + continue; + S->setVisibility(Visibility); + } + } } /// Resolve linkage for prevailing symbols in the \p Index. @@ -369,7 +393,7 @@ static void thinLTOResolvePrevailingGUID( // referencing them because of the import. We make sure we always emit at least // one copy. void llvm::thinLTOResolvePrevailingInIndex( - ModuleSummaryIndex &Index, + const Config &C, ModuleSummaryIndex &Index, function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> @@ -385,9 +409,9 @@ void llvm::thinLTOResolvePrevailingInIndex( GlobalInvolvedWithAlias.insert(&AS->getAliasee()); for (auto &I : Index) - thinLTOResolvePrevailingGUID(Index.getValueInfo(I), GlobalInvolvedWithAlias, - isPrevailing, recordNewLinkage, - GUIDPreservedSymbols); + thinLTOResolvePrevailingGUID(C, Index.getValueInfo(I), + GlobalInvolvedWithAlias, isPrevailing, + recordNewLinkage, GUIDPreservedSymbols); } static bool isWeakObjectWithRWAccess(GlobalValueSummary *GVS) { @@ -587,8 +611,11 @@ Error LTO::add(std::unique_ptr<InputFile> Input, if (Conf.ResolutionFile) writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); - if (RegularLTO.CombinedModule->getTargetTriple().empty()) + if (RegularLTO.CombinedModule->getTargetTriple().empty()) { RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple()); + if (Triple(Input->getTargetTriple()).isOSBinFormatELF()) + Conf.VisibilityScheme = Config::ELF; + } const SymbolResolution *ResI = Res.begin(); for (unsigned I = 0; I != Input->Mods.size(); ++I) @@ -1441,7 +1468,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, GlobalValue::LinkageTypes NewLinkage) { ResolvedODR[ModuleIdentifier][GUID] = NewLinkage; }; - thinLTOResolvePrevailingInIndex(ThinLTO.CombinedIndex, isPrevailing, + thinLTOResolvePrevailingInIndex(Conf, ThinLTO.CombinedIndex, isPrevailing, recordNewLinkage, GUIDPreservedSymbols); generateParamAccessSummary(ThinLTO.CombinedIndex); |