diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionImport.cpp')
| -rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 149 |
1 files changed, 90 insertions, 59 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index 2f6cf0ca7087..d9b43109f629 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -187,23 +188,6 @@ selectCallee(const ModuleSummaryIndex &Index, return false; } - // For SamplePGO, in computeImportForFunction the OriginalId - // may have been used to locate the callee summary list (See - // comment there). - // The mapping from OriginalId to GUID may return a GUID - // that corresponds to a static variable. Filter it out here. - // This can happen when - // 1) There is a call to a library function which is not defined - // in the index. - // 2) There is a static variable with the OriginalGUID identical - // to the GUID of the library function in 1); - // When this happens, the logic for SamplePGO kicks in and - // the static variable in 2) will be found, which needs to be - // filtered out. - if (GVSummary->getSummaryKind() == GlobalValueSummary::GlobalVarKind) { - Reason = FunctionImporter::ImportFailureReason::GlobalVar; - return false; - } if (GlobalValue::isInterposableLinkage(GVSummary->linkage())) { Reason = FunctionImporter::ImportFailureReason::InterposableLinkage; // There is no point in importing these, we can't inline them @@ -264,21 +248,6 @@ using EdgeInfo = } // anonymous namespace -static ValueInfo -updateValueInfoForIndirectCalls(const ModuleSummaryIndex &Index, ValueInfo VI) { - if (!VI.getSummaryList().empty()) - return VI; - // For SamplePGO, the indirect call targets for local functions will - // have its original name annotated in profile. We try to find the - // corresponding PGOFuncName as the GUID. - // FIXME: Consider updating the edges in the graph after building - // it, rather than needing to perform this mapping on each walk. - auto GUID = Index.getGUIDFromOriginalID(VI.getGUID()); - if (GUID == 0) - return ValueInfo(); - return Index.getValueInfo(GUID); -} - static bool shouldImportGlobal(const ValueInfo &VI, const GVSummaryMapTy &DefinedGVSummaries) { const auto &GVS = DefinedGVSummaries.find(VI.getGUID()); @@ -400,10 +369,6 @@ static void computeImportForFunction( continue; } - VI = updateValueInfoForIndirectCalls(Index, VI); - if (!VI) - continue; - if (DefinedGVSummaries.count(VI.getGUID())) { // FIXME: Consider not skipping import if the module contains // a non-prevailing def with interposable linkage. The prevailing copy @@ -496,7 +461,7 @@ static void computeImportForFunction( VI.name().str() + " due to " + getFailureName(Reason); auto Error = make_error<StringError>( - Msg, std::make_error_code(std::errc::operation_not_supported)); + Msg, make_error_code(errc::not_supported)); logAllUnhandledErrors(std::move(Error), errs(), "Error importing module: "); break; @@ -839,16 +804,61 @@ void llvm::ComputeCrossModuleImportForModuleFromIndex( #endif } -void llvm::computeDeadSymbols( +// For SamplePGO, the indirect call targets for local functions will +// have its original name annotated in profile. We try to find the +// corresponding PGOFuncName as the GUID, and fix up the edges +// accordingly. +void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, + FunctionSummary *FS) { + for (auto &EI : FS->mutableCalls()) { + if (!EI.first.getSummaryList().empty()) + continue; + auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID()); + if (GUID == 0) + continue; + // Update the edge to point directly to the correct GUID. + auto VI = Index.getValueInfo(GUID); + if (llvm::any_of( + VI.getSummaryList(), + [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) { + // The mapping from OriginalId to GUID may return a GUID + // that corresponds to a static variable. Filter it out here. + // This can happen when + // 1) There is a call to a library function which is not defined + // in the index. + // 2) There is a static variable with the OriginalGUID identical + // to the GUID of the library function in 1); + // When this happens the static variable in 2) will be found, + // which needs to be filtered out. + return SummaryPtr->getSummaryKind() == + GlobalValueSummary::GlobalVarKind; + })) + continue; + EI.first = VI; + } +} + +void llvm::updateIndirectCalls(ModuleSummaryIndex &Index) { + for (const auto &Entry : Index) { + for (auto &S : Entry.second.SummaryList) { + if (auto *FS = dyn_cast<FunctionSummary>(S.get())) + updateValueInfoForIndirectCalls(Index, FS); + } + } +} + +void llvm::computeDeadSymbolsAndUpdateIndirectCalls( ModuleSummaryIndex &Index, const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) { assert(!Index.withGlobalValueDeadStripping()); - if (!ComputeDead) - return; - if (GUIDPreservedSymbols.empty()) - // Don't do anything when nothing is live, this is friendly with tests. + if (!ComputeDead || + // Don't do anything when nothing is live, this is friendly with tests. + GUIDPreservedSymbols.empty()) { + // Still need to update indirect calls. + updateIndirectCalls(Index); return; + } unsigned LiveSymbols = 0; SmallVector<ValueInfo, 128> Worklist; Worklist.reserve(GUIDPreservedSymbols.size() * 2); @@ -863,13 +873,16 @@ void llvm::computeDeadSymbols( // Add values flagged in the index as live roots to the worklist. for (const auto &Entry : Index) { auto VI = Index.getValueInfo(Entry); - for (auto &S : Entry.second.SummaryList) + for (auto &S : Entry.second.SummaryList) { + if (auto *FS = dyn_cast<FunctionSummary>(S.get())) + updateValueInfoForIndirectCalls(Index, FS); if (S->isLive()) { LLVM_DEBUG(dbgs() << "Live root: " << VI << "\n"); Worklist.push_back(VI); ++LiveSymbols; break; } + } } // Make value live and add it to the worklist if it was not live before. @@ -882,9 +895,6 @@ void llvm::computeDeadSymbols( // binary, which increases the binary size unnecessarily. Note that // if this code changes, the importer needs to change so that edges // to functions marked dead are skipped. - VI = updateValueInfoForIndirectCalls(Index, VI); - if (!VI) - return; if (llvm::any_of(VI.getSummaryList(), [](const std::unique_ptr<llvm::GlobalValueSummary> &S) { @@ -958,7 +968,8 @@ void llvm::computeDeadSymbolsWithConstProp( const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled) { - computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing); + computeDeadSymbolsAndUpdateIndirectCalls(Index, GUIDPreservedSymbols, + isPrevailing); if (ImportEnabled) Index.propagateAttributes(GUIDPreservedSymbols); } @@ -1040,13 +1051,33 @@ bool llvm::convertToDeclaration(GlobalValue &GV) { return true; } -void llvm::thinLTOResolvePrevailingInModule( - Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { - auto updateLinkage = [&](GlobalValue &GV) { +void llvm::thinLTOFinalizeInModule(Module &TheModule, + const GVSummaryMapTy &DefinedGlobals, + bool PropagateAttrs) { + auto FinalizeInModule = [&](GlobalValue &GV, bool Propagate = false) { // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); if (GS == DefinedGlobals.end()) return; + + if (Propagate) + if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GS->second)) { + if (Function *F = dyn_cast<Function>(&GV)) { + // TODO: propagate ReadNone and ReadOnly. + if (FS->fflags().ReadNone && !F->doesNotAccessMemory()) + F->setDoesNotAccessMemory(); + + if (FS->fflags().ReadOnly && !F->onlyReadsMemory()) + F->setOnlyReadsMemory(); + + if (FS->fflags().NoRecurse && !F->doesNotRecurse()) + F->setDoesNotRecurse(); + + if (FS->fflags().NoUnwind && !F->doesNotThrow()) + F->setDoesNotThrow(); + } + } + auto NewLinkage = GS->second->linkage(); if (GlobalValue::isLocalLinkage(GV.getLinkage()) || // Don't internalize anything here, because the code below @@ -1105,11 +1136,11 @@ void llvm::thinLTOResolvePrevailingInModule( // Process functions and global now for (auto &GV : TheModule) - updateLinkage(GV); + FinalizeInModule(GV, PropagateAttrs); for (auto &GV : TheModule.globals()) - updateLinkage(GV); + FinalizeInModule(GV); for (auto &GV : TheModule.aliases()) - updateLinkage(GV); + FinalizeInModule(GV); } /// Run internalization on \p TheModule based on symmary analysis. @@ -1153,7 +1184,7 @@ void llvm::thinLTOInternalizeModule(Module &TheModule, /// Make alias a clone of its aliasee. static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) { - Function *Fn = cast<Function>(GA->getBaseObject()); + Function *Fn = cast<Function>(GA->getAliaseeObject()); ValueToValueMapTy VMap; Function *NewFn = CloneFunction(Fn, VMap); @@ -1259,12 +1290,12 @@ Expected<bool> FunctionImporter::importFunctions( if (Error Err = GA.materialize()) return std::move(Err); // Import alias as a copy of its aliasee. - GlobalObject *Base = GA.getBaseObject(); - if (Error Err = Base->materialize()) + GlobalObject *GO = GA.getAliaseeObject(); + if (Error Err = GO->materialize()) return std::move(Err); auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA); - LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << Base->getGUID() - << " " << Base->getName() << " from " + LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << GO->getGUID() << " " + << GO->getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (EnableImportMetadata) { // Add 'thinlto_src_module' metadata for statistics and debugging. @@ -1303,7 +1334,7 @@ Expected<bool> FunctionImporter::importFunctions( std::move(SrcModule), GlobalsToImport.getArrayRef(), [](GlobalValue &, IRMover::ValueAdder) {}, /*IsPerformingImport=*/true)) - report_fatal_error("Function Import: link error: " + + report_fatal_error(Twine("Function Import: link error: ") + toString(std::move(Err))); ImportedCount += GlobalsToImport.size(); |
