From: Teresa Johnson Date: Mon, 2 Nov 2015 22:17:32 +0000 (+0000) Subject: Revert "Support for ThinLTO function importing and symbol linking." X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3d95431a332d216e7fe7bdc0f0024072121d5d04;p=oota-llvm.git Revert "Support for ThinLTO function importing and symbol linking." This reverts commit r251837, due to a number of bot failures of the form: /home/grosser/buildslave/perf-x86_64-penryn-O3-polly-fast/llvm.obj/tools/llvm-link/Release+Asserts/llvm-link.o:llvm-link.cpp:function loadIndex(llvm::LLVMContext&, llvm::Module const*): error: undefined reference to 'llvm::object::FunctionIndexObjectFile::create(llvm::MemoryBufferRef, llvm::LLVMContext&, llvm::Module const*, bool)' /home/grosser/buildslave/perf-x86_64-penryn-O3-polly-fast/llvm.obj/tools/llvm-link/Release+Asserts/llvm-link.o:llvm-link.cpp:function loadIndex(llvm::LLVMContext&, llvm::Module const*): error: undefined reference to 'llvm::object::FunctionIndexObjectFile::takeIndex()' I'm not sure why these are happening - I added Object to the requred libraries in tools/llvm-link/LLVMBuild.txt and the LLVM_LINK_COMPONENTS in tools/llvm-link/CMakeLists.txt. Confirmed for my build that these symbols come out of libLLVMObject.a. What am I missing? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251841 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 5f1c7200468..3308084fbd8 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -64,8 +64,6 @@ namespace llvm { DiagnosticHandlerFunction DiagnosticHandler); /// Parse the specified bitcode buffer, returning the function info index. - /// If ExportingModule is true, check for functions in the index from this - /// module when the combined index is built during parsing and set flag. /// If IsLazy is true, parse the entire function summary into /// the index. Otherwise skip the function summary section, and only create /// an index object with a map from function name to function summary offset. @@ -73,7 +71,6 @@ namespace llvm { ErrorOr> getFunctionInfoIndex(MemoryBufferRef Buffer, LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler, - const Module *ExportingModule = nullptr, bool IsLazy = false); /// This method supports lazy reading of function summary data from the diff --git a/include/llvm/IR/FunctionInfo.h b/include/llvm/IR/FunctionInfo.h index e265ad37096..264954757cf 100644 --- a/include/llvm/IR/FunctionInfo.h +++ b/include/llvm/IR/FunctionInfo.h @@ -165,18 +165,8 @@ private: /// Holds strings for combined index, mapping to the corresponding module ID. ModulePathStringTableTy ModulePathStringTable; - /// The main module being compiled, that we are importing into, if applicable. - /// Used to check if any of its functions are in the index and therefore - /// potentially exported. - const Module *ExportingModule; - - /// Flag indicating whether the exporting module has any functions in the - /// index and therefore potentially exported (imported into another module). - bool HasExportedFunctions; - public: - FunctionInfoIndex(const Module *M = nullptr) - : ExportingModule(M), HasExportedFunctions(false){}; + FunctionInfoIndex() = default; ~FunctionInfoIndex() = default; // Disable the copy constructor and assignment operators, so @@ -196,12 +186,6 @@ public: /// Add a function info for a function of the given name. void addFunctionInfo(StringRef FuncName, std::unique_ptr Info) { - if (ExportingModule) { - assert(Info->functionSummary()); - if (ExportingModule->getModuleIdentifier() == - Info->functionSummary()->modulePath()) - HasExportedFunctions = true; - } FunctionMap[FuncName].push_back(std::move(Info)); } @@ -239,14 +223,6 @@ public: return ModulePathStringTable.insert(std::make_pair(ModPath, ModId)) .first->first(); } - - /// Check if the given Module has any functions available for exporting - /// in the index. - bool hasExportedFunctions(const Module *M) { - assert(M == ExportingModule && - "Checking for exported functions on unexpected module"); - return HasExportedFunctions; - } }; } // End llvm namespace diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h index 679e60582e8..3a6df80aa38 100644 --- a/include/llvm/Linker/Linker.h +++ b/include/llvm/Linker/Linker.h @@ -14,7 +14,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/IR/DiagnosticInfo.h" -#include "llvm/IR/FunctionInfo.h" namespace llvm { class Module; @@ -77,13 +76,8 @@ public: /// \brief Link \p Src into the composite. The source is destroyed. /// Passing OverrideSymbols as true will have symbols from Src /// shadow those in the Dest. - /// For ThinLTO function importing/exporting the \p FunctionInfoIndex - /// is passed. If a \p FuncToImport is provided, only that single - /// function is imported from the source module. /// Returns true on error. - bool linkInModule(Module *Src, unsigned Flags = Flags::None, - FunctionInfoIndex *Index = nullptr, - Function *FuncToImport = nullptr); + bool linkInModule(Module *Src, unsigned Flags = Flags::None); /// \brief Set the composite to the passed-in module. void setModule(Module *Dst); diff --git a/include/llvm/Object/FunctionIndexObjectFile.h b/include/llvm/Object/FunctionIndexObjectFile.h index 12057447f5c..08eff540c94 100644 --- a/include/llvm/Object/FunctionIndexObjectFile.h +++ b/include/llvm/Object/FunctionIndexObjectFile.h @@ -18,7 +18,6 @@ namespace llvm { class FunctionInfoIndex; -class Module; namespace object { class ObjectFile; @@ -85,8 +84,7 @@ public: /// Return new FunctionIndexObjectFile instance containing parsed function /// summary/index. static ErrorOr> - create(MemoryBufferRef Object, LLVMContext &Context, - const Module *ExportingModule = nullptr, bool IsLazy = false); + create(MemoryBufferRef Object, LLVMContext &Context, bool IsLazy = false); /// \brief Parse the function summary information for function with the /// given name out of the given buffer. Parsed information is diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 4b8b554b252..1a63e08f667 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5813,12 +5813,12 @@ llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context, ErrorOr> llvm::getFunctionInfoIndex(MemoryBufferRef Buffer, LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler, - const Module *ExportingModule, bool IsLazy) { + bool IsLazy) { std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); FunctionIndexBitcodeReader R(Buf.get(), Context, DiagnosticHandler, IsLazy); std::unique_ptr Index = - llvm::make_unique(ExportingModule); + llvm::make_unique(); auto cleanupOnError = [&](std::error_code EC) { R.releaseBuffer(); // Never take ownership on error. diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index b7aab9e9644..94b12aae1f0 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -369,14 +369,12 @@ class ValueMaterializerTy final : public ValueMaterializer { TypeMapTy &TypeMap; Module *DstM; std::vector &LazilyLinkGlobalValues; - ModuleLinker *ModLinker; public: ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM, - std::vector &LazilyLinkGlobalValues, - ModuleLinker *ModLinker) + std::vector &LazilyLinkGlobalValues) : ValueMaterializer(), TypeMap(TypeMap), DstM(DstM), - LazilyLinkGlobalValues(LazilyLinkGlobalValues), ModLinker(ModLinker) {} + LazilyLinkGlobalValues(LazilyLinkGlobalValues) {} Value *materializeValueFor(Value *V) override; }; @@ -429,38 +427,12 @@ class ModuleLinker { /// For symbol clashes, prefer those from Src. unsigned Flags; - /// Function index passed into ModuleLinker for using in function - /// importing/exporting handling. - FunctionInfoIndex *ImportIndex; - - /// Function to import from source module, all other functions are - /// imported as declarations instead of definitions. - Function *ImportFunction; - - /// Set to true if the given FunctionInfoIndex 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; - public: ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM, - DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags, - FunctionInfoIndex *Index = nullptr, - Function *FuncToImport = nullptr) + DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags) : DstM(dstM), SrcM(srcM), TypeMap(Set), - ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues, this), - DiagnosticHandler(DiagnosticHandler), Flags(Flags), ImportIndex(Index), - ImportFunction(FuncToImport), HasExportedFunctions(false) { - assert((ImportIndex || !ImportFunction) && - "Expect a FunctionInfoIndex when importing"); - // If we have a FunctionInfoIndex 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 && !ImportFunction) - HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM); - } + ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues), + DiagnosticHandler(DiagnosticHandler), Flags(Flags) {} bool run(); @@ -470,14 +442,6 @@ public: return Flags & Linker::InternalizeLinkedSymbols; } - /// Handles cloning of a global values from the source module into - /// the destination module, including setting the attributes and visibility. - GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, const GlobalValue *SGV, - const GlobalValue *DGV = nullptr); - - /// Check if we should promote the given local value to global scope. - bool doPromoteLocalToGlobal(const GlobalValue *SGV); - private: bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src); @@ -544,42 +508,6 @@ private: void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src); bool linkGlobalValueBody(GlobalValue &Src); - /// Functions that take care of cloning a specific global value type - /// into the destination module. - GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap, - const GlobalVariable *SGVar); - Function *copyFunctionProto(TypeMapTy &TypeMap, const Function *SF); - GlobalValue *copyGlobalAliasProto(TypeMapTy &TypeMap, const GlobalAlias *SGA); - - /// Helper methods to check if we are importing from or potentially - /// exporting from the current source module. - bool isPerformingImport() { return ImportFunction != nullptr; } - bool isModuleExporting() { return HasExportedFunctions; } - - /// If we are importing from the source module, checks if we should - /// import SGV as a definition, otherwise import as a declaration. - bool doImportAsDefinition(const GlobalValue *SGV); - - /// Get the name for SGV that should be used in the linked destination - /// module. Specifically, this handles the case where we need to rename - /// a local that is being promoted to global scope. - std::string getName(const GlobalValue *SGV); - - /// Get the new linkage for SGV that should be used in the linked destination - /// module. Specifically, for ThinLTO importing or exporting it may need - /// to be adjusted. - GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV); - - /// Copies the necessary global value attributes and name from the source - /// to the newly cloned global value. - void copyGVAttributes(GlobalValue *NewGV, const GlobalValue *SrcGV); - - /// Updates the visibility for the new global cloned from the source - /// and, if applicable, linked with an existing destination global. - /// Handles visibility change required for promoted locals. - void setVisibility(GlobalValue *NewGV, const GlobalValue *SGV, - const GlobalValue *DGV = nullptr); - void linkNamedMDNodes(); void stripReplacedSubprograms(); }; @@ -591,9 +519,6 @@ private: static void forceRenaming(GlobalValue *GV, StringRef Name) { // If the global doesn't force its name or if it already has the right name, // there is nothing for us to do. - // Note that any required local to global promotion should already be done, - // so promoted locals will not skip this handling as their linkage is no - // longer local. if (GV->hasLocalLinkage() || GV->getName() == Name) return; @@ -611,23 +536,9 @@ static void forceRenaming(GlobalValue *GV, StringRef Name) { /// copy additional attributes (those not needed to construct a GlobalValue) /// from the SrcGV to the DestGV. -void ModuleLinker::copyGVAttributes(GlobalValue *NewGV, - const GlobalValue *SrcGV) { - auto *GA = dyn_cast(SrcGV); - // Check for the special case of converting an alias (definition) to a - // non-alias (declaration). This can happen when we are importing and - // encounter a weak_any alias (weak_any defs may not be imported, see - // comments in ModuleLinker::getLinkage) or an alias whose base object is - // being imported as a declaration. In that case copy the attributes from the - // base object. - if (GA && !dyn_cast(NewGV)) { - assert(isPerformingImport() && - (GA->hasWeakAnyLinkage() || - !doImportAsDefinition(GA->getBaseObject()))); - NewGV->copyAttributesFrom(GA->getBaseObject()); - } else - NewGV->copyAttributesFrom(SrcGV); - forceRenaming(NewGV, getName(SrcGV)); +static void copyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) { + DestGV->copyAttributesFrom(SrcGV); + forceRenaming(DestGV, SrcGV->getName()); } static bool isLessConstraining(GlobalValue::VisibilityTypes a, @@ -643,169 +554,17 @@ static bool isLessConstraining(GlobalValue::VisibilityTypes a, return false; } -bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) { - if (!isPerformingImport()) - return false; - // Always import GlobalVariable definitions. The linkage changes - // described in ModuleLinker::getLinkage ensure the correct behavior (e.g. - // global variables with external linkage are transformed to - // available_externally defintions, which are ultimately turned into - // declaratios after the EliminateAvailableExternally pass). - if (dyn_cast(SGV) && !SGV->isDeclaration()) - return true; - // Only import the function requested for importing. - auto *SF = dyn_cast(SGV); - if (SF && SF == ImportFunction) - return true; - // Otherwise no. - return false; -} - -bool ModuleLinker::doPromoteLocalToGlobal(const GlobalValue *SGV) { - assert(SGV->hasLocalLinkage()); - // Both the imported references and the original local variable must - // be promoted. - if (!isPerformingImport() && !isModuleExporting()) - return false; - - // Local const variables never need to be promoted unless they are address - // taken. The imported uses can simply use the clone created in this module. - // For now we are conservative in determining which variables are not - // address taken by checking the unnamed addr flag. To be more aggressive, - // the address taken information must be checked earlier during parsing - // of the module and recorded in the function index for use when importing - // from that module. - auto *GVar = dyn_cast(SGV); - if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr()) - return false; - - // Eventually we only need to promote functions in the exporting module that - // are referenced by a potentially exported function (i.e. one that is in the - // function index). - return true; -} - -std::string ModuleLinker::getName(const GlobalValue *SGV) { - // For locals that must be promoted to global scope, ensure that - // the promoted name uniquely identifies the copy in the original module, - // using the ID assigned during combined index creation. When importing, - // we rename all locals (not just those that are promoted) in order to - // avoid naming conflicts between locals imported from different modules. - if (SGV->hasLocalLinkage() && - (doPromoteLocalToGlobal(SGV) || isPerformingImport())) - return FunctionInfoIndex::getGlobalNameForLocal( - SGV->getName(), - ImportIndex->getModuleId(SGV->getParent()->getModuleIdentifier())); - return SGV->getName(); -} - -GlobalValue::LinkageTypes ModuleLinker::getLinkage(const GlobalValue *SGV) { - // Any local variable that is referenced by an exported function needs - // to be promoted to global scope. Since we don't currently know which - // functions reference which local variables/functions, we must treat - // all as potentially exported if this module is exporting anything. - if (isModuleExporting()) { - if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV)) - return GlobalValue::ExternalLinkage; - return SGV->getLinkage(); - } - - // Otherwise, if we aren't importing, no linkage change is needed. - if (!isPerformingImport()) - return SGV->getLinkage(); - - switch (SGV->getLinkage()) { - case GlobalValue::ExternalLinkage: - // External defnitions are converted to available_externally - // definitions upon import, so that they are available for inlining - // and/or optimization, but are turned into declarations later - // during the EliminateAvailableExternally pass. - if (doImportAsDefinition(SGV)) - return GlobalValue::AvailableExternallyLinkage; - // An imported external declaration stays external. - return SGV->getLinkage(); - - case GlobalValue::AvailableExternallyLinkage: - // An imported available_externally definition converts - // to external if imported as a declaration. - if (!doImportAsDefinition(SGV)) - return GlobalValue::ExternalLinkage; - // An imported available_externally declaration stays that way. - return SGV->getLinkage(); - - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - // These both stay the same when importing the definition. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - - case GlobalValue::WeakAnyLinkage: - // Can't import weak_any definitions correctly, or we might change the - // program semantics, since the linker will pick the first weak_any - // definition and importing would change the order they are seen by the - // linker. The module linking caller needs to enforce this. - assert(!doImportAsDefinition(SGV)); - // If imported as a declaration, it becomes external_weak. - return GlobalValue::ExternalWeakLinkage; - - case GlobalValue::WeakODRLinkage: - // For weak_odr linkage, there is a guarantee that all copies will be - // equivalent, so the issue described above for weak_any does not exist, - // and the definition can be imported. It can be treated similarly - // to an imported externally visible global value. - if (doImportAsDefinition(SGV)) - return GlobalValue::AvailableExternallyLinkage; - else - return GlobalValue::ExternalLinkage; - - case GlobalValue::AppendingLinkage: - // It would be incorrect to import an appending linkage variable, - // since it would cause global constructors/destructors to be - // executed multiple times. This should have already been handled - // by linkGlobalValueProto. - assert(false && "Cannot import appending linkage variable"); - - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - // If we are promoting the local to global scope, it is handled - // similarly to a normal externally visible global. - if (doPromoteLocalToGlobal(SGV)) { - if (doImportAsDefinition(SGV)) - return GlobalValue::AvailableExternallyLinkage; - else - return GlobalValue::ExternalLinkage; - } - // A non-promoted imported local definition stays local. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - - case GlobalValue::ExternalWeakLinkage: - // External weak doesn't apply to definitions, must be a declaration. - assert(!doImportAsDefinition(SGV)); - // Linkage stays external_weak. - return SGV->getLinkage(); - - case GlobalValue::CommonLinkage: - // Linkage stays common on definitions. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - } - - llvm_unreachable("unknown linkage type"); -} - /// Loop through the global variables in the src module and merge them into the /// dest module. -GlobalVariable * -ModuleLinker::copyGlobalVariableProto(TypeMapTy &TypeMap, - const GlobalVariable *SGVar) { +static GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap, Module &DstM, + const GlobalVariable *SGVar) { // No linking to be performed or linking from the source: simply create an // identical version of the symbol over in the dest module... the // initializer will be filled in later by LinkGlobalInits. GlobalVariable *NewDGV = new GlobalVariable( - *DstM, TypeMap.get(SGVar->getType()->getElementType()), - SGVar->isConstant(), getLinkage(SGVar), /*init*/ nullptr, getName(SGVar), - /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), + DstM, TypeMap.get(SGVar->getType()->getElementType()), + SGVar->isConstant(), SGVar->getLinkage(), /*init*/ nullptr, + SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), SGVar->getType()->getAddressSpace()); return NewDGV; @@ -813,75 +572,34 @@ ModuleLinker::copyGlobalVariableProto(TypeMapTy &TypeMap, /// Link the function in the source module into the destination module if /// needed, setting up mapping information. -Function *ModuleLinker::copyFunctionProto(TypeMapTy &TypeMap, - const Function *SF) { +static Function *copyFunctionProto(TypeMapTy &TypeMap, Module &DstM, + const Function *SF) { // If there is no linkage to be performed or we are linking from the source, // bring SF over. - return Function::Create(TypeMap.get(SF->getFunctionType()), getLinkage(SF), - getName(SF), DstM); + return Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(), + SF->getName(), &DstM); } /// Set up prototypes for any aliases that come over from the source module. -GlobalValue *ModuleLinker::copyGlobalAliasProto(TypeMapTy &TypeMap, - const GlobalAlias *SGA) { - // If we are importing and encounter a weak_any alias, or an alias to - // an object being imported as a declaration, we must import the alias - // as a declaration as well, which involves converting it to a non-alias. - // See comments in ModuleLinker::getLinkage for why we cannot import - // weak_any defintions. - if (isPerformingImport() && (SGA->hasWeakAnyLinkage() || - !doImportAsDefinition(SGA->getBaseObject()))) { - // Need to convert to declaration. All aliases must be definitions. - const GlobalValue *GVal = SGA->getBaseObject(); - GlobalValue *NewGV; - if (auto *GVar = dyn_cast(GVal)) - NewGV = copyGlobalVariableProto(TypeMap, GVar); - else { - auto *F = dyn_cast(GVal); - assert(F); - NewGV = copyFunctionProto(TypeMap, F); - } - // Set the linkage to ExternalWeak, see also comments in - // ModuleLinker::getLinkage. - if (SGA->hasWeakAnyLinkage()) - NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); - // Don't attempt to link body, needs to be a declaration. - DoNotLinkFromSource.insert(SGA); - return NewGV; - } +static GlobalAlias *copyGlobalAliasProto(TypeMapTy &TypeMap, Module &DstM, + const GlobalAlias *SGA) { // If there is no linkage to be performed or we're linking from the source, // bring over SGA. auto *Ty = TypeMap.get(SGA->getValueType()); return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(), - getLinkage(SGA), getName(SGA), DstM); + SGA->getLinkage(), SGA->getName(), &DstM); } -void ModuleLinker::setVisibility(GlobalValue *NewGV, const GlobalValue *SGV, - const GlobalValue *DGV) { - GlobalValue::VisibilityTypes Visibility = SGV->getVisibility(); - if (DGV) - Visibility = isLessConstraining(Visibility, DGV->getVisibility()) - ? DGV->getVisibility() - : Visibility; - // For promoted locals, mark them hidden so that they can later be - // stripped from the symbol table to reduce bloat. - if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV)) - Visibility = GlobalValue::HiddenVisibility; - NewGV->setVisibility(Visibility); -} - -GlobalValue *ModuleLinker::copyGlobalValueProto(TypeMapTy &TypeMap, - const GlobalValue *SGV, - const GlobalValue *DGV) { +static GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, Module &DstM, + const GlobalValue *SGV) { GlobalValue *NewGV; if (auto *SGVar = dyn_cast(SGV)) - NewGV = copyGlobalVariableProto(TypeMap, SGVar); + NewGV = copyGlobalVariableProto(TypeMap, DstM, SGVar); else if (auto *SF = dyn_cast(SGV)) - NewGV = copyFunctionProto(TypeMap, SF); + NewGV = copyFunctionProto(TypeMap, DstM, SF); else - NewGV = copyGlobalAliasProto(TypeMap, cast(SGV)); + NewGV = copyGlobalAliasProto(TypeMap, DstM, cast(SGV)); copyGVAttributes(NewGV, SGV); - setVisibility(NewGV, SGV, DGV); return NewGV; } @@ -890,7 +608,7 @@ Value *ValueMaterializerTy::materializeValueFor(Value *V) { if (!SGV) return nullptr; - GlobalValue *DGV = ModLinker->copyGlobalValueProto(TypeMap, SGV); + GlobalValue *DGV = copyGlobalValueProto(TypeMap, *DstM, SGV); if (Comdat *SC = SGV->getComdat()) { if (auto *DGO = dyn_cast(DGV)) { @@ -1024,9 +742,6 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { - // Caller should have already determined that we can't link from source - // when importing (see comments in linkGlobalValueProto). - assert(!isPerformingImport()); LinkFromSrc = true; return false; } @@ -1034,28 +749,6 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); - if (isPerformingImport()) { - if (isa(&Src)) { - // For functions, LinkFromSrc iff this is the function requested - // for importing. For variables, decide below normally. - LinkFromSrc = (&Src == ImportFunction); - return false; - } - - // Check if this is an alias with an already existing definition - // in Dest, which must have come from a prior importing pass from - // the same Src module. Unlike imported function and variable - // definitions, which are imported as available_externally and are - // not definitions for the linker, that is not a valid linkage for - // imported aliases which must be definitions. Simply use the existing - // Dest copy. - if (isa(&Src) && !DestIsDeclaration) { - assert(isa(&Dest)); - LinkFromSrc = false; - return false; - } - } - if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. @@ -1347,21 +1040,13 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { GlobalValue *DGV = getLinkedToGlobal(SGV); // Handle the ultra special appending linkage case first. - assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); - if (SGV->hasAppendingLinkage() && isPerformingImport()) { - // Don't want to append to global_ctors list, for example, when we - // are importing for ThinLTO, otherwise the global ctors and dtors - // get executed multiple times for local variables (the latter causing - // double frees). - DoNotLinkFromSource.insert(SGV); - return false; - } if (DGV && DGV->hasAppendingLinkage()) return linkAppendingVarProto(cast(DGV), cast(SGV)); bool LinkFromSrc = true; Comdat *C = nullptr; + GlobalValue::VisibilityTypes Visibility = SGV->getVisibility(); bool HasUnnamedAddr = SGV->hasUnnamedAddr(); if (const Comdat *SC = SGV->getComdat()) { @@ -1385,8 +1070,12 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType())); } - if (DGV) + if (DGV) { + Visibility = isLessConstraining(Visibility, DGV->getVisibility()) + ? DGV->getVisibility() + : Visibility; HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); + } if (!LinkFromSrc && !DGV) return false; @@ -1394,12 +1083,10 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { GlobalValue *NewGV; if (!LinkFromSrc) { NewGV = DGV; - // When linking from source we setVisibility from copyGlobalValueProto. - setVisibility(NewGV, SGV, DGV); } else { // If the GV is to be lazily linked, don't create it just yet. // The ValueMaterializerTy will deal with creating it if it's used. - if (!DGV && !shouldOverrideFromSrc() && SGV != ImportFunction && + if (!DGV && !shouldOverrideFromSrc() && (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() || SGV->hasAvailableExternallyLinkage())) { DoNotLinkFromSource.insert(SGV); @@ -1413,7 +1100,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { return false; } - NewGV = copyGlobalValueProto(TypeMap, SGV, DGV); + NewGV = copyGlobalValueProto(TypeMap, *DstM, SGV); if (DGV && isa(DGV)) if (auto *NewF = dyn_cast(NewGV)) @@ -1421,6 +1108,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { } NewGV->setUnnamedAddr(HasUnnamedAddr); + NewGV->setVisibility(Visibility); if (auto *NewGO = dyn_cast(NewGV)) { if (C) @@ -1925,10 +1613,6 @@ bool ModuleLinker::run() { if (DoNotLinkFromSource.count(&SF)) continue; - // When importing, only materialize the function requested for import. - if (isPerformingImport() && &SF != ImportFunction) - continue; - if (linkGlobalValueBody(SF)) return true; } @@ -1962,8 +1646,6 @@ bool ModuleLinker::run() { while (!LazilyLinkGlobalValues.empty()) { GlobalValue *SGV = LazilyLinkGlobalValues.back(); LazilyLinkGlobalValues.pop_back(); - if (isPerformingImport() && !doImportAsDefinition(SGV)) - continue; // Skip declarations that ValueMaterializer may have created in // case we link in only some of SrcM. @@ -2097,10 +1779,9 @@ void Linker::deleteModule() { Composite = nullptr; } -bool Linker::linkInModule(Module *Src, unsigned Flags, FunctionInfoIndex *Index, - Function *FuncToImport) { +bool Linker::linkInModule(Module *Src, unsigned Flags) { ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, - DiagnosticHandler, Flags, Index, FuncToImport); + DiagnosticHandler, Flags); bool RetCode = TheLinker.run(); Composite->dropTriviallyDeadConstantArrays(); return RetCode; diff --git a/lib/Object/FunctionIndexObjectFile.cpp b/lib/Object/FunctionIndexObjectFile.cpp index ee65990c528..b1e8ebc657c 100644 --- a/lib/Object/FunctionIndexObjectFile.cpp +++ b/lib/Object/FunctionIndexObjectFile.cpp @@ -1,4 +1,5 @@ -//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===// +//===- FunctionIndexObjectFile.cpp - Function index file implementation +//----===// // // The LLVM Compiler Infrastructure // @@ -85,15 +86,15 @@ bool FunctionIndexObjectFile::hasFunctionSummaryInMemBuffer( // function summary/index. ErrorOr> FunctionIndexObjectFile::create(MemoryBufferRef Object, LLVMContext &Context, - const Module *ExportingModule, bool IsLazy) { + bool IsLazy) { std::unique_ptr Index; ErrorOr BCOrErr = findBitcodeInMemBuffer(Object); if (!BCOrErr) return BCOrErr.getError(); - ErrorOr> IOrErr = getFunctionInfoIndex( - BCOrErr.get(), Context, nullptr, ExportingModule, IsLazy); + ErrorOr> IOrErr = + getFunctionInfoIndex(BCOrErr.get(), Context, nullptr, IsLazy); if (std::error_code EC = IOrErr.getError()) return EC; diff --git a/lib/Transforms/IPO/ElimAvailExtern.cpp b/lib/Transforms/IPO/ElimAvailExtern.cpp index 0e138cbbc7a..e13c00a92e4 100644 --- a/lib/Transforms/IPO/ElimAvailExtern.cpp +++ b/lib/Transforms/IPO/ElimAvailExtern.cpp @@ -49,46 +49,9 @@ ModulePass *llvm::createEliminateAvailableExternallyPass() { return new EliminateAvailableExternally(); } -static void convertAliasToDeclaration(GlobalAlias &GA, Module &M) { - GlobalValue *GVal = GA.getBaseObject(); - GlobalValue *NewGV; - if (auto *GVar = dyn_cast(GVal)) { - GlobalVariable *NewGVar = new GlobalVariable( - M, GVar->getType()->getElementType(), GVar->isConstant(), - GVar->getLinkage(), /*init*/ nullptr, GA.getName(), GVar, - GVar->getThreadLocalMode(), GVar->getType()->getAddressSpace()); - NewGV = NewGVar; - NewGV->copyAttributesFrom(GVar); - } else { - auto *F = dyn_cast(GVal); - assert(F); - Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), - GA.getName(), &M); - NewGV = NewF; - NewGV->copyAttributesFrom(F); - } - GA.replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, GA.getType())); - GA.eraseFromParent(); -} - bool EliminateAvailableExternally::runOnModule(Module &M) { bool Changed = false; - // Convert any aliases that alias with an available externally - // value (which will be turned into declarations later on in this routine) - // into declarations themselves. All aliases must be definitions, and - // must alias with a definition. So this involves creating a declaration - // equivalent to the alias's base object. - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;) { - // Increment the iterator first since we may delete the current alias. - GlobalAlias &GA = *(I++); - GlobalValue *GVal = GA.getBaseObject(); - if (!GVal->hasAvailableExternallyLinkage()) - continue; - convertAliasToDeclaration(GA, M); - Changed = true; - } - // Drop initializers of available externally global variables. for (GlobalVariable &GV : M.globals()) { if (!GV.hasAvailableExternallyLinkage()) @@ -102,7 +65,6 @@ bool EliminateAvailableExternally::runOnModule(Module &M) { GV.removeDeadConstantUsers(); GV.setLinkage(GlobalValue::ExternalLinkage); NumVariables++; - Changed = true; } // Drop the bodies of available externally functions. @@ -114,7 +76,6 @@ bool EliminateAvailableExternally::runOnModule(Module &M) { F.deleteBody(); F.removeDeadConstantUsers(); NumFunctions++; - Changed = true; } return Changed; diff --git a/test/Linker/Inputs/funcimport.ll b/test/Linker/Inputs/funcimport.ll deleted file mode 100644 index 25cfcfc2a65..00000000000 --- a/test/Linker/Inputs/funcimport.ll +++ /dev/null @@ -1,28 +0,0 @@ -define i32 @main() #0 { -entry: - call void (...) @weakalias() - call void (...) @analias() - %call = call i32 (...) @referencestatics() - %call1 = call i32 (...) @referenceglobals() - %call2 = call i32 (...) @referencecommon() - call void (...) @setfuncptr() - call void (...) @callfuncptr() - call void (...) @callweakfunc() - ret i32 0 -} - -declare void @weakalias(...) #1 - -declare void @analias(...) #1 - -declare i32 @referencestatics(...) #1 - -declare i32 @referenceglobals(...) #1 - -declare i32 @referencecommon(...) #1 - -declare void @setfuncptr(...) #1 - -declare void @callfuncptr(...) #1 - -declare void @callweakfunc(...) #1 diff --git a/test/Linker/funcimport.ll b/test/Linker/funcimport.ll deleted file mode 100644 index 1b9a08694d8..00000000000 --- a/test/Linker/funcimport.ll +++ /dev/null @@ -1,169 +0,0 @@ -; Do setup work for all below tests: generate bitcode and combined index -; RUN: llvm-as -function-summary %s -o %t.bc -; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc -; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc - -; Ensure statics are promoted/renamed correctly from this file (all but -; constant variable need promotion). -; RUN: llvm-link %t.bc -functionindex=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC -; EXPORTSTATIC: @staticvar.llvm.1 = hidden global -; EXPORTSTATIC: @staticconstvar = internal unnamed_addr constant -; EXPORTSTATIC: @P.llvm.1 = hidden global void ()* null -; EXPORTSTATIC: define hidden i32 @staticfunc.llvm.1 -; EXPORTSTATIC: define hidden void @staticfunc2.llvm.1 - -; Ensure that both weak alias to an imported function and strong alias to a -; non-imported function are correctly turned into declarations. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1 -; IMPORTGLOB1: define available_externally void @globalfunc1 -; IMPORTGLOB1: declare void @globalfunc2 -; IMPORTGLOB1: declare extern_weak void @weakalias -; IMPORTGLOB1: declare void @analias - -; Ensure that weak alias to a non-imported function is correctly -; turned into a declaration, but that strong alias to an imported function -; is imported as alias. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2 -; IMPORTGLOB2: @analias = alias void (...), bitcast (void ()* @globalfunc2 -; IMPORTGLOB2: declare void @globalfunc1 -; IMPORTGLOB2: define available_externally void @globalfunc2 -; IMPORTGLOB2: declare extern_weak void @weakalias - -; Ensure that strong alias imported in second pass of importing ends up -; as an alias. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB3 -; IMPORTGLOB3: @analias = alias void (...), bitcast (void ()* @globalfunc2 -; IMPORTGLOB3: define available_externally void @globalfunc1 -; IMPORTGLOB3: define available_externally void @globalfunc2 -; IMPORTGLOB3: declare extern_weak void @weakalias - -; Ensure that strong alias imported in first pass of importing ends up -; as an alias, and that seeing the alias definition during a second inlining -; pass is handled correctly. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB4 -; IMPORTGLOB4: @analias = alias void (...), bitcast (void ()* @globalfunc2 -; IMPORTGLOB4: define available_externally void @globalfunc2 -; IMPORTGLOB4: define available_externally void @globalfunc1 -; IMPORTGLOB4: declare extern_weak void @weakalias - -; Ensure that imported static variable and function references are correctly -; promoted and renamed (including static constant variable). -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC -; IMPORTSTATIC: @staticvar.llvm.1 = available_externally hidden global -; IMPORTSTATIC: @staticconstvar.llvm.1 = internal unnamed_addr constant -; IMPORTSTATIC: define available_externally i32 @referencestatics -; IMPORTSTATIC: %call = call i32 @staticfunc.llvm.1 -; IMPORTSTATIC: %0 = load i32, i32* @staticvar.llvm.1 -; IMPORTSTATIC: declare hidden i32 @staticfunc.llvm.1 - -; Ensure that imported global (external) function and variable references -; are handled correctly (including referenced variable imported as -; available_externally definition) -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referenceglobals:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOBALS -; IMPORTGLOBALS: @globalvar = available_externally global -; IMPORTGLOBALS: declare void @globalfunc1() -; IMPORTGLOBALS: define available_externally i32 @referenceglobals - -; Ensure that common variable correctly imported as common defition. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencecommon:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMMON -; IMPORTCOMMON: @commonvar = common global -; IMPORTCOMMON: define available_externally i32 @referencecommon - -; Ensure that imported static function pointer correctly promoted and renamed. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR -; IMPORTFUNCPTR: @P.llvm.1 = available_externally hidden global void ()* null -; IMPORTFUNCPTR: define available_externally void @callfuncptr -; IMPORTFUNCPTR: %0 = load void ()*, void ()** @P.llvm.1 - -; Ensure that imported weak function reference/definition handled properly. -; Imported weak_any definition should be skipped with warning, and imported -; reference should turned into an external_weak declaration. -; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC -; IMPORTWEAKFUNC: Ignoring import request for weak-any function weakfunc -; IMPORTWEAKFUNC: declare extern_weak void @weakfunc -; IMPORTWEAKFUNC: define available_externally void @callweakfunc - -@globalvar = global i32 1, align 4 -@staticvar = internal global i32 1, align 4 -@staticconstvar = internal unnamed_addr constant [2 x i32] [i32 10, i32 20], align 4 -@commonvar = common global i32 0, align 4 -@P = internal global void ()* null, align 8 - -@weakalias = weak alias void (...), bitcast (void ()* @globalfunc1 to void (...)*) -@analias = alias void (...), bitcast (void ()* @globalfunc2 to void (...)*) - -define void @globalfunc1() #0 { -entry: - ret void -} - -define void @globalfunc2() #0 { -entry: - ret void -} - -define i32 @referencestatics(i32 %i) #0 { -entry: - %i.addr = alloca i32, align 4 - store i32 %i, i32* %i.addr, align 4 - %call = call i32 @staticfunc() - %0 = load i32, i32* @staticvar, align 4 - %add = add nsw i32 %call, %0 - %1 = load i32, i32* %i.addr, align 4 - %idxprom = sext i32 %1 to i64 - %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* @staticconstvar, i64 0, i64 %idxprom - %2 = load i32, i32* %arrayidx, align 4 - %add1 = add nsw i32 %add, %2 - ret i32 %add1 -} - -define i32 @referenceglobals(i32 %i) #0 { -entry: - %i.addr = alloca i32, align 4 - store i32 %i, i32* %i.addr, align 4 - call void @globalfunc1() - %0 = load i32, i32* @globalvar, align 4 - ret i32 %0 -} - -define i32 @referencecommon(i32 %i) #0 { -entry: - %i.addr = alloca i32, align 4 - store i32 %i, i32* %i.addr, align 4 - %0 = load i32, i32* @commonvar, align 4 - ret i32 %0 -} - -define void @setfuncptr() #0 { -entry: - store void ()* @staticfunc2, void ()** @P, align 8 - ret void -} - -define void @callfuncptr() #0 { -entry: - %0 = load void ()*, void ()** @P, align 8 - call void %0() - ret void -} - -define weak void @weakfunc() #0 { -entry: - ret void -} - -define void @callweakfunc() #0 { -entry: - call void @weakfunc() - ret void -} - -define internal i32 @staticfunc() #0 { -entry: - ret i32 1 -} - -define internal void @staticfunc2() #0 { -entry: - ret void -} diff --git a/tools/llvm-link/CMakeLists.txt b/tools/llvm-link/CMakeLists.txt index e4ced186336..d4f5be74904 100644 --- a/tools/llvm-link/CMakeLists.txt +++ b/tools/llvm-link/CMakeLists.txt @@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS Core IRReader Linker - Object Support ) diff --git a/tools/llvm-link/LLVMBuild.txt b/tools/llvm-link/LLVMBuild.txt index 807823820ed..2e386f3c231 100644 --- a/tools/llvm-link/LLVMBuild.txt +++ b/tools/llvm-link/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-link parent = Tools -required_libraries = AsmParser BitReader BitWriter IRReader Linker Object +required_libraries = AsmParser BitReader BitWriter IRReader Linker diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 718d57a343f..7f294f3e719 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -18,12 +18,10 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" -#include "llvm/IR/FunctionInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/Object/FunctionIndexObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -45,23 +43,6 @@ static cl::list OverridingInputs( cl::desc( "input bitcode file which can override previously defined symbol(s)")); -// Option to simulate function importing for testing. This enables using -// llvm-link to simulate ThinLTO backend processes. -static cl::list Imports( - "import", cl::ZeroOrMore, cl::value_desc("function:filename"), - cl::desc("Pair of function name and filename, where function should be " - "imported from bitcode in filename")); - -// Option to support testing of function importing. The function index -// must be specified in the case were we request imports via the -import -// option, as well as when compiling any module with functions that may be -// exported (imported by a different llvm-link -import invocation), to ensure -// consistent promotion and renaming of locals. -static cl::opt FunctionIndex("functionindex", - cl::desc("Function index filename"), - cl::init(""), - cl::value_desc("filename")); - static cl::opt OutputFilename("o", cl::desc("Override output filename"), cl::init("-"), cl::value_desc("filename")); @@ -137,90 +118,6 @@ static void diagnosticHandler(const DiagnosticInfo &DI) { errs() << '\n'; } -/// Load a function index if requested by the -functionindex option. -static ErrorOr> -loadIndex(LLVMContext &Context, const Module *ExportingModule = nullptr) { - assert(!FunctionIndex.empty()); - ErrorOr> FileOrErr = - MemoryBuffer::getFileOrSTDIN(FunctionIndex); - std::error_code EC = FileOrErr.getError(); - if (EC) - return EC; - MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef(); - ErrorOr> ObjOrErr = - object::FunctionIndexObjectFile::create(BufferRef, Context, - ExportingModule); - EC = ObjOrErr.getError(); - if (EC) - return EC; - - object::FunctionIndexObjectFile &Obj = **ObjOrErr; - return Obj.takeIndex(); -} - -/// Import any functions requested via the -import option. -static bool importFunctions(const char *argv0, LLVMContext &Context, - Linker &L) { - for (const auto &Import : Imports) { - // Identify the requested function and its bitcode source file. - size_t Idx = Import.find(':'); - if (Idx == std::string::npos) { - errs() << "Import parameter bad format: " << Import << "\n"; - return false; - } - std::string FunctionName = Import.substr(0, Idx); - std::string FileName = Import.substr(Idx + 1, std::string::npos); - - // Load the specified source module. - std::unique_ptr M = loadFile(argv0, FileName, Context); - if (!M.get()) { - errs() << argv0 << ": error loading file '" << FileName << "'\n"; - return false; - } - - if (verifyModule(*M, &errs())) { - errs() << argv0 << ": " << FileName - << ": error: input module is broken!\n"; - return false; - } - - Function *F = M->getFunction(FunctionName); - if (!F) { - errs() << "Ignoring import request for non-existent function " - << FunctionName << " from " << FileName << "\n"; - continue; - } - // We cannot import weak_any functions without possibly affecting the - // order they are seen and selected by the linker, changing program - // semantics. - if (F->hasWeakAnyLinkage()) { - errs() << "Ignoring import request for weak-any function " << FunctionName - << " from " << FileName << "\n"; - continue; - } - - if (Verbose) - errs() << "Importing " << FunctionName << " from " << FileName << "\n"; - - std::unique_ptr Index; - if (!FunctionIndex.empty()) { - ErrorOr> IndexOrErr = - loadIndex(Context); - std::error_code EC = IndexOrErr.getError(); - if (EC) { - errs() << EC.message() << '\n'; - return false; - } - Index = std::move(IndexOrErr.get()); - } - - // Link in the specified function. - if (L.linkInModule(M.get(), false, Index.get(), F)) - return false; - } - return true; -} - static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list &Files, unsigned Flags) { @@ -238,24 +135,10 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, return false; } - // If a function index is supplied, load it so linkInModule can treat - // local functions/variables as exported and promote if necessary. - std::unique_ptr Index; - if (!FunctionIndex.empty()) { - ErrorOr> IndexOrErr = - loadIndex(Context, &*M); - std::error_code EC = IndexOrErr.getError(); - if (EC) { - errs() << EC.message() << '\n'; - return false; - } - Index = std::move(IndexOrErr.get()); - } - if (Verbose) errs() << "Linking in '" << File << "'\n"; - if (L.linkInModule(M.get(), ApplicableFlags, Index.get())) + if (L.linkInModule(M.get(), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; @@ -291,10 +174,6 @@ int main(int argc, char **argv) { Flags | Linker::Flags::OverrideFromSrc)) return 1; - // Import any functions requested via -import - if (!importFunctions(argv[0], Context, L)) - return 1; - if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite; std::error_code EC;