diff options
author | George Rimar <grimar@accesssoftek.com> | 2018-01-29 08:03:30 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2018-01-29 08:03:30 +0000 |
commit | eaf5172ca6be291677f6f84cffae0c66656600a3 (patch) | |
tree | a4a2196f3b147192435ca6632a267cc7cd06c4d8 /llvm/lib | |
parent | 62b62356fae9a66a7bdbf33d5790d7db39c9af5e (diff) | |
download | bcm5719-llvm-eaf5172ca6be291677f6f84cffae0c66656600a3.tar.gz bcm5719-llvm-eaf5172ca6be291677f6f84cffae0c66656600a3.zip |
[ThinLTO] - Stop internalizing and drop non-prevailing symbols.
Implementation marks non-prevailing symbols as not live in the summary.
Then them are dropped in backends.
Fixes https://bugs.llvm.org/show_bug.cgi?id=35938
Differential revision: https://reviews.llvm.org/D42107
llvm-svn: 323633
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/LTO/LTOBackend.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 50 |
4 files changed, 90 insertions, 28 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 98567fb6202..0e705718a64 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -423,6 +423,14 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, "Multiple prevailing defs are not allowed"); GlobalRes.Prevailing = true; GlobalRes.IRName = Sym.getIRName(); + } else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) { + // Sometimes it can be two copies of symbol in a module and prevailing + // symbol can have no IR name. That might happen if symbol is defined in + // module level inline asm block. In case we have multiple modules with + // the same symbol we want to use IR name of the prevailing symbol. + // Otherwise, if we haven't seen a prevailing symbol, set the name so that + // we can later use it to check if there is any prevailing copy in IR. + GlobalRes.IRName = Sym.getIRName(); } // Set the partition to external if we know it is re-defined by the linker @@ -747,12 +755,31 @@ unsigned LTO::getMaxTasks() const { Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { // Compute "dead" symbols, we don't want to import/export these! DenseSet<GlobalValue::GUID> GUIDPreservedSymbols; - for (auto &Res : GlobalResolutions) + DenseMap<GlobalValue::GUID, PrevailingType> GUIDPrevailingResolutions; + for (auto &Res : GlobalResolutions) { + // Normally resolution have IR name of symbol. We can do nothing here + // otherwise. See comments in GlobalResolution struct for more details. + if (Res.second.IRName.empty()) + continue; + + GlobalValue::GUID GUID = GlobalValue::getGUID( + GlobalValue::dropLLVMManglingEscape(Res.second.IRName)); + if (Res.second.VisibleOutsideSummary && Res.second.Prevailing) GUIDPreservedSymbols.insert(GlobalValue::getGUID( GlobalValue::dropLLVMManglingEscape(Res.second.IRName))); - computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols); + GUIDPrevailingResolutions[GUID] = + Res.second.Prevailing ? PrevailingType::Yes : PrevailingType::No; + } + + auto isPrevailing = [&](GlobalValue::GUID G) { + auto It = GUIDPrevailingResolutions.find(G); + if (It == GUIDPrevailingResolutions.end()) + return PrevailingType::Unknown; + return It->second; + }; + computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols, isPrevailing); if (auto E = runRegularLTO(AddStream)) return E; @@ -800,7 +827,7 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { if (!Conf.CodeGenOnly) { for (const auto &R : GlobalResolutions) { - if (!R.second.Prevailing) + if (!R.second.isPrevailingIRSymbol()) continue; if (R.second.Partition != 0 && R.second.Partition != GlobalResolution::External) @@ -1114,7 +1141,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache) { // If the symbol does not have external references or it is not prevailing, // then not need to mark it as exported from a ThinLTO partition. if (Res.second.Partition != GlobalResolution::External || - !Res.second.Prevailing) + !Res.second.isPrevailingIRSymbol()) continue; auto GUID = GlobalValue::getGUID( GlobalValue::dropLLVMManglingEscape(Res.second.IRName)); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 07053267750..1898d4bb25c 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -399,6 +399,17 @@ Error lto::backend(Config &C, AddStreamFn AddStream, return Error::success(); } +static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, + const ModuleSummaryIndex &Index) { + for (auto &GV : Mod) { + auto It = DefinedGlobals.find(GV.getGUID()); + if (It == DefinedGlobals.end()) + continue; + if (!Index.isGlobalValueLive(It->second)) + convertToDeclaration(GV); + } +} + Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, Module &Mod, const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, @@ -420,6 +431,8 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, renameModuleForThinLTO(Mod, CombinedIndex); + dropDeadSymbols(Mod, DefinedGlobals, CombinedIndex); + thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals); if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod)) diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index b5ac5a77e9c..b2e34c54428 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -621,6 +621,18 @@ static void internalizeAndPromoteInIndex( thinLTOInternalizeAndPromoteInIndex(Index, isExported); } +static void computeDeadSymbolsInIndex( + ModuleSummaryIndex &Index, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { + // We have no symbols resolution available. And can't do any better now in the + // case where the prevailing symbol is in a native object. It can be refined + // with linker information in the future. + auto isPrevailing = [&](GlobalValue::GUID G) { + return PrevailingType::Unknown; + }; + computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing); +} + /** * Perform promotion and renaming of exported internal functions. * Index is updated to reflect linkage changes from weak resolution. @@ -639,7 +651,7 @@ void ThinLTOCodeGenerator::promote(Module &TheModule, PreservedSymbols, Triple(TheModule.getTargetTriple())); // Compute "dead" symbols, we don't want to import/export these! - computeDeadSymbols(Index, GUIDPreservedSymbols); + computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols); // Generate import/export list StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); @@ -678,7 +690,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule, PreservedSymbols, Triple(TheModule.getTargetTriple())); // Compute "dead" symbols, we don't want to import/export these! - computeDeadSymbols(Index, GUIDPreservedSymbols); + computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols); // Generate import/export list StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); @@ -755,7 +767,7 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule, Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); // Compute "dead" symbols, we don't want to import/export these! - computeDeadSymbols(Index, GUIDPreservedSymbols); + computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols); // Generate import/export list StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); @@ -901,7 +913,7 @@ void ThinLTOCodeGenerator::run() { computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple); // Compute "dead" symbols, we don't want to import/export these! - computeDeadSymbols(*Index, GUIDPreservedSymbols); + computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols); // Collect the import/export lists for all modules from the call-graph in the // combined index. diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index ed85c20051e..8dbee83bc3e 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -163,6 +163,9 @@ selectCallee(const ModuleSummaryIndex &Index, CalleeSummaryList, [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) { auto *GVSummary = SummaryPtr.get(); + if (!Index.isGlobalValueLive(GVSummary)) + return false; + // For SamplePGO, in computeImportForFunction the OriginalId // may have been used to locate the callee summary list (See // comment there). @@ -495,7 +498,8 @@ void llvm::ComputeCrossModuleImportForModuleFromIndex( void llvm::computeDeadSymbols( ModuleSummaryIndex &Index, - const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, + function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) { assert(!Index.withGlobalValueDeadStripping()); if (!ComputeDead) return; @@ -524,7 +528,6 @@ void llvm::computeDeadSymbols( } // Make value live and add it to the worklist if it was not live before. - // FIXME: we should only make the prevailing copy live here auto visit = [&](ValueInfo VI) { // FIXME: If we knew which edges were created for indirect call profiles, // we could skip them here. Any that are live should be reached via @@ -540,6 +543,11 @@ void llvm::computeDeadSymbols( for (auto &S : VI.getSummaryList()) if (S->isLive()) return; + + // We do not keep live symbols that are known to be non-prevailing. + if (isPrevailing(VI.getGUID()) == PrevailingType::No) + return; + for (auto &S : VI.getSummaryList()) S->setLive(true); ++LiveSymbols; @@ -550,6 +558,8 @@ void llvm::computeDeadSymbols( auto VI = Worklist.pop_back_val(); for (auto &Summary : VI.getSummaryList()) { GlobalValueSummary *Base = Summary->getBaseObject(); + // Set base value live in case it is an alias. + Base->setLive(true); for (auto Ref : Base->refs()) visit(Ref); if (auto *FS = dyn_cast<FunctionSummary>(Base)) @@ -603,26 +613,26 @@ llvm::EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, return std::error_code(); } +void llvm::convertToDeclaration(GlobalValue &GV) { + DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName() << "\n"); + if (Function *F = dyn_cast<Function>(&GV)) { + F->deleteBody(); + F->clearMetadata(); + } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) { + V->setInitializer(nullptr); + V->setLinkage(GlobalValue::ExternalLinkage); + V->clearMetadata(); + } else + // For now we don't resolve or drop aliases. Once we do we'll + // need to add support here for creating either a function or + // variable declaration, and return the new GlobalValue* for + // the caller to use. + llvm_unreachable("Expected function or variable"); +} + /// Fixup WeakForLinker linkages in \p TheModule based on summary analysis. void llvm::thinLTOResolveWeakForLinkerModule( Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { - auto ConvertToDeclaration = [](GlobalValue &GV) { - DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName() << "\n"); - if (Function *F = dyn_cast<Function>(&GV)) { - F->deleteBody(); - F->clearMetadata(); - } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) { - V->setInitializer(nullptr); - V->setLinkage(GlobalValue::ExternalLinkage); - V->clearMetadata(); - } else - // For now we don't resolve or drop aliases. Once we do we'll - // need to add support here for creating either a function or - // variable declaration, and return the new GlobalValue* for - // the caller to use. - llvm_unreachable("Expected function or variable"); - }; - auto updateLinkage = [&](GlobalValue &GV) { // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); @@ -653,7 +663,7 @@ void llvm::thinLTOResolveWeakForLinkerModule( // the definition in that case. if (GlobalValue::isAvailableExternallyLinkage(NewLinkage) && GlobalValue::isInterposableLinkage(GV.getLinkage())) - ConvertToDeclaration(GV); + convertToDeclaration(GV); else { DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " << GV.getLinkage() << " to " << NewLinkage << "\n"); |