aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-04-21 05:47:17 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-04-21 05:47:17 +0000
commita71a5a628956b30e3f86167335a9ffe4d08abdbf (patch)
tree8030f3a42b4c7752eb659db98980d016924ec094 /llvm/lib/LTO/ThinLTOCodeGenerator.cpp
parent253f71ba5a1ba64e06b1b176c8a92af14b057b3b (diff)
downloadllvm-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.cpp49
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