summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp74
-rw-r--r--llvm/lib/Transforms/Utils/FunctionImportUtils.cpp5
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).
OpenPOWER on IntegriCloud