summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/FunctionImport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionImport.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp86
1 files changed, 54 insertions, 32 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 088b114e787..d6dfe17518b 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -79,13 +79,16 @@ namespace {
/// number of source modules parsed/linked.
/// - One that has PGO data attached.
/// - [insert you fancy metric here]
-static const FunctionSummary *
+static const GlobalValueSummary *
selectCallee(const GlobalValueInfoList &CalleeInfoList, unsigned Threshold) {
auto It = llvm::find_if(
CalleeInfoList, [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
assert(GlobInfo->summary() &&
"We should not have a Global Info without summary");
- auto *Summary = cast<FunctionSummary>(GlobInfo->summary());
+ auto *GVSummary = GlobInfo->summary();
+ if (auto *AS = dyn_cast<AliasSummary>(GVSummary))
+ GVSummary = &AS->getAliasee();
+ auto *Summary = cast<FunctionSummary>(GVSummary);
if (GlobalValue::isWeakAnyLinkage(Summary->linkage()))
return false;
@@ -98,14 +101,14 @@ selectCallee(const GlobalValueInfoList &CalleeInfoList, unsigned Threshold) {
if (It == CalleeInfoList.end())
return nullptr;
- return cast<FunctionSummary>((*It)->summary());
+ return cast<GlobalValueSummary>((*It)->summary());
}
/// Return the summary for the function \p GUID that fits the \p Threshold, or
/// null if there's no match.
-static const FunctionSummary *selectCallee(GlobalValue::GUID GUID,
- unsigned Threshold,
- const ModuleSummaryIndex &Index) {
+static const GlobalValueSummary *selectCallee(GlobalValue::GUID GUID,
+ unsigned Threshold,
+ const ModuleSummaryIndex &Index) {
auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
if (CalleeInfoList == Index.end()) {
return nullptr; // This function does not have a summary
@@ -140,7 +143,7 @@ using EdgeInfo = std::pair<const FunctionSummary *, unsigned /* Threshold */>;
static void computeImportForFunction(
const FunctionSummary &Summary, const ModuleSummaryIndex &Index,
unsigned Threshold,
- const std::map<GlobalValue::GUID, FunctionSummary *> &DefinedFunctions,
+ const std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedFunctions,
SmallVectorImpl<EdgeInfo> &Worklist,
FunctionImporter::ImportMapTy &ImportsForModule,
StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
@@ -158,11 +161,19 @@ static void computeImportForFunction(
DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");
continue;
}
- assert(CalleeSummary->instCount() <= Threshold &&
+ // "Resolve" the summary, traversing alias,
+ const FunctionSummary *ResolvedCalleeSummary;
+ if (isa<AliasSummary>(CalleeSummary))
+ ResolvedCalleeSummary = cast<FunctionSummary>(
+ &cast<AliasSummary>(CalleeSummary)->getAliasee());
+ else
+ ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
+
+ assert(ResolvedCalleeSummary->instCount() <= Threshold &&
"selectCallee() didn't honor the threshold");
- auto &ProcessedThreshold =
- ImportsForModule[CalleeSummary->modulePath()][GUID];
+ auto ExportModulePath = ResolvedCalleeSummary->modulePath();
+ auto &ProcessedThreshold = ImportsForModule[ExportModulePath][GUID];
/// Since the traversal of the call graph is DFS, we can revisit a function
/// a second time with a higher threshold. In this case, it is added back to
/// the worklist with the new threshold.
@@ -175,18 +186,17 @@ static void computeImportForFunction(
ProcessedThreshold = Threshold;
// Make exports in the source module.
- auto ExportModulePath = CalleeSummary->modulePath();
if (ExportLists) {
auto &ExportList = (*ExportLists)[ExportModulePath];
ExportList.insert(GUID);
// Mark all functions and globals referenced by this function as exported
// to the outside if they are defined in the same source module.
- for (auto &Edge : CalleeSummary->calls()) {
+ for (auto &Edge : ResolvedCalleeSummary->calls()) {
auto CalleeGUID = Edge.first.getGUID();
if (isGlobalExported(Index, ExportModulePath, CalleeGUID))
ExportList.insert(CalleeGUID);
}
- for (auto &Ref : CalleeSummary->refs()) {
+ for (auto &Ref : ResolvedCalleeSummary->refs()) {
auto GUID = Ref.getGUID();
if (isGlobalExported(Index, ExportModulePath, GUID))
ExportList.insert(GUID);
@@ -194,7 +204,7 @@ static void computeImportForFunction(
}
// Insert the newly imported function to the worklist.
- Worklist.push_back(std::make_pair(CalleeSummary, Threshold));
+ Worklist.push_back(std::make_pair(ResolvedCalleeSummary, Threshold));
}
}
@@ -202,7 +212,7 @@ static void computeImportForFunction(
/// as well as the list of "exports", i.e. the list of symbols referenced from
/// another module (that may require promotion).
static void ComputeImportForModule(
- const std::map<GlobalValue::GUID, FunctionSummary *> &DefinedFunctions,
+ const std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedFunctions,
const ModuleSummaryIndex &Index,
FunctionImporter::ImportMapTy &ImportsForModule,
StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
@@ -214,8 +224,11 @@ static void ComputeImportForModule(
// module
for (auto &FuncInfo : DefinedFunctions) {
auto *Summary = FuncInfo.second;
+ if (auto *AS = dyn_cast<AliasSummary>(Summary))
+ Summary = &AS->getAliasee();
+ auto *FuncSummary = cast<FunctionSummary>(Summary);
DEBUG(dbgs() << "Initalize import for " << FuncInfo.first << "\n");
- computeImportForFunction(*Summary, Index, ImportInstrLimit,
+ computeImportForFunction(*FuncSummary, Index, ImportInstrLimit,
DefinedFunctions, Worklist, ImportsForModule,
ExportLists);
}
@@ -245,16 +258,20 @@ void llvm::ComputeCrossModuleImport(
// Collect for each module the list of function it defines.
// GUID -> Summary
- StringMap<std::map<GlobalValue::GUID, FunctionSummary *>>
+ StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
Module2FunctionInfoMap(ModuleCount);
for (auto &GlobalList : Index) {
auto GUID = GlobalList.first;
for (auto &GlobInfo : GlobalList.second) {
- auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobInfo->summary());
- if (!Summary)
+ auto *Summary = GlobInfo->summary();
+ if (isa<GlobalVarSummary>(Summary))
/// Ignore global variable, focus on functions
continue;
+ if (auto *AS = dyn_cast<AliasSummary>(Summary))
+ if (isa<GlobalVarSummary>(&AS->getAliasee()))
+ /// Ignore alias to global variable, focus on functions
+ continue;
DEBUG(dbgs() << "Adding definition: Module '" << Summary->modulePath()
<< "' defines '" << GUID << "'\n");
Module2FunctionInfoMap[Summary->modulePath()][GUID] = Summary;
@@ -295,7 +312,7 @@ void llvm::ComputeCrossModuleImportForModule(
// Collect the list of functions this module defines.
// GUID -> Summary
- std::map<GlobalValue::GUID, FunctionSummary *> FunctionInfoMap;
+ std::map<GlobalValue::GUID, GlobalValueSummary *> FunctionInfoMap;
Index.collectDefinedFunctionsForModule(ModulePath, FunctionInfoMap);
// Compute the import list for this module.
@@ -358,7 +375,7 @@ bool FunctionImporter::importFunctions(
GlobalsToImport.insert(&GV);
}
}
- for (auto &GV : SrcModule->aliases()) {
+ for (auto &GV : SrcModule->globals()) {
if (!GV.hasName())
continue;
auto GUID = GV.getGUID();
@@ -367,18 +384,11 @@ bool FunctionImporter::importFunctions(
<< GV.getName() << " from " << SrcModule->getSourceFileName()
<< "\n");
if (Import) {
- // Alias can't point to "available_externally". However when we import
- // linkOnceODR the linkage does not change. So we import the alias
- // and aliasee only in this case.
- const GlobalObject *GO = GV.getBaseObject();
- if (!GO->hasLinkOnceODRLinkage())
- continue;
GV.materialize();
GlobalsToImport.insert(&GV);
- GlobalsToImport.insert(GO);
}
}
- for (auto &GV : SrcModule->globals()) {
+ for (auto &GV : SrcModule->aliases()) {
if (!GV.hasName())
continue;
auto GUID = GV.getGUID();
@@ -387,6 +397,20 @@ bool FunctionImporter::importFunctions(
<< GV.getName() << " from " << SrcModule->getSourceFileName()
<< "\n");
if (Import) {
+ // Alias can't point to "available_externally". However when we import
+ // linkOnceODR the linkage does not change. So we import the alias
+ // and aliasee only in this case.
+ GlobalObject *GO = GV.getBaseObject();
+ if (!GO->hasLinkOnceODRLinkage())
+ continue;
+#ifndef NDEBUG
+ if (!GlobalsToImport.count(GO))
+ DEBUG(dbgs() << " alias triggers importing aliasee " << GO->getGUID()
+ << " " << GO->getName() << " from "
+ << SrcModule->getSourceFileName() << "\n");
+#endif
+ GO->materialize();
+ GlobalsToImport.insert(GO);
GV.materialize();
GlobalsToImport.insert(&GV);
}
@@ -464,9 +488,7 @@ public:
static char ID;
/// Specify pass name for debug output
- const char *getPassName() const override {
- return "Function Importing";
- }
+ const char *getPassName() const override { return "Function Importing"; }
explicit FunctionImportPass(const ModuleSummaryIndex *Index = nullptr)
: ModulePass(ID), Index(Index) {}
OpenPOWER on IntegriCloud