diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/LTO/LTO.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/LTO/LTO.cpp | 102 |
1 files changed, 84 insertions, 18 deletions
diff --git a/contrib/llvm-project/llvm/lib/LTO/LTO.cpp b/contrib/llvm-project/llvm/lib/LTO/LTO.cpp index 9103d11059e0..69d500ba9bce 100644 --- a/contrib/llvm-project/llvm/lib/LTO/LTO.cpp +++ b/contrib/llvm-project/llvm/lib/LTO/LTO.cpp @@ -11,7 +11,9 @@ //===----------------------------------------------------------------------===// #include "llvm/LTO/LTO.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/StackSafetyAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -33,6 +35,7 @@ #include "llvm/Object/IRObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -203,10 +206,11 @@ 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()) { - AddUnsigned(VI.isDSOLocal()); + AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation())); AddUsedCfiGlobal(VI.getGUID()); } if (auto *GVS = dyn_cast<GlobalVarSummary>(GS)) { @@ -225,7 +229,7 @@ void llvm::computeLTOCacheKey( for (auto &TT : FS->type_checked_load_const_vcalls()) UsedTypeIds.insert(TT.VFunc.GUID); for (auto &ET : FS->calls()) { - AddUnsigned(ET.first.isDSOLocal()); + AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation())); AddUsedCfiGlobal(ET.first.getGUID()); } } @@ -315,12 +319,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 +360,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 +396,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 +412,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) { @@ -539,8 +566,8 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, // Set the partition to external if we know it is re-defined by the linker // with -defsym or -wrap options, used elsewhere, e.g. it is visible to a - // regular object, is referenced from llvm.compiler_used, or was already - // recorded as being referenced from a different partition. + // regular object, is referenced from llvm.compiler.used/llvm.used, or was + // already recorded as being referenced from a different partition. if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() || (GlobalRes.Partition != GlobalResolution::Unknown && GlobalRes.Partition != Partition)) { @@ -553,6 +580,8 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, // from a module that does not have a summary. GlobalRes.VisibleOutsideSummary |= (Res.VisibleToRegularObj || Sym.isUsed() || !InSummary); + + GlobalRes.ExportDynamic |= Res.ExportDynamic; } } @@ -587,8 +616,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) @@ -723,6 +755,7 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, Skip(); std::set<const Comdat *> NonPrevailingComdats; + SmallSet<StringRef, 2> NonPrevailingAsmSymbols; for (const InputFile::Symbol &Sym : Syms) { assert(ResI != ResE); SymbolResolution Res = *ResI++; @@ -769,7 +802,14 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, GV->setDLLStorageClass(GlobalValue::DLLStorageClassTypes:: DefaultStorageClass); } + } else if (auto *AS = Msym.dyn_cast<ModuleSymbolTable::AsmSymbol *>()) { + // Collect non-prevailing symbols. + if (!Res.Prevailing) + NonPrevailingAsmSymbols.insert(AS->first); + } else { + llvm_unreachable("unknown symbol type"); } + // Common resolution: collect the maximum size/alignment over all commons. // We also record if we see an instance of a common as prevailing, so that // if none is prevailing we can ignore it later. @@ -783,11 +823,29 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, CommonRes.Align = max(*SymAlign, CommonRes.Align); CommonRes.Prevailing |= Res.Prevailing; } - } + if (!M.getComdatSymbolTable().empty()) for (GlobalValue &GV : M.global_values()) handleNonPrevailingComdat(GV, NonPrevailingComdats); + + // Prepend ".lto_discard <sym>, <sym>*" directive to each module inline asm + // block. + if (!M.getModuleInlineAsm().empty()) { + std::string NewIA = ".lto_discard"; + if (!NonPrevailingAsmSymbols.empty()) { + // Don't dicard a symbol if there is a live .symver for it. + ModuleSymbolTable::CollectAsmSymvers( + M, [&](StringRef Name, StringRef Alias) { + if (!NonPrevailingAsmSymbols.count(Alias)) + NonPrevailingAsmSymbols.erase(Name); + }); + NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", "); + } + NewIA += "\n"; + M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm()); + } + assert(MsymI == MsymE); return std::move(Mod); } @@ -950,6 +1008,9 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { if (Res.second.VisibleOutsideSummary && Res.second.Prevailing) GUIDPreservedSymbols.insert(GUID); + if (Res.second.ExportDynamic) + DynamicExportSymbols.insert(GUID); + GUIDPrevailingResolutions[GUID] = Res.second.Prevailing ? PrevailingType::Yes : PrevailingType::No; } @@ -1034,7 +1095,8 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { // If allowed, upgrade public vcall visibility metadata to linkage unit // visibility before whole program devirtualization in the optimizer. updateVCallVisibilityInModule(*RegularLTO.CombinedModule, - Conf.HasWholeProgramVisibility); + Conf.HasWholeProgramVisibility, + DynamicExportSymbols); if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule)) @@ -1068,9 +1130,9 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { } if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) { - if (Error Err = backend( - Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, - std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex)) + if (Error Err = + backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, + *RegularLTO.CombinedModule, ThinLTO.CombinedIndex)) return Err; } @@ -1154,7 +1216,7 @@ public: return MOrErr.takeError(); return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex, - ImportList, DefinedGlobals, ModuleMap); + ImportList, DefinedGlobals, &ModuleMap); }; auto ModuleID = BM.getModuleIdentifier(); @@ -1382,7 +1444,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, // If allowed, upgrade public vcall visibility to linkage unit visibility in // the summaries before whole program devirtualization below. updateVCallVisibilityInIndex(ThinLTO.CombinedIndex, - Conf.HasWholeProgramVisibility); + Conf.HasWholeProgramVisibility, + DynamicExportSymbols); // Perform index-based WPD. This will return immediately if there are // no index entries in the typeIdMetadata map (e.g. if we are instead @@ -1417,6 +1480,9 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs()) ExportedGUIDs.insert( GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def))); + for (auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls()) + ExportedGUIDs.insert( + GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Decl))); auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) { const auto &ExportList = ExportLists.find(ModuleIdentifier); @@ -1441,7 +1507,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); |