diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 45 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/FunctionImportUtils.cpp | 21 |
2 files changed, 59 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index 1196dd0099b..60ca8e32897 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -294,10 +294,8 @@ static void computeImportForReferencedGlobals( LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n"); for (auto &RefSummary : VI.getSummaryList()) - if (RefSummary->getSummaryKind() == GlobalValueSummary::GlobalVarKind && - !RefSummary->notEligibleToImport() && - !GlobalValue::isInterposableLinkage(RefSummary->linkage()) && - RefSummary->refs().empty()) { + if (isa<GlobalVarSummary>(RefSummary.get()) && + canImportGlobalVar(RefSummary.get())) { auto ILI = ImportList[RefSummary->modulePath()].insert(VI.getGUID()); // Only update stat if we haven't already imported this variable. if (ILI.second) @@ -824,6 +822,25 @@ void llvm::computeDeadSymbols( NumLiveSymbols += LiveSymbols; } +// Compute dead symbols and propagate constants in combined index. +void llvm::computeDeadSymbolsWithConstProp( + ModuleSummaryIndex &Index, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, + function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing, + bool ImportEnabled) { + computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing); + if (ImportEnabled) { + Index.propagateConstants(GUIDPreservedSymbols); + } else { + // If import is disabled we should drop read-only attribute + // from all summaries to prevent internalization. + for (auto &P : Index) + for (auto &S : P.second.SummaryList) + if (auto *GVS = dyn_cast<GlobalVarSummary>(S.get())) + GVS->setReadOnly(false); + } +} + /// Compute the set of summaries needed for a ThinLTO backend compilation of /// \p ModulePath. void llvm::gatherImportedSummariesForModule( @@ -1020,6 +1037,22 @@ static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) { return NewFn; } +// Internalize values that we marked with specific attribute +// in processGlobalForThinLTO. +static void internalizeImmutableGVs(Module &M) { + for (auto &GV : M.globals()) { + // Skip GVs which have been converted to declarations + // by dropDeadSymbols. + if (GV.isDeclaration()) + continue; + if (auto *GVar = dyn_cast<GlobalVariable>(&GV)) + if (GVar->hasAttribute("thinlto-internalize")) { + GVar->setLinkage(GlobalValue::InternalLinkage); + GVar->setVisibility(GlobalValue::DefaultVisibility); + } + } +} + // Automatically import functions in Module \p DestModule based on the summaries // index. Expected<bool> FunctionImporter::importFunctions( @@ -1143,6 +1176,8 @@ Expected<bool> FunctionImporter::importFunctions( NumImportedModules++; } + internalizeImmutableGVs(DestModule); + NumImportedFunctions += (ImportedCount - ImportedGVCount); NumImportedGlobalVars += ImportedGVCount; @@ -1159,7 +1194,7 @@ static bool doImportingForModule(Module &M) { if (SummaryFile.empty()) report_fatal_error("error: -function-import requires -summary-file\n"); Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr = - getModuleSummaryIndexForFile(SummaryFile); + getModuleSummaryIndexForFile(SummaryFile); if (!IndexPtrOrErr) { logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(), "Error loading file '" + SummaryFile + "': "); diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp index 479816a339d..89e74da4d99 100644 --- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp +++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -204,8 +204,9 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { // Check the summaries to see if the symbol gets resolved to a known local // definition. + ValueInfo VI; if (GV.hasName()) { - ValueInfo VI = ImportIndex.getValueInfo(GV.getGUID()); + VI = ImportIndex.getValueInfo(GV.getGUID()); if (VI && VI.isDSOLocal()) { GV.setDSOLocal(true); if (GV.hasDLLImportStorageClass()) @@ -213,6 +214,22 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { } } + // Mark read-only variables which can be imported with specific attribute. + // We can't internalize them now because IRMover will fail to link variable + // definitions to their external declarations during ThinLTO import. We'll + // internalize read-only variables later, after import is finished. + // See internalizeImmutableGVs. + // + // If global value dead stripping is not enabled in summary then + // propagateConstants hasn't been run (may be because we're using + // distriuted import. We can't internalize GV in such case. + if (!GV.isDeclaration() && VI && ImportIndex.withGlobalValueDeadStripping()) { + const auto &SL = VI.getSummaryList(); + auto *GVS = SL.empty() ? nullptr : dyn_cast<GlobalVarSummary>(SL[0].get()); + if (GVS && GVS->isReadOnly()) + cast<GlobalVariable>(&GV)->addAttribute("thinlto-internalize"); + } + bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { @@ -230,7 +247,7 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { // Remove functions imported as available externally defs from comdats, // as this is a declaration for the linker, and will be dropped eventually. // It is illegal for comdats to contain declarations. - auto *GO = dyn_cast_or_null<GlobalObject>(&GV); + auto *GO = dyn_cast<GlobalObject>(&GV); if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { // The IRMover should not have placed any imported declarations in // a comdat, so the only declaration that should be in a comdat |