aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2021-01-27 10:43:51 -0800
committerFangrui Song <i@maskray.me>2021-01-27 10:43:51 -0800
commit54fb3ca96e261f7107cb1b5778c34cb0e0808be6 (patch)
tree8d6091e77327a0695d974602db03808433461666 /llvm/lib/LTO/LTO.cpp
parent0b50fa99452f7f3077e62348b6cf6850a65930af (diff)
downloadllvm-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.cpp41
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);