Skip to content

Commit 54fb3ca

Browse files
committed
[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
1 parent 0b50fa9 commit 54fb3ca

34 files changed

+278
-142
lines changed

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ struct ValueInfo {
223223
return RefAndFlags.getPointer();
224224
}
225225

226+
/// Returns the most constraining visibility among summaries. The
227+
/// visibilities, ordered from least to most constraining, are: default,
228+
/// protected and hidden.
229+
GlobalValue::VisibilityTypes getELFVisibility() const;
230+
226231
bool isDSOLocal() const;
227232

228233
/// Checks if all copies are eligible for auto-hiding (have flag set).
@@ -294,6 +299,9 @@ class GlobalValueSummary {
294299
/// types based on global summary-based analysis.
295300
unsigned Linkage : 4;
296301

302+
/// Indicates the visibility.
303+
unsigned Visibility : 2;
304+
297305
/// Indicate if the global value cannot be imported (e.g. it cannot
298306
/// be renamed or references something that can't be renamed).
299307
unsigned NotEligibleToImport : 1;
@@ -322,10 +330,12 @@ class GlobalValueSummary {
322330

323331
/// Convenience Constructors
324332
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
333+
GlobalValue::VisibilityTypes Visibility,
325334
bool NotEligibleToImport, bool Live, bool IsLocal,
326335
bool CanAutoHide)
327-
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
328-
Live(Live), DSOLocal(IsLocal), CanAutoHide(CanAutoHide) {}
336+
: Linkage(Linkage), Visibility(Visibility),
337+
NotEligibleToImport(NotEligibleToImport), Live(Live),
338+
DSOLocal(IsLocal), CanAutoHide(CanAutoHide) {}
329339
};
330340

331341
private:
@@ -410,6 +420,13 @@ class GlobalValueSummary {
410420

411421
bool canAutoHide() const { return Flags.CanAutoHide; }
412422

423+
GlobalValue::VisibilityTypes getVisibility() const {
424+
return (GlobalValue::VisibilityTypes)Flags.Visibility;
425+
}
426+
void setVisibility(GlobalValue::VisibilityTypes Vis) {
427+
Flags.Visibility = (unsigned)Vis;
428+
}
429+
413430
/// Flag that this global value cannot be imported.
414431
void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
415432

@@ -594,6 +611,7 @@ class FunctionSummary : public GlobalValueSummary {
594611
return FunctionSummary(
595612
FunctionSummary::GVFlags(
596613
GlobalValue::LinkageTypes::AvailableExternallyLinkage,
614+
GlobalValue::DefaultVisibility,
597615
/*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false,
598616
/*CanAutoHide=*/false),
599617
/*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0,

llvm/include/llvm/IR/ModuleSummaryIndexYAML.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ template <> struct MappingTraits<TypeIdSummary> {
136136
};
137137

138138
struct FunctionSummaryYaml {
139-
unsigned Linkage;
139+
unsigned Linkage, Visibility;
140140
bool NotEligibleToImport, Live, IsLocal, CanAutoHide;
141141
std::vector<uint64_t> Refs;
142142
std::vector<uint64_t> TypeTests;
@@ -178,6 +178,7 @@ namespace yaml {
178178
template <> struct MappingTraits<FunctionSummaryYaml> {
179179
static void mapping(IO &io, FunctionSummaryYaml& summary) {
180180
io.mapOptional("Linkage", summary.Linkage);
181+
io.mapOptional("Visibility", summary.Visibility);
181182
io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
182183
io.mapOptional("Live", summary.Live);
183184
io.mapOptional("Local", summary.IsLocal);
@@ -224,6 +225,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
224225
Elem.SummaryList.push_back(std::make_unique<FunctionSummary>(
225226
GlobalValueSummary::GVFlags(
226227
static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
228+
static_cast<GlobalValue::VisibilityTypes>(FSum.Visibility),
227229
FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal,
228230
FSum.CanAutoHide),
229231
/*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, Refs,
@@ -244,7 +246,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
244246
for (auto &VI : FSum->refs())
245247
Refs.push_back(VI.getGUID());
246248
FSums.push_back(FunctionSummaryYaml{
247-
FSum->flags().Linkage,
249+
FSum->flags().Linkage, FSum->flags().Visibility,
248250
static_cast<bool>(FSum->flags().NotEligibleToImport),
249251
static_cast<bool>(FSum->flags().Live),
250252
static_cast<bool>(FSum->flags().DSOLocal),

llvm/include/llvm/LTO/Config.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ namespace lto {
3838
/// LTO configuration. A linker can configure LTO by setting fields in this data
3939
/// structure and passing it to the lto::LTO constructor.
4040
struct Config {
41+
enum VisScheme {
42+
FromPrevailing,
43+
ELF,
44+
};
4145
// Note: when adding fields here, consider whether they need to be added to
4246
// computeCacheKey in LTO.cpp.
4347
std::string CPU;
@@ -75,6 +79,12 @@ struct Config {
7579
/// want to know a priori all possible output files.
7680
bool AlwaysEmitRegularLTOObj = false;
7781

82+
/// Allows non-imported definitions to get the potentially more constraining
83+
/// visibility from the prevailing definition. FromPrevailing is the default
84+
/// because it works for many binary formats. ELF can use the more optimized
85+
/// 'ELF' scheme.
86+
VisScheme VisibilityScheme = FromPrevailing;
87+
7888
/// If this field is set, the set of passes run in the middle-end optimizer
7989
/// will be the one specified by the string. Only works with the new pass
8090
/// manager as the old one doesn't have this ability.

llvm/include/llvm/LTO/LTO.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ToolOutputFile;
4343
/// This is done for correctness (if value exported, ensure we always
4444
/// emit a copy), and compile-time optimization (allow drop of duplicates).
4545
void thinLTOResolvePrevailingInIndex(
46-
ModuleSummaryIndex &Index,
46+
const lto::Config &C, ModuleSummaryIndex &Index,
4747
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
4848
isPrevailing,
4949
function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>

llvm/include/llvm/Transforms/IPO/FunctionImport.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,10 @@ std::error_code EmitImportsFiles(
214214
StringRef ModulePath, StringRef OutputFilename,
215215
const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
216216

217-
/// Resolve prevailing symbol linkages in \p TheModule based on the information
218-
/// recorded in the summaries during global summary-based analysis.
217+
/// Resolve prevailing symbol linkages and constrain visibility (1. CanAutoHide,
218+
/// 2. consider visibility from other definitions for ELF) in \p TheModule based
219+
/// on the information recorded in the summaries during global summary-based
220+
/// analysis.
219221
void thinLTOResolvePrevailingInModule(Module &TheModule,
220222
const GVSummaryMapTy &DefinedGlobals);
221223

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,10 @@ static void computeFunctionSummary(
459459
bool NonRenamableLocal = isNonRenamableLocal(F);
460460
bool NotEligibleForImport =
461461
NonRenamableLocal || HasInlineAsmMaybeReferencingInternal;
462-
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
463-
/* Live = */ false, F.isDSOLocal(),
464-
F.hasLinkOnceODRLinkage() && F.hasGlobalUnnamedAddr());
462+
GlobalValueSummary::GVFlags Flags(
463+
F.getLinkage(), F.getVisibility(), NotEligibleForImport,
464+
/* Live = */ false, F.isDSOLocal(),
465+
F.hasLinkOnceODRLinkage() && F.hasGlobalUnnamedAddr());
465466
FunctionSummary::FFlags FunFlags{
466467
F.hasFnAttribute(Attribute::ReadNone),
467468
F.hasFnAttribute(Attribute::ReadOnly),
@@ -580,9 +581,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
580581
SmallPtrSet<const User *, 8> Visited;
581582
bool HasBlockAddress = findRefEdges(Index, &V, RefEdges, Visited);
582583
bool NonRenamableLocal = isNonRenamableLocal(V);
583-
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
584-
/* Live = */ false, V.isDSOLocal(),
585-
V.hasLinkOnceODRLinkage() && V.hasGlobalUnnamedAddr());
584+
GlobalValueSummary::GVFlags Flags(
585+
V.getLinkage(), V.getVisibility(), NonRenamableLocal,
586+
/* Live = */ false, V.isDSOLocal(),
587+
V.hasLinkOnceODRLinkage() && V.hasGlobalUnnamedAddr());
586588

587589
VTableFuncList VTableFuncs;
588590
// If splitting is not enabled, then we compute the summary information
@@ -622,9 +624,10 @@ static void
622624
computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
623625
DenseSet<GlobalValue::GUID> &CantBePromoted) {
624626
bool NonRenamableLocal = isNonRenamableLocal(A);
625-
GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
626-
/* Live = */ false, A.isDSOLocal(),
627-
A.hasLinkOnceODRLinkage() && A.hasGlobalUnnamedAddr());
627+
GlobalValueSummary::GVFlags Flags(
628+
A.getLinkage(), A.getVisibility(), NonRenamableLocal,
629+
/* Live = */ false, A.isDSOLocal(),
630+
A.hasLinkOnceODRLinkage() && A.hasGlobalUnnamedAddr());
628631
auto AS = std::make_unique<AliasSummary>(Flags);
629632
auto *Aliasee = A.getBaseObject();
630633
auto AliaseeVI = Index.getValueInfo(Aliasee->getGUID());
@@ -697,11 +700,12 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
697700
if (!GV)
698701
return;
699702
assert(GV->isDeclaration() && "Def in module asm already has definition");
700-
GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
701-
/* NotEligibleToImport = */ true,
702-
/* Live = */ true,
703-
/* Local */ GV->isDSOLocal(),
704-
GV->hasLinkOnceODRLinkage() && GV->hasGlobalUnnamedAddr());
703+
GlobalValueSummary::GVFlags GVFlags(
704+
GlobalValue::InternalLinkage, GlobalValue::DefaultVisibility,
705+
/* NotEligibleToImport = */ true,
706+
/* Live = */ true,
707+
/* Local */ GV->isDSOLocal(),
708+
GV->hasLinkOnceODRLinkage() && GV->hasGlobalUnnamedAddr());
705709
CantBePromoted.insert(GV->getGUID());
706710
// Create the appropriate summary type.
707711
if (Function *F = dyn_cast<Function>(GV)) {

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ lltok::Kind LLLexer::LexIdentifier() {
751751
KEYWORD(flags);
752752
KEYWORD(blockcount);
753753
KEYWORD(linkage);
754+
KEYWORD(visibility);
754755
KEYWORD(notEligibleToImport);
755756
KEYWORD(live);
756757
KEYWORD(dsoLocal);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8517,7 +8517,8 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
85178517

85188518
StringRef ModulePath;
85198519
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
8520-
/*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
8520+
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
8521+
/*NotEligibleToImport=*/false,
85218522
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
85228523
unsigned InstCount;
85238524
std::vector<FunctionSummary::EdgeTy> Calls;
@@ -8593,7 +8594,8 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
85938594

85948595
StringRef ModulePath;
85958596
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
8596-
/*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
8597+
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
8598+
/*NotEligibleToImport=*/false,
85978599
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
85988600
GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
85998601
/* WriteOnly */ false,
@@ -8651,7 +8653,8 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
86518653

86528654
StringRef ModulePath;
86538655
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
8654-
/*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
8656+
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
8657+
/*NotEligibleToImport=*/false,
86558658
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
86568659
if (parseToken(lltok::colon, "expected ':' here") ||
86578660
parseToken(lltok::lparen, "expected '(' here") ||
@@ -9339,8 +9342,9 @@ bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
93399342

93409343
/// GVFlags
93419344
/// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ','
9342-
/// 'notEligibleToImport' ':' Flag ',' 'live' ':' Flag ','
9343-
/// 'dsoLocal' ':' Flag ',' 'canAutoHide' ':' Flag ')'
9345+
/// 'visibility' ':' Flag 'notEligibleToImport' ':' Flag ','
9346+
/// 'live' ':' Flag ',' 'dsoLocal' ':' Flag ','
9347+
/// 'canAutoHide' ':' Flag ',' ')'
93449348
bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
93459349
assert(Lex.getKind() == lltok::kw_flags);
93469350
Lex.Lex();
@@ -9361,6 +9365,13 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
93619365
assert(HasLinkage && "Linkage not optional in summary entry");
93629366
Lex.Lex();
93639367
break;
9368+
case lltok::kw_visibility:
9369+
Lex.Lex();
9370+
if (parseToken(lltok::colon, "expected ':'"))
9371+
return true;
9372+
parseOptionalVisibility(Flag);
9373+
GVFlags.Visibility = Flag;
9374+
break;
93649375
case lltok::kw_notEligibleToImport:
93659376
Lex.Lex();
93669377
if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))

llvm/lib/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ enum Kind {
384384
kw_flags,
385385
kw_blockcount,
386386
kw_linkage,
387+
kw_visibility,
387388
kw_notEligibleToImport,
388389
kw_live,
389390
kw_dsoLocal,

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,13 +968,17 @@ static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) {
968968
return Flags;
969969
}
970970

971-
/// Decode the flags for GlobalValue in the summary.
971+
// Decode the flags for GlobalValue in the summary. The bits for each attribute:
972+
//
973+
// linkage: [0,4), notEligibleToImport: 4, live: 5, local: 6, canAutoHide: 7,
974+
// visibility: [8, 10).
972975
static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
973976
uint64_t Version) {
974977
// Summary were not emitted before LLVM 3.9, we don't need to upgrade Linkage
975978
// like getDecodedLinkage() above. Any future change to the linkage enum and
976979
// to getDecodedLinkage() will need to be taken into account here as above.
977980
auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
981+
auto Visibility = GlobalValue::VisibilityTypes((RawFlags >> 8) & 3); // 2 bits
978982
RawFlags = RawFlags >> 4;
979983
bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
980984
// The Live flag wasn't introduced until version 3. For dead stripping
@@ -984,7 +988,8 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
984988
bool Local = (RawFlags & 0x4);
985989
bool AutoHide = (RawFlags & 0x8);
986990

987-
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local, AutoHide);
991+
return GlobalValueSummary::GVFlags(Linkage, Visibility, NotEligibleToImport,
992+
Live, Local, AutoHide);
988993
}
989994

990995
// Decode the flags for GlobalVariable in the summary

0 commit comments

Comments
 (0)