diff options
Diffstat (limited to 'llvm/lib/LTO/LTOCodeGenerator.cpp')
| -rw-r--r-- | llvm/lib/LTO/LTOCodeGenerator.cpp | 42 |
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; } |

