diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2016-04-21 05:47:17 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2016-04-21 05:47:17 +0000 |
commit | a71a5a628956b30e3f86167335a9ffe4d08abdbf (patch) | |
tree | 8030f3a42b4c7752eb659db98980d016924ec094 /llvm/lib/LTO/ThinLTOCodeGenerator.cpp | |
parent | 253f71ba5a1ba64e06b1b176c8a92af14b057b3b (diff) | |
download | llvm-a71a5a628956b30e3f86167335a9ffe4d08abdbf.zip llvm-a71a5a628956b30e3f86167335a9ffe4d08abdbf.tar.gz llvm-a71a5a628956b30e3f86167335a9ffe4d08abdbf.tar.bz2 |
ThinLTO: Resolve linkonce_odr aliases just like functions
This help to streamline the process of handling importing since
we don't need to special case alias everywhere: just like
linkonce_odr function, make sure at least one alias is emitted
by turning it weak.
Differential Revision: http://reviews.llvm.org/D19308
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 266958
Diffstat (limited to 'llvm/lib/LTO/ThinLTOCodeGenerator.cpp')
-rw-r--r-- | llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 271520e..ee21979 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -122,10 +122,11 @@ bool IsFirstDefinitionForLinker(const GlobalValueInfoList &GVInfo, return true; } -static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex &Index, - StringRef ModuleIdentifier, - GlobalValue::GUID GUID, - const GlobalValueSummary &GV) { +static GlobalValue::LinkageTypes +ResolveODR(const ModuleSummaryIndex &Index, + const FunctionImporter::ExportSetTy &ExportList, + StringRef ModuleIdentifier, GlobalValue::GUID GUID, + const GlobalValueSummary &GV) { auto HasMultipleCopies = [&](const GlobalValueInfoList &GVInfo) { return GVInfo.size() > 1; }; @@ -146,13 +147,19 @@ static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex &Index, auto &GVInfo = Index.findGlobalValueInfoList(GUID)->second; // We need to emit only one of these, the first module will keep // it, but turned into a weak while the others will drop it. - if (!HasMultipleCopies(GVInfo)) + if (!HasMultipleCopies(GVInfo)) { + // Exported LinkonceODR needs to be promoted to not be discarded + if (GlobalValue::isDiscardableIfUnused(OriginalLinkage) && + ExportList.count(GUID)) + return GlobalValue::WeakODRLinkage; break; + } if (IsFirstDefinitionForLinker(GVInfo, Index, ModuleIdentifier)) return GlobalValue::WeakODRLinkage; - else - return GlobalValue::AvailableExternallyLinkage; - break; + else if (isa<AliasSummary>(&GV)) + // Alias can't be turned into available_externally. + return OriginalLinkage; + return GlobalValue::AvailableExternallyLinkage; } } return OriginalLinkage; @@ -166,6 +173,7 @@ static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex &Index, /// one copy. static void ResolveODR( const ModuleSummaryIndex &Index, + const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedGlobals, StringRef ModuleIdentifier, DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR) { @@ -185,7 +193,8 @@ static void ResolveODR( for (auto &GV : DefinedGlobals) { if (GlobalInvolvedWithAlias.count(GV.second)) continue; - auto NewLinkage = ResolveODR(Index, ModuleIdentifier, GV.first, *GV.second); + auto NewLinkage = + ResolveODR(Index, ExportList, ModuleIdentifier, GV.first, *GV.second); if (NewLinkage != GV.second->linkage()) { ResolvedODR[GV.first] = NewLinkage; } @@ -213,6 +222,14 @@ void fixupODR( << GV.getLinkage() << " to " << NewLinkage->second << "\n"); GV.setLinkage(NewLinkage->second); } + for (auto &GV : TheModule.aliases()) { + auto NewLinkage = ResolvedODR.find(GV.getGUID()); + if (NewLinkage == ResolvedODR.end()) + continue; + DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " + << GV.getLinkage() << " to " << NewLinkage->second << "\n"); + GV.setLinkage(NewLinkage->second); + } } static StringMap<MemoryBufferRef> @@ -453,17 +470,25 @@ std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() { */ void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index) { + auto ModuleCount = Index.modulePaths().size(); auto ModuleIdentifier = TheModule.getModuleIdentifier(); // Collect for each module the list of function it defines (GUID -> Summary). StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> ModuleToDefinedGVSummaries; Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); + // Generate import/export list + StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); + StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount); + ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists, + ExportLists); + auto &ExportList = ExportLists[ModuleIdentifier]; + // Resolve the LinkOnceODR, trying to turn them into "available_externally" // where possible. // This is a compile-time optimization. DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR; - ResolveODR(Index, ModuleToDefinedGVSummaries[ModuleIdentifier], + ResolveODR(Index, ExportList, ModuleToDefinedGVSummaries[ModuleIdentifier], ModuleIdentifier, ResolvedODR); fixupODR(TheModule, ResolvedODR); @@ -577,9 +602,11 @@ void ThinLTOCodeGenerator::run() { Context.setDiscardValueNames(LTODiscardValueNames); Context.enableDebugTypeODRUniquing(); auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier(); + auto &ExportList = ExportLists[ModuleIdentifier]; DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR; - ResolveODR(*Index, ModuleToDefinedGVSummaries[ModuleIdentifier], + ResolveODR(*Index, ExportList, + ModuleToDefinedGVSummaries[ModuleIdentifier], ModuleIdentifier, ResolvedODR); // Parse module now |