summaryrefslogtreecommitdiffstats
path: root/llvm/lib/LTO/LTOCodeGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/LTO/LTOCodeGenerator.cpp')
-rw-r--r--llvm/lib/LTO/LTOCodeGenerator.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 66df23bab1b..70626682d55 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -347,6 +347,12 @@ applyRestriction(GlobalValue &GV,
if (isa<Function>(GV) &&
std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
AsmUsed.insert(&GV);
+
+ // Record the linkage type of non-local symbols so they can be restored prior
+ // to module splitting.
+ if (ShouldRestoreGlobalsLinkage && !GV.hasAvailableExternallyLinkage() &&
+ !GV.hasLocalLinkage() && GV.hasName())
+ ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
}
static void findUsedValues(GlobalVariable *LLVMUsed,
@@ -454,6 +460,35 @@ void LTOCodeGenerator::applyScopeRestrictions() {
ScopeRestrictionsDone = true;
}
+/// Restore original linkage for symbols that may have been internalized
+void LTOCodeGenerator::restoreLinkageForExternals() {
+ if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
+ return;
+
+ assert(ScopeRestrictionsDone &&
+ "Cannot externalize without internalization!");
+
+ if (ExternalSymbols.empty())
+ return;
+
+ auto externalize = [this](GlobalValue &GV) {
+ if (!GV.hasLocalLinkage() || !GV.hasName())
+ return;
+
+ auto I = ExternalSymbols.find(GV.getName());
+ if (I == ExternalSymbols.end())
+ return;
+
+ GV.setLinkage(I->second);
+ };
+
+ std::for_each(MergedModule->begin(), MergedModule->end(), externalize);
+ std::for_each(MergedModule->global_begin(), MergedModule->global_end(),
+ externalize);
+ std::for_each(MergedModule->alias_begin(), MergedModule->alias_end(),
+ externalize);
+}
+
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
bool DisableGVNLoadPRE,
@@ -504,6 +539,10 @@ bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
preCodeGenPasses.add(createObjCARCContractPass());
preCodeGenPasses.run(*MergedModule);
+ // Re-externalize globals that may have been internalized to increase scope
+ // for splitting
+ restoreLinkageForExternals();
+
// Do code generation. We need to preserve the module in case the client calls
// writeMergedModules() after compilation, but we only need to allow this at
// parallelism level 1. This is achieved by having splitCodeGen return the
@@ -511,7 +550,8 @@ bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
// MergedModule.
MergedModule =
splitCodeGen(std::move(MergedModule), Out, MCpu, FeatureStr, Options,
- RelocModel, CodeModel::Default, CGOptLevel, FileType);
+ RelocModel, CodeModel::Default, CGOptLevel, FileType,
+ ShouldRestoreGlobalsLinkage);
return true;
}
OpenPOWER on IntegriCloud