diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 60 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 7 |
6 files changed, 77 insertions, 45 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index f5ba637e58e..0227eab0ede 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -190,7 +190,8 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, // FIXME: refactor this to use the same code that inliner is using. F.isVarArg(); GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport, - /* LiveRoot = */ false); + /* LiveRoot = */ false, + /* AutoHide */ false); auto FuncSummary = llvm::make_unique<FunctionSummary>( Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(), TypeTests.takeVector()); @@ -207,7 +208,8 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V, findRefEdges(&V, RefEdges, Visited); bool NonRenamableLocal = isNonRenamableLocal(V); GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal, - /* LiveRoot = */ false); + /* LiveRoot = */ false, + /* AutoHide */ false); auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector()); if (NonRenamableLocal) @@ -220,7 +222,8 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A, DenseSet<GlobalValue::GUID> &CantBePromoted) { bool NonRenamableLocal = isNonRenamableLocal(A); GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal, - /* LiveRoot = */ false); + /* LiveRoot = */ false, + /* AutoHide */ false); auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{}); auto *Aliasee = A.getBaseObject(); auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee); @@ -339,7 +342,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( assert(GV->isDeclaration() && "Def in module asm already has definition"); GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage, /* NotEligibleToImport */ true, - /* LiveRoot */ true); + /* LiveRoot */ true, + /* AutoHide */ false); CantBePromoted.insert(GlobalValue::getGUID(Name)); // Create the appropriate summary type. if (isa<Function>(GV)) { diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index a46e49ccde8..c9d2ad5c71b 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -800,13 +800,14 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, // like getDecodedLinkage() above. Any future change to the linkage enum and // to getDecodedLinkage() will need to be taken into account here as above. auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits - RawFlags = RawFlags >> 4; - bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3; + bool NotEligibleToImport = ((RawFlags >> 4) & 0x1) || Version < 3; // The LiveRoot flag wasn't introduced until version 3. For dead stripping // to work correctly on earlier versions, we must conservatively treat all // values as live. - bool LiveRoot = (RawFlags & 0x2) || Version < 3; - return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot); + bool LiveRoot = ((RawFlags >> 5) & 0x1) || Version < 3; + bool AutoHide = (RawFlags >> 6) & 0x1; + return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot, + AutoHide); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 4eac89c37a5..bdb57f59dde 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -971,13 +971,13 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) { static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) { uint64_t RawFlags = 0; - RawFlags |= Flags.NotEligibleToImport; // bool - RawFlags |= (Flags.LiveRoot << 1); // Linkage don't need to be remapped at that time for the summary. Any future // change to the getEncodedLinkage() function will need to be taken into // account here as well. - RawFlags = (RawFlags << 4) | Flags.Linkage; // 4 bits - + RawFlags |= Flags.Linkage; // 4 bits linkage + RawFlags |= (Flags.NotEligibleToImport << 4); // bool + RawFlags |= (Flags.LiveRoot << 5); // bool + RawFlags |= (Flags.AutoHide << 6); // bool return RawFlags; } diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index df19ded398d..51b7e7d13c7 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -199,11 +199,14 @@ void llvm::thinLTOResolveWeakForLinkerInIndex( static void thinLTOInternalizeAndPromoteGUID( GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, - function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { + function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) { for (auto &S : GVSummaryList) { - if (isExported(S->modulePath(), GUID)) { + auto ExportResolution = isExported(S->modulePath(), GUID); + if (ExportResolution != Internal) { if (GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::ExternalLinkage); + if (ExportResolution == Hidden) + S->setAutoHide(); } else if (!GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::InternalLinkage); } @@ -213,7 +216,7 @@ static void thinLTOInternalizeAndPromoteGUID( // as external and non-exported values as internal. void llvm::thinLTOInternalizeAndPromoteInIndex( ModuleSummaryIndex &Index, - function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { + function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) { for (auto &I : Index) thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); } @@ -921,11 +924,20 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, const GlobalValueSummary *S) { return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath(); }; - auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { + auto isExported = [&](StringRef ModuleIdentifier, + GlobalValue::GUID GUID) -> SummaryResolution { const auto &ExportList = ExportLists.find(ModuleIdentifier); - return (ExportList != ExportLists.end() && - ExportList->second.count(GUID)) || - ExportedGUIDs.count(GUID); + if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) || + ExportedGUIDs.count(GUID)) { + // We could do better by hiding when a symbol is in + // GUIDPreservedSymbols because it is only referenced from regular LTO + // or from native files and not outside the final binary, but that's + // something the native linker could do as gwell. + if (GUIDPreservedSymbols.count(GUID)) + return Exported; + return Hidden; + } + return Internal; }; thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 104fb199da0..b62db61f4c4 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -234,16 +234,16 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM, // Convert the PreservedSymbols map from "Name" based to "GUID" based. static DenseSet<GlobalValue::GUID> -computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols, - const Triple &TheTriple) { - DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size()); - for (auto &Entry : PreservedSymbols) { +convertSymbolNamesToGUID(const StringSet<> &NamedSymbols, + const Triple &TheTriple) { + DenseSet<GlobalValue::GUID> GUIDSymbols(NamedSymbols.size()); + for (auto &Entry : NamedSymbols) { StringRef Name = Entry.first(); if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_') Name = Name.drop_front(); - GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name)); + GUIDSymbols.insert(GlobalValue::getGUID(Name)); } - return GUIDPreservedSymbols; + return GUIDSymbols; } std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule, @@ -554,10 +554,7 @@ void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) { } void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) { - // FIXME: At the moment, we don't take advantage of this extra information, - // we're conservatively considering cross-references as preserved. - // CrossReferencedSymbols.insert(Name); - PreservedSymbols.insert(Name); + CrossReferencedSymbols.insert(Name); } // TargetMachine factory @@ -620,7 +617,7 @@ void ThinLTOCodeGenerator::promote(Module &TheModule, Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); // Convert the preserved symbols set from string to GUID - auto GUIDPreservedSymbols = computeGUIDPreservedSymbols( + auto GUIDPreservedSymbols = convertSymbolNamesToGUID( PreservedSymbols, Triple(TheModule.getTargetTriple())); // Compute "dead" symbols, we don't want to import/export these! @@ -641,11 +638,13 @@ void ThinLTOCodeGenerator::promote(Module &TheModule, // Promote the exported values in the index, so that they are promoted // in the module. - auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { + auto isExported = [&](StringRef ModuleIdentifier, + GlobalValue::GUID GUID) -> SummaryResolution { const auto &ExportList = ExportLists.find(ModuleIdentifier); - return (ExportList != ExportLists.end() && - ExportList->second.count(GUID)) || - GUIDPreservedSymbols.count(GUID); + if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) || + GUIDPreservedSymbols.count(GUID)) + return Exported; + return Internal; }; thinLTOInternalizeAndPromoteInIndex(Index, isExported); @@ -665,7 +664,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule, Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); // Convert the preserved symbols set from string to GUID - auto GUIDPreservedSymbols = computeGUIDPreservedSymbols( + auto GUIDPreservedSymbols = convertSymbolNamesToGUID( PreservedSymbols, Triple(TheModule.getTargetTriple())); // Compute "dead" symbols, we don't want to import/export these! @@ -739,7 +738,7 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule, // Convert the preserved symbols set from string to GUID auto GUIDPreservedSymbols = - computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple); + convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple); // Collect for each module the list of function it defines (GUID -> Summary). StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount); @@ -761,11 +760,13 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule, return; // Internalization - auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { + auto isExported = [&](StringRef ModuleIdentifier, + GlobalValue::GUID GUID) -> SummaryResolution { const auto &ExportList = ExportLists.find(ModuleIdentifier); - return (ExportList != ExportLists.end() && - ExportList->second.count(GUID)) || - GUIDPreservedSymbols.count(GUID); + if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) || + GUIDPreservedSymbols.count(GUID)) + return Exported; + return Internal; }; thinLTOInternalizeAndPromoteInIndex(Index, isExported); thinLTOInternalizeModule(TheModule, @@ -894,7 +895,9 @@ void ThinLTOCodeGenerator::run() { // Convert the preserved symbols set from string to GUID, this is needed for // computing the caching hash and the internalization. auto GUIDPreservedSymbols = - computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple); + convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple); + auto GUIDCrossRefSymbols = + convertSymbolNamesToGUID(CrossReferencedSymbols, TMBuilder.TheTriple); // Compute "dead" symbols, we don't want to import/export these! auto DeadSymbols = computeDeadSymbols(*Index, GUIDPreservedSymbols); @@ -916,11 +919,16 @@ void ThinLTOCodeGenerator::run() { // impacts the caching. resolveWeakForLinkerInIndex(*Index, ResolvedODR); - auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { + auto isExported = [&](StringRef ModuleIdentifier, + GlobalValue::GUID GUID) -> SummaryResolution { + if (GUIDPreservedSymbols.count(GUID)) + return Exported; + if (GUIDCrossRefSymbols.count(GUID)) + return Hidden; const auto &ExportList = ExportLists.find(ModuleIdentifier); - return (ExportList != ExportLists.end() && - ExportList->second.count(GUID)) || - GUIDPreservedSymbols.count(GUID); + if (ExportList != ExportLists.end() && ExportList->second.count(GUID)) + return Hidden; + return Internal; }; // Use global summary-based analysis to identify symbols that can be diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index b8fc79a03b6..f469c24dd42 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -650,6 +650,13 @@ void llvm::thinLTOInternalizeModule(Module &TheModule, return !GlobalValue::isLocalLinkage(Linkage); }; + // Try to auto-hide the symbols. + for (auto &GO : TheModule.global_objects()) { + const auto &GS = DefinedGlobals.find(GO.getGUID()); + if (GS != DefinedGlobals.end() && GS->second->flags().AutoHide) + GO.setVisibility(GlobalValue::HiddenVisibility); + } + // FIXME: See if we can just internalize directly here via linkage changes // based on the index, rather than invoking internalizeModule. llvm::internalizeModule(TheModule, MustPreserveGV); |