diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Transforms/IPO/FunctionImport.cpp | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionImport.cpp')
| -rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index 18343030bc6a..2f6cf0ca7087 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -84,6 +84,10 @@ static cl::opt<int> ImportCutoff( "import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)")); +static cl::opt<bool> + ForceImportAll("force-import-all", cl::init(false), cl::Hidden, + cl::desc("Import functions with noinline attribute")); + static cl::opt<float> ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), @@ -227,7 +231,7 @@ selectCallee(const ModuleSummaryIndex &Index, } if ((Summary->instCount() > Threshold) && - !Summary->fflags().AlwaysInline) { + !Summary->fflags().AlwaysInline && !ForceImportAll) { Reason = FunctionImporter::ImportFailureReason::TooLarge; return false; } @@ -240,7 +244,7 @@ selectCallee(const ModuleSummaryIndex &Index, } // Don't bother importing if we can't inline it anyway. - if (Summary->fflags().NoInline) { + if (Summary->fflags().NoInline && !ForceImportAll) { Reason = FunctionImporter::ImportFailureReason::NoInline; return false; } @@ -275,6 +279,29 @@ updateValueInfoForIndirectCalls(const ModuleSummaryIndex &Index, ValueInfo VI) { return Index.getValueInfo(GUID); } +static bool shouldImportGlobal(const ValueInfo &VI, + const GVSummaryMapTy &DefinedGVSummaries) { + const auto &GVS = DefinedGVSummaries.find(VI.getGUID()); + if (GVS == DefinedGVSummaries.end()) + return true; + // We should not skip import if the module contains a definition with + // interposable linkage type. This is required for correctness in + // the situation with two following conditions: + // * the def with interposable linkage is non-prevailing, + // * there is a prevailing def available for import and marked read-only. + // In this case, the non-prevailing def will be converted to a declaration, + // while the prevailing one becomes internal, thus no definitions will be + // available for linking. In order to prevent undefined symbol link error, + // the prevailing definition must be imported. + // FIXME: Consider adding a check that the suitable prevailing definition + // exists and marked read-only. + if (VI.getSummaryList().size() > 1 && + GlobalValue::isInterposableLinkage(GVS->second->linkage())) + return true; + + return false; +} + static void computeImportForReferencedGlobals( const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, @@ -282,7 +309,7 @@ static void computeImportForReferencedGlobals( FunctionImporter::ImportMapTy &ImportList, StringMap<FunctionImporter::ExportSetTy> *ExportLists) { for (auto &VI : Summary.refs()) { - if (DefinedGVSummaries.count(VI.getGUID())) { + if (!shouldImportGlobal(VI, DefinedGVSummaries)) { LLVM_DEBUG( dbgs() << "Ref ignored! Target already in destination module.\n"); continue; @@ -378,6 +405,9 @@ static void computeImportForFunction( 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 + // can safely be imported (see shouldImportGlobal()). LLVM_DEBUG(dbgs() << "ignored! Target already in destination module.\n"); continue; } @@ -461,17 +491,28 @@ static void computeImportForFunction( FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>( VI, Edge.second.getHotness(), Reason, 1); } - LLVM_DEBUG( - dbgs() << "ignored! No qualifying callee with summary found.\n"); - continue; + if (ForceImportAll) { + std::string Msg = std::string("Failed to import function ") + + VI.name().str() + " due to " + + getFailureName(Reason); + auto Error = make_error<StringError>( + Msg, std::make_error_code(std::errc::operation_not_supported)); + logAllUnhandledErrors(std::move(Error), errs(), + "Error importing module: "); + break; + } else { + LLVM_DEBUG(dbgs() + << "ignored! No qualifying callee with summary found.\n"); + continue; + } } // "Resolve" the summary CalleeSummary = CalleeSummary->getBaseObject(); ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary); - assert((ResolvedCalleeSummary->fflags().AlwaysInline || - (ResolvedCalleeSummary->instCount() <= NewThreshold)) && + assert((ResolvedCalleeSummary->fflags().AlwaysInline || ForceImportAll || + (ResolvedCalleeSummary->instCount() <= NewThreshold)) && "selectCallee() didn't honor the threshold"); auto ExportModulePath = ResolvedCalleeSummary->modulePath(); @@ -888,7 +929,6 @@ void llvm::computeDeadSymbols( while (!Worklist.empty()) { auto VI = Worklist.pop_back_val(); for (auto &Summary : VI.getSummaryList()) { - Summary->setLive(true); if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) { // If this is an alias, visit the aliasee VI to ensure that all copies // are marked live and it is added to the worklist for further @@ -1000,7 +1040,6 @@ bool llvm::convertToDeclaration(GlobalValue &GV) { return true; } -/// Fixup prevailing symbol linkages in \p TheModule based on summary analysis. void llvm::thinLTOResolvePrevailingInModule( Module &TheModule, const GVSummaryMapTy &DefinedGlobals) { auto updateLinkage = [&](GlobalValue &GV) { @@ -1009,8 +1048,6 @@ void llvm::thinLTOResolvePrevailingInModule( if (GS == DefinedGlobals.end()) return; auto NewLinkage = GS->second->linkage(); - if (NewLinkage == GV.getLinkage()) - return; if (GlobalValue::isLocalLinkage(GV.getLinkage()) || // Don't internalize anything here, because the code below // lacks necessary correctness checks. Leave this job to @@ -1020,6 +1057,16 @@ void llvm::thinLTOResolvePrevailingInModule( GV.isDeclaration()) return; + // Set the potentially more constraining visibility computed from summaries. + // The DefaultVisibility condition is because older GlobalValueSummary does + // not record DefaultVisibility and we don't want to change protected/hidden + // to default. + if (GS->second->getVisibility() != GlobalValue::DefaultVisibility) + GV.setVisibility(GS->second->getVisibility()); + + if (NewLinkage == GV.getLinkage()) + return; + // Check for a non-prevailing def that has interposable linkage // (e.g. non-odr weak or linkonce). In that case we can't simply // convert to available_externally, since it would lose the |
