summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-03-19 00:40:31 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-03-19 00:40:31 +0000
commit8d05185a26ecbd1079b43651c427508a6156f1ea (patch)
tree8795898d6605a0f3e13c3d4e3dda784c2a08dddd /llvm/lib
parent67e03a1ce6df29e880727dbf38eb5db250a1a6ae (diff)
downloadbcm5719-llvm-8d05185a26ecbd1079b43651c427508a6156f1ea.tar.gz
bcm5719-llvm-8d05185a26ecbd1079b43651c427508a6156f1ea.zip
Rework linkInModule(), making it oblivious to ThinLTO
Summary: ThinLTO is relying on linkInModule to import selected function. However a lot of "magic" was hidden in linkInModule and the IRMover, who would rename and promote global variables on the fly. This is moving to an approach where the steps are decoupled and the client is reponsible to specify the list of globals to import. As a consequence some test are changed because they were relying on the previous behavior which was importing the definition of *every* single global without control on the client side. Now the burden is on the client to decide if a global has to be imported or not. Reviewers: tejohnson Subscribers: joker.eph, llvm-commits Differential Revision: http://reviews.llvm.org/D18122 From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 263863
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Linker/LinkModules.cpp63
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp6
-rw-r--r--llvm/lib/Transforms/Utils/FunctionImportUtils.cpp36
3 files changed, 33 insertions, 72 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index eee1bb3ebb4..2ee0b9664a3 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -35,19 +35,9 @@ class ModuleLinker {
/// For symbol clashes, prefer those from Src.
unsigned Flags;
- /// Module summary index passed into ModuleLinker for using in function
- /// importing/exporting handling.
- const ModuleSummaryIndex *ImportIndex;
-
/// Functions to import from source module, all other functions are
/// imported as declarations instead of definitions.
- DenseSet<const GlobalValue *> *FunctionsToImport;
-
- /// Set to true if the given ModuleSummaryIndex contains any functions
- /// from this source module, in which case we must conservatively assume
- /// that any of its functions may be imported into another module
- /// as part of a different backend compilation process.
- bool HasExportedFunctions = false;
+ DenseSet<const GlobalValue *> *GlobalsToImport;
/// Association between metadata value id and temporary metadata that
/// remains unmapped after function importing. Saved during function
@@ -116,7 +106,7 @@ class ModuleLinker {
/// Helper method to check if we are importing from the current source
/// module.
- bool isPerformingImport() const { return FunctionsToImport != nullptr; }
+ bool isPerformingImport() const { return GlobalsToImport != nullptr; }
/// If we are importing from the source module, checks if we should
/// import SGV as a definition, otherwise import as a declaration.
@@ -124,21 +114,10 @@ class ModuleLinker {
public:
ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,
- const ModuleSummaryIndex *Index = nullptr,
- DenseSet<const GlobalValue *> *FunctionsToImport = nullptr,
+ DenseSet<const GlobalValue *> *GlobalsToImport = nullptr,
DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr)
- : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), ImportIndex(Index),
- FunctionsToImport(FunctionsToImport),
- ValIDToTempMDMap(ValIDToTempMDMap) {
- assert((ImportIndex || !FunctionsToImport) &&
- "Expect a ModuleSummaryIndex when importing");
- // If we have a ModuleSummaryIndex but no function to import,
- // then this is the primary module being compiled in a ThinLTO
- // backend compilation, and we need to see if it has functions that
- // may be exported to another backend compilation.
- if (ImportIndex && !FunctionsToImport)
- HasExportedFunctions = ImportIndex->hasExportedFunctions(*this->SrcM);
- }
+ : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags),
+ GlobalsToImport(GlobalsToImport), ValIDToTempMDMap(ValIDToTempMDMap) {}
bool run();
};
@@ -147,8 +126,8 @@ public:
bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
if (!isPerformingImport())
return false;
- return FunctionImportGlobalProcessing::doImportAsDefinition(
- SGV, FunctionsToImport);
+ return FunctionImportGlobalProcessing::doImportAsDefinition(SGV,
+ GlobalsToImport);
}
static GlobalValue::VisibilityTypes
@@ -297,7 +276,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
if (isa<Function>(&Src)) {
// For functions, LinkFromSrc iff this is a function requested
// for importing. For variables, decide below normally.
- LinkFromSrc = FunctionsToImport->count(&Src);
+ LinkFromSrc = GlobalsToImport->count(&Src);
return false;
}
@@ -423,12 +402,12 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
if (GV.hasAppendingLinkage() && isPerformingImport())
return false;
- if (isPerformingImport() && !doImportAsDefinition(&GV))
- return false;
-
- if (!DGV && !shouldOverrideFromSrc() &&
- (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
- GV.hasAvailableExternallyLinkage()))
+ if (isPerformingImport()) {
+ if (!doImportAsDefinition(&GV))
+ return false;
+ } else if (!DGV && !shouldOverrideFromSrc() &&
+ (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
+ GV.hasAvailableExternallyLinkage()))
return false;
if (GV.isDeclaration())
@@ -508,15 +487,6 @@ bool ModuleLinker::run() {
if (linkIfNeeded(GA))
return true;
- if (ImportIndex) {
- FunctionImportGlobalProcessing ThinLTOProcessing(*SrcM, *ImportIndex,
- FunctionsToImport);
- if (ThinLTOProcessing.run())
- return true;
- for (auto *GV : ThinLTOProcessing.getNewExportedValues())
- ValuesToLink.insert(GV);
- }
-
for (unsigned I = 0; I < ValuesToLink.size(); ++I) {
GlobalValue *GV = ValuesToLink[I];
const Comdat *SC = GV->getComdat();
@@ -549,10 +519,9 @@ bool ModuleLinker::run() {
Linker::Linker(Module &M) : Mover(M) {}
bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags,
- const ModuleSummaryIndex *Index,
- DenseSet<const GlobalValue *> *FunctionsToImport,
+ DenseSet<const GlobalValue *> *GlobalsToImport,
DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
- ModuleLinker ModLinker(Mover, std::move(Src), Flags, Index, FunctionsToImport,
+ ModuleLinker ModLinker(Mover, std::move(Src), Flags, GlobalsToImport,
ValIDToTempMDMap);
return ModLinker.run();
}
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 5de0577f14e..5a51235f59a 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -266,7 +266,6 @@ GetImportList(Module &DestModule,
if (!F && isa<GlobalAlias>(SGV)) {
auto *SGA = dyn_cast<GlobalAlias>(SGV);
F = dyn_cast<Function>(SGA->getBaseObject());
- CalledFunctionName = F->getName();
}
assert(F && "Imported Function is ... not a Function");
@@ -349,8 +348,11 @@ bool FunctionImporter::importFunctions(Module &DestModule) {
UpgradeDebugInfo(*SrcModule);
// Link in the specified functions.
+ if (renameModuleForThinLTO(*SrcModule, Index, &FunctionsToImport))
+ return true;
+
if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
- &Index, &FunctionsToImport))
+ &FunctionsToImport))
report_fatal_error("Function Import: link error");
ImportedCount += FunctionsToImport.size();
diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
index eceb0850941..c4561cd23ea 100644
--- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
@@ -18,30 +18,20 @@ using namespace llvm;
/// Checks if we should import SGV as a definition, otherwise import as a
/// declaration.
bool FunctionImportGlobalProcessing::doImportAsDefinition(
- const GlobalValue *SGV, DenseSet<const GlobalValue *> *FunctionsToImport) {
- auto *GA = dyn_cast<GlobalAlias>(SGV);
- if (GA) {
+ const GlobalValue *SGV, DenseSet<const GlobalValue *> *GlobalsToImport) {
+
+ // For alias, we tie the definition to the base object. Extract it and recurse
+ if (auto *GA = dyn_cast<GlobalAlias>(SGV)) {
if (GA->hasWeakAnyLinkage())
return false;
const GlobalObject *GO = GA->getBaseObject();
if (!GO->hasLinkOnceODRLinkage())
return false;
return FunctionImportGlobalProcessing::doImportAsDefinition(
- GO, FunctionsToImport);
+ GO, GlobalsToImport);
}
- // Always import GlobalVariable definitions, except for the special
- // case of WeakAny which are imported as ExternalWeak declarations
- // (see comments in FunctionImportGlobalProcessing::getLinkage). The linkage
- // changes described in FunctionImportGlobalProcessing::getLinkage ensure the
- // correct behavior (e.g. global variables with external linkage are
- // transformed to available_externally definitions, which are ultimately
- // turned into declarations after the EliminateAvailableExternally pass).
- if (isa<GlobalVariable>(SGV) && !SGV->isDeclaration() &&
- !SGV->hasWeakAnyLinkage())
- return true;
- // Only import the function requested for importing.
- auto *SF = dyn_cast<Function>(SGV);
- if (SF && FunctionsToImport->count(SF))
+ // Only import the globals requested for importing.
+ if (GlobalsToImport->count(SGV))
return true;
// Otherwise no.
return false;
@@ -51,8 +41,8 @@ bool FunctionImportGlobalProcessing::doImportAsDefinition(
const GlobalValue *SGV) {
if (!isPerformingImport())
return false;
- return FunctionImportGlobalProcessing::doImportAsDefinition(
- SGV, FunctionsToImport);
+ return FunctionImportGlobalProcessing::doImportAsDefinition(SGV,
+ GlobalsToImport);
}
bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
@@ -198,8 +188,6 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
GV.setLinkage(getLinkage(&GV));
if (!GV.hasLocalLinkage())
GV.setVisibility(GlobalValue::HiddenVisibility);
- if (isModuleExporting())
- NewExportedValues.insert(&GV);
} else
GV.setLinkage(getLinkage(&GV));
@@ -231,7 +219,9 @@ bool FunctionImportGlobalProcessing::run() {
return false;
}
-bool llvm::renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index) {
- FunctionImportGlobalProcessing ThinLTOProcessing(M, Index);
+bool llvm::renameModuleForThinLTO(
+ Module &M, const ModuleSummaryIndex &Index,
+ DenseSet<const GlobalValue *> *GlobalsToImport) {
+ FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport);
return ThinLTOProcessing.run();
}
OpenPOWER on IntegriCloud