Index: llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h +++ llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h @@ -32,7 +32,7 @@ /// Globals to import from this module, all other functions will be /// imported as declarations instead of definitions. - DenseSet *GlobalsToImport; + SetVector *GlobalsToImport; /// Set to true if the given ModuleSummaryIndex contains any functions /// from this source module, in which case we must conservatively assume @@ -85,7 +85,7 @@ public: FunctionImportGlobalProcessing( Module &M, const ModuleSummaryIndex &Index, - DenseSet *GlobalsToImport = nullptr) + SetVector *GlobalsToImport = nullptr) : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) { // If we have a ModuleSummaryIndex but no function to import, // then this is the primary module being compiled in a ThinLTO @@ -104,16 +104,15 @@ bool run(); - static bool - doImportAsDefinition(const GlobalValue *SGV, - DenseSet *GlobalsToImport); + static bool doImportAsDefinition(const GlobalValue *SGV, + SetVector *GlobalsToImport); }; /// Perform in-place global value handling on the given Module for /// exported local functions renamed and promoted for ThinLTO. bool renameModuleForThinLTO( Module &M, const ModuleSummaryIndex &Index, - DenseSet *GlobalsToImport = nullptr); + SetVector *GlobalsToImport = nullptr); } // End llvm namespace Index: llvm/trunk/lib/Linker/LinkModules.cpp =================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp +++ llvm/trunk/lib/Linker/LinkModules.cpp @@ -129,8 +129,7 @@ bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) { if (!isPerformingImport()) return false; - return FunctionImportGlobalProcessing::doImportAsDefinition(SGV, - GlobalsToImport); + report_fatal_error("ModuleLinker does not support importing"); } static GlobalValue::VisibilityTypes Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -658,8 +658,7 @@ << DestModule.getModuleIdentifier() << "\n"); unsigned ImportedCount = 0; - // Linker that will be used for importing function - Linker TheLinker(DestModule); + IRMover Mover(DestModule); // Do the actual import of functions now, one Module at a time std::set ModuleNameOrderedList; for (auto &FunctionsToImportPerModule : ImportList) { @@ -683,7 +682,7 @@ auto &ImportGUIDs = FunctionsToImportPerModule->second; // Find the globals to import - DenseSet GlobalsToImport; + SetVector GlobalsToImport; for (Function &F : *SrcModule) { if (!F.hasName()) continue; @@ -722,6 +721,13 @@ } } 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()) continue; auto GUID = GA.getGUID(); @@ -766,10 +772,9 @@ << " from " << SrcModule->getSourceFileName() << "\n"; } - // Instruct the linker that the client will take care of linkonce resolution - unsigned Flags = Linker::Flags::DontForceLinkLinkonceODR; - - if (TheLinker.linkInModule(std::move(SrcModule), Flags, &GlobalsToImport)) + if (Mover.move(std::move(SrcModule), GlobalsToImport.getArrayRef(), + [](GlobalValue &, IRMover::ValueAdder) {}, + /*LinkModuleInlineAsm=*/false, /*IsPerformingImport=*/true)) report_fatal_error("Function Import: link error"); ImportedCount += GlobalsToImport.size(); Index: llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -21,11 +21,11 @@ /// Checks if we should import SGV as a definition, otherwise import as a /// declaration. bool FunctionImportGlobalProcessing::doImportAsDefinition( - const GlobalValue *SGV, DenseSet *GlobalsToImport) { + const GlobalValue *SGV, SetVector *GlobalsToImport) { // For alias, we tie the definition to the base object. Extract it and recurse if (auto *GA = dyn_cast(SGV)) { - if (GA->hasWeakAnyLinkage()) + if (GA->isInterposable()) return false; const GlobalObject *GO = GA->getBaseObject(); if (!GO->hasLinkOnceODRLinkage()) @@ -34,7 +34,7 @@ GO, GlobalsToImport); } // Only import the globals requested for importing. - if (GlobalsToImport->count(SGV)) + if (GlobalsToImport->count(const_cast(SGV))) return true; // Otherwise no. return false; @@ -57,7 +57,8 @@ return false; if (isPerformingImport()) { - assert((!GlobalsToImport->count(SGV) || !isNonRenamableLocal(*SGV)) && + assert((!GlobalsToImport->count(const_cast(SGV)) || + !isNonRenamableLocal(*SGV)) && "Attempting to promote non-renamable local"); // 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 @@ -254,9 +255,8 @@ return false; } -bool llvm::renameModuleForThinLTO( - Module &M, const ModuleSummaryIndex &Index, - DenseSet *GlobalsToImport) { +bool llvm::renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, + SetVector *GlobalsToImport) { FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport); return ThinLTOProcessing.run(); }