diff options
author | Teresa Johnson <tejohnson@google.com> | 2016-07-13 03:42:41 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2016-07-13 03:42:41 +0000 |
commit | 27694571b11b66709192bab87af6b7fd7de0a9f9 (patch) | |
tree | ede6aeaaecc4337f953319b0ff4b7390232390ef | |
parent | 17bdf445e42e902dbd97e80facfdeaa7cb6e61f8 (diff) | |
download | bcm5719-llvm-27694571b11b66709192bab87af6b7fd7de0a9f9.tar.gz bcm5719-llvm-27694571b11b66709192bab87af6b7fd7de0a9f9.zip |
[ThinLTO/gold] ThinLTO internalization fixes
Internalization was missing cases where we originally had a local symbol
that was promoted eagerly but not actually exported. This is because we
were only internalizing the set of global (non-local) symbols that were
PREVAILAING_DEF_IRONLY. Instead, collect the set of global symbols that
are referenced outside of a single IR file, and skip internalization for
those.
llvm-svn: 275247
-rw-r--r-- | llvm/test/tools/gold/X86/thinlto.ll | 2 | ||||
-rw-r--r-- | llvm/test/tools/gold/X86/thinlto_internalize.ll | 7 | ||||
-rw-r--r-- | llvm/tools/gold/gold-plugin.cpp | 25 |
3 files changed, 18 insertions, 16 deletions
diff --git a/llvm/test/tools/gold/X86/thinlto.ll b/llvm/test/tools/gold/X86/thinlto.ll index 09bf21d4a82..771dfa03154 100644 --- a/llvm/test/tools/gold/X86/thinlto.ll +++ b/llvm/test/tools/gold/X86/thinlto.ll @@ -62,6 +62,8 @@ ; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK ; BACKEND1-NEXT: <GLOBALVAL_SUMMARY_BLOCK ; BACKEND1-NEXT: <VERSION +; One of these will be a COMBINED_ORIGINAL_NAME since f can be internalized. +; BACKEND1-NEXT: <COMBINED ; BACKEND1-NEXT: <COMBINED ; BACKEND1-NEXT: <COMBINED ; BACKEND1-NEXT: </GLOBALVAL_SUMMARY_BLOCK diff --git a/llvm/test/tools/gold/X86/thinlto_internalize.ll b/llvm/test/tools/gold/X86/thinlto_internalize.ll index 5cf14250a3c..4d626ee0d60 100644 --- a/llvm/test/tools/gold/X86/thinlto_internalize.ll +++ b/llvm/test/tools/gold/X86/thinlto_internalize.ll @@ -11,11 +11,18 @@ ; f() should be internalized and eliminated after inlining ; CHECK-NOT: @f() +; h() should be internalized after promotion, and eliminated after inlining +; CHECK-NOT: @h.llvm. + target triple = "x86_64-unknown-linux-gnu" define i32 @g() { call void @f() + call void @h() ret i32 0 } define void @f() { ret void } +define internal void @h() { + ret void +} diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp index cd4e39cb81c..4fff5dcf900 100644 --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -1323,10 +1323,9 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) { // interfaces with gold. DenseMap<void *, std::unique_ptr<PluginInputFile>> HandleToInputFile; - // Keep track of internalization candidates as well as those that may not - // be internalized because they are refereneced from other IR modules. - DenseSet<GlobalValue::GUID> Internalize; - DenseSet<GlobalValue::GUID> CrossReferenced; + // Keep track of symbols that must not be internalized because they + // are referenced outside of a single IR module. + DenseSet<GlobalValue::GUID> Preserve; ModuleSummaryIndex CombinedIndex; uint64_t NextModuleId = 0; @@ -1352,23 +1351,17 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) { if (Index) CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); - // Look for internalization candidates based on gold's symbol resolution - // information. Also track symbols referenced from other IR modules. + // Use gold's symbol resolution information to identify symbols referenced + // by more than a single IR module (before importing, which is checked + // separately). for (auto &Sym : F.syms) { ld_plugin_symbol_resolution Resolution = (ld_plugin_symbol_resolution)Sym.resolution; - if (Resolution == LDPR_PREVAILING_DEF_IRONLY) - Internalize.insert(GlobalValue::getGUID(Sym.name)); - if (Resolution == LDPR_RESOLVED_IR || Resolution == LDPR_PREEMPTED_IR) - CrossReferenced.insert(GlobalValue::getGUID(Sym.name)); + if (Resolution != LDPR_PREVAILING_DEF_IRONLY) + Preserve.insert(GlobalValue::getGUID(Sym.name)); } } - // Remove symbols referenced from other IR modules from the internalization - // candidate set. - for (auto &S : CrossReferenced) - Internalize.erase(S); - // Collect for each module the list of function it defines (GUID -> // Summary). StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> @@ -1387,7 +1380,7 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) { const auto &ExportList = ExportLists.find(ModuleIdentifier); return (ExportList != ExportLists.end() && ExportList->second.count(GUID)) || - !Internalize.count(GUID); + Preserve.count(GUID); }; // Use global summary-based analysis to identify symbols that can be |