diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 74 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/FunctionImportUtils.cpp | 5 |
2 files changed, 75 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index 3f0d2624f5d..ec82248d78b 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -75,6 +75,69 @@ static std::unique_ptr<Module> loadFile(const std::string &FileName, namespace { +// Return true if the Summary describes a GlobalValue that can be externally +// referenced, i.e. it does not need renaming (linkage is not local) or renaming +// is possible (does not have a section for instance). +static bool canBeExternallyReferenced(const GlobalValueSummary &Summary) { + if (!Summary.needsRenaming()) + return true; + + if (Summary.hasSection()) + // Can't rename a global that needs renaming if has a section. + return false; + + return true; +} + +// Return true if \p GUID describes a GlobalValue that can be externally +// referenced, i.e. it does not need renaming (linkage is not local) or +// renaming is possible (does not have a section for instance). +static bool canBeExternallyReferenced(const ModuleSummaryIndex &Index, + GlobalValue::GUID GUID) { + auto Summaries = Index.findGlobalValueSummaryList(GUID); + if (Summaries == Index.end()) + return true; + if (Summaries->second.size() != 1) + // If there are multiple globals with this GUID, then we know it is + // not a local symbol, and it is necessarily externally referenced. + return true; + + // We don't need to check for the module path, because if it can't be + // externally referenced and we call it, it is necessarilly in the same + // module + return canBeExternallyReferenced(**Summaries->second.begin()); +} + +// Return true if the global described by \p Summary can be imported in another +// module. +static bool eligibleForImport(const ModuleSummaryIndex &Index, + const GlobalValueSummary &Summary) { + if (!canBeExternallyReferenced(Summary)) + // Can't import a global that needs renaming if has a section for instance. + // FIXME: we may be able to import it by copying it without promotion. + return false; + + // Check references (and potential calls) in the same module. If the current + // value references a global that can't be externally referenced it is not + // eligible for import. + bool AllRefsCanBeExternallyReferenced = + llvm::all_of(Summary.refs(), [&](const ValueInfo &VI) { + return canBeExternallyReferenced(Index, VI.getGUID()); + }); + if (!AllRefsCanBeExternallyReferenced) + return false; + + if (auto *FuncSummary = dyn_cast<FunctionSummary>(&Summary)) { + bool AllCallsCanBeExternallyReferenced = llvm::all_of( + FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) { + return canBeExternallyReferenced(Index, Edge.first.getGUID()); + }); + if (!AllCallsCanBeExternallyReferenced) + return false; + } + return true; +} + /// Given a list of possible callee implementation for a call site, select one /// that fits the \p Threshold. /// @@ -86,7 +149,8 @@ namespace { /// - One that has PGO data attached. /// - [insert you fancy metric here] static const GlobalValueSummary * -selectCallee(const GlobalValueSummaryList &CalleeSummaryList, +selectCallee(const ModuleSummaryIndex &Index, + const GlobalValueSummaryList &CalleeSummaryList, unsigned Threshold) { auto It = llvm::find_if( CalleeSummaryList, @@ -111,6 +175,9 @@ selectCallee(const GlobalValueSummaryList &CalleeSummaryList, if (Summary->instCount() > Threshold) return false; + if (!eligibleForImport(Index, *Summary)) + return false; + return true; }); if (It == CalleeSummaryList.end()) @@ -125,10 +192,9 @@ static const GlobalValueSummary *selectCallee(GlobalValue::GUID GUID, unsigned Threshold, const ModuleSummaryIndex &Index) { auto CalleeSummaryList = Index.findGlobalValueSummaryList(GUID); - if (CalleeSummaryList == Index.end()) { + if (CalleeSummaryList == Index.end()) return nullptr; // This function does not have a summary - } - return selectCallee(CalleeSummaryList->second, Threshold); + return selectCallee(Index, CalleeSummaryList->second, Threshold); } /// Mark the global \p GUID as export by module \p ExportModulePath if found in diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp index f1d12bce06c..4280e96841e 100644 --- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp +++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -64,6 +64,11 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal( if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr()) return false; + if (GVar && GVar->hasSection()) + // Some sections like "__DATA,__cfstring" are "magic" and promotion is not + // allowed. Just disable promotion on any GVar with sections right now. + return false; + // Eventually we only need to promote functions in the exporting module that // are referenced by a potentially exported function (i.e. one that is in the // summary index). |