summaryrefslogtreecommitdiffstats
path: root/llvm/tools/gold/gold-plugin.cpp
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2016-07-14 21:13:24 +0000
committerTeresa Johnson <tejohnson@google.com>2016-07-14 21:13:24 +0000
commit35e0204eecb944ff879c752d8b75f8122de621ea (patch)
tree30e01a1894e47e929f10d3ecee34904bceebb8c7 /llvm/tools/gold/gold-plugin.cpp
parent96e881deb5243dc915d049874389b4d01ae2db2a (diff)
downloadbcm5719-llvm-35e0204eecb944ff879c752d8b75f8122de621ea.tar.gz
bcm5719-llvm-35e0204eecb944ff879c752d8b75f8122de621ea.zip
[ThinLTO/gold] Perform index-based weak/linkonce resolution
Summary: Invoke the weak/linkonce symbol resolution support (already used by libLTO) that operates via the summary index. This ensures prevailing linkonce are kept, by making them weak, and marks preempted copies as available_externally when possible. With this change, the older support for keeping the prevailing linkonce (by changing their symbol resolution) is removed. Reviewers: mehdi_amini Subscribers: llvm-commits, mehdi_amini Differential Revision: http://reviews.llvm.org/D22302 llvm-svn: 275474
Diffstat (limited to 'llvm/tools/gold/gold-plugin.cpp')
-rw-r--r--llvm/tools/gold/gold-plugin.cpp50
1 files changed, 33 insertions, 17 deletions
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index dfe3d6f6971..e3351c29fcd 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -735,16 +735,6 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
if (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP && !Res.IsLinkonceOdr)
Resolution = LDPR_PREVAILING_DEF;
- // In ThinLTO mode change all prevailing resolutions to LDPR_PREVAILING_DEF.
- // For ThinLTO the IR files are compiled through the backend independently,
- // so we need to ensure that any prevailing linkonce copy will be emitted
- // into the object file by making it weak. Additionally, we can skip the
- // IRONLY handling for internalization, which isn't performed in ThinLTO
- // mode currently anyway.
- if (options::thinlto && (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP ||
- Resolution == LDPR_PREVAILING_DEF_IRONLY))
- Resolution = LDPR_PREVAILING_DEF;
-
GV->setUnnamedAddr(Res.UnnamedAddr);
GV->setVisibility(Res.Visibility);
@@ -998,6 +988,9 @@ void CodeGen::runLTOPasses() {
M->setDataLayout(TM->createDataLayout());
if (CombinedIndex) {
+ // Apply summary-based LinkOnce/Weak resolution decisions.
+ thinLTOResolveWeakForLinkerModule(*M, *DefinedGlobals);
+
// Apply summary-based internalization decisions. Skip if there are no
// defined globals from the summary since not only is it unnecessary, but
// if this module did not have a summary section the internalizer will
@@ -1322,6 +1315,10 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
// are referenced outside of a single IR module.
DenseSet<GlobalValue::GUID> Preserve;
+ // Keep track of the prevailing copy for each GUID, for use in resolving
+ // weak linkages.
+ DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
+
ModuleSummaryIndex CombinedIndex;
uint64_t NextModuleId = 0;
for (claimed_file &F : Modules) {
@@ -1342,19 +1339,27 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
std::unique_ptr<ModuleSummaryIndex> Index = getModuleSummaryIndexForFile(F);
- // Skip files without a module summary.
- if (Index)
- CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
-
// Use gold's symbol resolution information to identify symbols referenced
- // by more than a single IR module (before importing, which is checked
- // separately).
+ // by more than a single IR module (i.e. referenced by multiple IR modules
+ // or by a non-IR module). Cross references introduced by importing are
+ // checked separately via the export lists. Also track the prevailing copy
+ // for later symbol resolution.
for (auto &Sym : F.syms) {
ld_plugin_symbol_resolution Resolution =
(ld_plugin_symbol_resolution)Sym.resolution;
+ GlobalValue::GUID SymGUID = GlobalValue::getGUID(Sym.name);
if (Resolution != LDPR_PREVAILING_DEF_IRONLY)
- Preserve.insert(GlobalValue::getGUID(Sym.name));
+ Preserve.insert(SymGUID);
+
+ if (Index && (Resolution == LDPR_PREVAILING_DEF ||
+ Resolution == LDPR_PREVAILING_DEF_IRONLY ||
+ Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
+ PrevailingCopy[SymGUID] = Index->getGlobalValueSummary(SymGUID);
}
+
+ // Skip files without a module summary.
+ if (Index)
+ CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
}
// Collect for each module the list of function it defines (GUID ->
@@ -1368,6 +1373,12 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
ComputeCrossModuleImport(CombinedIndex, ModuleToDefinedGVSummaries,
ImportLists, ExportLists);
+ auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
+ const auto &Prevailing = PrevailingCopy.find(GUID);
+ assert(Prevailing != PrevailingCopy.end());
+ return Prevailing->second == S;
+ };
+
// Callback for internalization, to prevent internalization of symbols
// that were not candidates initially, and those that are being imported
// (which introduces new cross references).
@@ -1378,6 +1389,11 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
Preserve.count(GUID);
};
+ thinLTOResolveWeakForLinkerInIndex(
+ CombinedIndex, isPrevailing,
+ [](StringRef ModuleIdentifier, GlobalValue::GUID GUID,
+ GlobalValue::LinkageTypes NewLinkage) {});
+
// Use global summary-based analysis to identify symbols that can be
// internalized (because they aren't exported or preserved as per callback).
// Changes are made in the index, consumed in the ThinLTO backends.
OpenPOWER on IntegriCloud