forked from OSchip/llvm-project
FunctionImport: Use IRMover directly.
The importer was previously using ModuleLinker in a sort of "IRMover mode". Use IRMover directly instead in order to remove a level of indirection. I will remove all importing support from ModuleLinker in a separate change. Differential Revision: https://reviews.llvm.org/D29468 llvm-svn: 294014
This commit is contained in:
parent
cce2d8028f
commit
6d8f817f8b
|
@ -32,7 +32,7 @@ class FunctionImportGlobalProcessing {
|
||||||
|
|
||||||
/// Globals to import from this module, all other functions will be
|
/// Globals to import from this module, all other functions will be
|
||||||
/// imported as declarations instead of definitions.
|
/// imported as declarations instead of definitions.
|
||||||
DenseSet<const GlobalValue *> *GlobalsToImport;
|
SetVector<GlobalValue *> *GlobalsToImport;
|
||||||
|
|
||||||
/// Set to true if the given ModuleSummaryIndex contains any functions
|
/// Set to true if the given ModuleSummaryIndex contains any functions
|
||||||
/// from this source module, in which case we must conservatively assume
|
/// from this source module, in which case we must conservatively assume
|
||||||
|
@ -85,7 +85,7 @@ class FunctionImportGlobalProcessing {
|
||||||
public:
|
public:
|
||||||
FunctionImportGlobalProcessing(
|
FunctionImportGlobalProcessing(
|
||||||
Module &M, const ModuleSummaryIndex &Index,
|
Module &M, const ModuleSummaryIndex &Index,
|
||||||
DenseSet<const GlobalValue *> *GlobalsToImport = nullptr)
|
SetVector<GlobalValue *> *GlobalsToImport = nullptr)
|
||||||
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) {
|
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) {
|
||||||
// If we have a ModuleSummaryIndex but no function to import,
|
// If we have a ModuleSummaryIndex but no function to import,
|
||||||
// then this is the primary module being compiled in a ThinLTO
|
// then this is the primary module being compiled in a ThinLTO
|
||||||
|
@ -104,16 +104,15 @@ public:
|
||||||
|
|
||||||
bool run();
|
bool run();
|
||||||
|
|
||||||
static bool
|
static bool doImportAsDefinition(const GlobalValue *SGV,
|
||||||
doImportAsDefinition(const GlobalValue *SGV,
|
SetVector<GlobalValue *> *GlobalsToImport);
|
||||||
DenseSet<const GlobalValue *> *GlobalsToImport);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Perform in-place global value handling on the given Module for
|
/// Perform in-place global value handling on the given Module for
|
||||||
/// exported local functions renamed and promoted for ThinLTO.
|
/// exported local functions renamed and promoted for ThinLTO.
|
||||||
bool renameModuleForThinLTO(
|
bool renameModuleForThinLTO(
|
||||||
Module &M, const ModuleSummaryIndex &Index,
|
Module &M, const ModuleSummaryIndex &Index,
|
||||||
DenseSet<const GlobalValue *> *GlobalsToImport = nullptr);
|
SetVector<GlobalValue *> *GlobalsToImport = nullptr);
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
|
|
@ -129,8 +129,7 @@ public:
|
||||||
bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
|
bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
|
||||||
if (!isPerformingImport())
|
if (!isPerformingImport())
|
||||||
return false;
|
return false;
|
||||||
return FunctionImportGlobalProcessing::doImportAsDefinition(SGV,
|
report_fatal_error("ModuleLinker does not support importing");
|
||||||
GlobalsToImport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GlobalValue::VisibilityTypes
|
static GlobalValue::VisibilityTypes
|
||||||
|
|
|
@ -658,8 +658,7 @@ Expected<bool> FunctionImporter::importFunctions(
|
||||||
<< DestModule.getModuleIdentifier() << "\n");
|
<< DestModule.getModuleIdentifier() << "\n");
|
||||||
unsigned ImportedCount = 0;
|
unsigned ImportedCount = 0;
|
||||||
|
|
||||||
// Linker that will be used for importing function
|
IRMover Mover(DestModule);
|
||||||
Linker TheLinker(DestModule);
|
|
||||||
// Do the actual import of functions now, one Module at a time
|
// Do the actual import of functions now, one Module at a time
|
||||||
std::set<StringRef> ModuleNameOrderedList;
|
std::set<StringRef> ModuleNameOrderedList;
|
||||||
for (auto &FunctionsToImportPerModule : ImportList) {
|
for (auto &FunctionsToImportPerModule : ImportList) {
|
||||||
|
@ -683,7 +682,7 @@ Expected<bool> FunctionImporter::importFunctions(
|
||||||
|
|
||||||
auto &ImportGUIDs = FunctionsToImportPerModule->second;
|
auto &ImportGUIDs = FunctionsToImportPerModule->second;
|
||||||
// Find the globals to import
|
// Find the globals to import
|
||||||
DenseSet<const GlobalValue *> GlobalsToImport;
|
SetVector<GlobalValue *> GlobalsToImport;
|
||||||
for (Function &F : *SrcModule) {
|
for (Function &F : *SrcModule) {
|
||||||
if (!F.hasName())
|
if (!F.hasName())
|
||||||
continue;
|
continue;
|
||||||
|
@ -722,6 +721,13 @@ Expected<bool> FunctionImporter::importFunctions(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (GlobalAlias &GA : SrcModule->aliases()) {
|
for (GlobalAlias &GA : SrcModule->aliases()) {
|
||||||
|
// FIXME: This should eventually be controlled entirely by the summary.
|
||||||
|
if (FunctionImportGlobalProcessing::doImportAsDefinition(
|
||||||
|
&GA, &GlobalsToImport)) {
|
||||||
|
GlobalsToImport.insert(&GA);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GA.hasName())
|
if (!GA.hasName())
|
||||||
continue;
|
continue;
|
||||||
auto GUID = GA.getGUID();
|
auto GUID = GA.getGUID();
|
||||||
|
@ -766,10 +772,9 @@ Expected<bool> FunctionImporter::importFunctions(
|
||||||
<< " from " << SrcModule->getSourceFileName() << "\n";
|
<< " from " << SrcModule->getSourceFileName() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instruct the linker that the client will take care of linkonce resolution
|
if (Mover.move(std::move(SrcModule), GlobalsToImport.getArrayRef(),
|
||||||
unsigned Flags = Linker::Flags::DontForceLinkLinkonceODR;
|
[](GlobalValue &, IRMover::ValueAdder) {},
|
||||||
|
/*LinkModuleInlineAsm=*/false, /*IsPerformingImport=*/true))
|
||||||
if (TheLinker.linkInModule(std::move(SrcModule), Flags, &GlobalsToImport))
|
|
||||||
report_fatal_error("Function Import: link error");
|
report_fatal_error("Function Import: link error");
|
||||||
|
|
||||||
ImportedCount += GlobalsToImport.size();
|
ImportedCount += GlobalsToImport.size();
|
||||||
|
|
|
@ -21,11 +21,11 @@ using namespace llvm;
|
||||||
/// Checks if we should import SGV as a definition, otherwise import as a
|
/// Checks if we should import SGV as a definition, otherwise import as a
|
||||||
/// declaration.
|
/// declaration.
|
||||||
bool FunctionImportGlobalProcessing::doImportAsDefinition(
|
bool FunctionImportGlobalProcessing::doImportAsDefinition(
|
||||||
const GlobalValue *SGV, DenseSet<const GlobalValue *> *GlobalsToImport) {
|
const GlobalValue *SGV, SetVector<GlobalValue *> *GlobalsToImport) {
|
||||||
|
|
||||||
// For alias, we tie the definition to the base object. Extract it and recurse
|
// For alias, we tie the definition to the base object. Extract it and recurse
|
||||||
if (auto *GA = dyn_cast<GlobalAlias>(SGV)) {
|
if (auto *GA = dyn_cast<GlobalAlias>(SGV)) {
|
||||||
if (GA->hasWeakAnyLinkage())
|
if (GA->isInterposable())
|
||||||
return false;
|
return false;
|
||||||
const GlobalObject *GO = GA->getBaseObject();
|
const GlobalObject *GO = GA->getBaseObject();
|
||||||
if (!GO->hasLinkOnceODRLinkage())
|
if (!GO->hasLinkOnceODRLinkage())
|
||||||
|
@ -34,7 +34,7 @@ bool FunctionImportGlobalProcessing::doImportAsDefinition(
|
||||||
GO, GlobalsToImport);
|
GO, GlobalsToImport);
|
||||||
}
|
}
|
||||||
// Only import the globals requested for importing.
|
// Only import the globals requested for importing.
|
||||||
if (GlobalsToImport->count(SGV))
|
if (GlobalsToImport->count(const_cast<GlobalValue *>(SGV)))
|
||||||
return true;
|
return true;
|
||||||
// Otherwise no.
|
// Otherwise no.
|
||||||
return false;
|
return false;
|
||||||
|
@ -57,7 +57,8 @@ bool FunctionImportGlobalProcessing::shouldPromoteLocalToGlobal(
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isPerformingImport()) {
|
if (isPerformingImport()) {
|
||||||
assert((!GlobalsToImport->count(SGV) || !isNonRenamableLocal(*SGV)) &&
|
assert((!GlobalsToImport->count(const_cast<GlobalValue *>(SGV)) ||
|
||||||
|
!isNonRenamableLocal(*SGV)) &&
|
||||||
"Attempting to promote non-renamable local");
|
"Attempting to promote non-renamable local");
|
||||||
// We don't know for sure yet if we are importing this value (as either
|
// We don't know for sure yet if we are importing this value (as either
|
||||||
// a reference or a def), since we are simply walking all values in the
|
// a reference or a def), since we are simply walking all values in the
|
||||||
|
@ -254,9 +255,8 @@ bool FunctionImportGlobalProcessing::run() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::renameModuleForThinLTO(
|
bool llvm::renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index,
|
||||||
Module &M, const ModuleSummaryIndex &Index,
|
SetVector<GlobalValue *> *GlobalsToImport) {
|
||||||
DenseSet<const GlobalValue *> *GlobalsToImport) {
|
|
||||||
FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport);
|
FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport);
|
||||||
return ThinLTOProcessing.run();
|
return ThinLTOProcessing.run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue