summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-04-16 06:56:44 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-04-16 06:56:44 +0000
commit2d28f7aa07483ba57428c654170467966581849c (patch)
tree57505eb0c7546aa598bca418a57f455fe0e74bf4 /llvm/lib/Transforms
parentd82f494aa41ffbac2586d4b090af33aa51e3dd15 (diff)
downloadbcm5719-llvm-2d28f7aa07483ba57428c654170467966581849c.tar.gz
bcm5719-llvm-2d28f7aa07483ba57428c654170467966581849c.zip
ThinLTO: Make aliases explicit in the summary
To be able to work accurately on the reference graph when taking decision about internalizing, promoting, renaming, etc. We need to have the alias information explicit. Differential Revision: http://reviews.llvm.org/D18836 From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 266517
Diffstat (limited to 'llvm/lib/Transforms')
-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