[llvm] r251841 - Revert "Support for ThinLTO function importing and symbol linking."

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 2 14:24:02 PST 2015


On Mon, Nov 2, 2015 at 2:17 PM, Teresa Johnson via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: tejohnson
> Date: Mon Nov  2 16:17:32 2015
> New Revision: 251841
>
> URL: http://llvm.org/viewvc/llvm-project?rev=251841&view=rev
> Log:
> 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?

Answering my own question: tools/llvm-link/Makefile needs updating...

>
> Removed:
>     llvm/trunk/test/Linker/Inputs/funcimport.ll
>     llvm/trunk/test/Linker/funcimport.ll
> Modified:
>     llvm/trunk/include/llvm/Bitcode/ReaderWriter.h
>     llvm/trunk/include/llvm/IR/FunctionInfo.h
>     llvm/trunk/include/llvm/Linker/Linker.h
>     llvm/trunk/include/llvm/Object/FunctionIndexObjectFile.h
>     llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>     llvm/trunk/lib/Linker/LinkModules.cpp
>     llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp
>     llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp
>     llvm/trunk/tools/llvm-link/CMakeLists.txt
>     llvm/trunk/tools/llvm-link/LLVMBuild.txt
>     llvm/trunk/tools/llvm-link/llvm-link.cpp
>
> Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original)
> +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Nov  2 16:17:32 2015
> @@ -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<std::unique_ptr<FunctionInfoIndex>>
>    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
>
> Modified: llvm/trunk/include/llvm/IR/FunctionInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/FunctionInfo.h?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/FunctionInfo.h (original)
> +++ llvm/trunk/include/llvm/IR/FunctionInfo.h Mon Nov  2 16:17:32 2015
> @@ -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<FunctionInfo> 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
>
> Modified: llvm/trunk/include/llvm/Linker/Linker.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Linker/Linker.h?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Linker/Linker.h (original)
> +++ llvm/trunk/include/llvm/Linker/Linker.h Mon Nov  2 16:17:32 2015
> @@ -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);
>
> Modified: llvm/trunk/include/llvm/Object/FunctionIndexObjectFile.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/FunctionIndexObjectFile.h?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/FunctionIndexObjectFile.h (original)
> +++ llvm/trunk/include/llvm/Object/FunctionIndexObjectFile.h Mon Nov  2 16:17:32 2015
> @@ -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<std::unique_ptr<FunctionIndexObjectFile>>
> -  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
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Nov  2 16:17:32 2015
> @@ -5813,12 +5813,12 @@ llvm::getBitcodeTargetTriple(MemoryBuffe
>  ErrorOr<std::unique_ptr<FunctionInfoIndex>>
>  llvm::getFunctionInfoIndex(MemoryBufferRef Buffer, LLVMContext &Context,
>                             DiagnosticHandlerFunction DiagnosticHandler,
> -                           const Module *ExportingModule, bool IsLazy) {
> +                           bool IsLazy) {
>    std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
>    FunctionIndexBitcodeReader R(Buf.get(), Context, DiagnosticHandler, IsLazy);
>
>    std::unique_ptr<FunctionInfoIndex> Index =
> -      llvm::make_unique<FunctionInfoIndex>(ExportingModule);
> +      llvm::make_unique<FunctionInfoIndex>();
>
>    auto cleanupOnError = [&](std::error_code EC) {
>      R.releaseBuffer(); // Never take ownership on error.
>
> Modified: llvm/trunk/lib/Linker/LinkModules.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Linker/LinkModules.cpp (original)
> +++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Nov  2 16:17:32 2015
> @@ -369,14 +369,12 @@ class ValueMaterializerTy final : public
>    TypeMapTy &TypeMap;
>    Module *DstM;
>    std::vector<GlobalValue *> &LazilyLinkGlobalValues;
> -  ModuleLinker *ModLinker;
>
>  public:
>    ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM,
> -                      std::vector<GlobalValue *> &LazilyLinkGlobalValues,
> -                      ModuleLinker *ModLinker)
> +                      std::vector<GlobalValue *> &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 *G
>
>  /// 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<GlobalAlias>(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<GlobalAlias>(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(GlobalVal
>    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<GlobalVariable>(SGV) && !SGV->isDeclaration())
> -    return true;
> -  // Only import the function requested for importing.
> -  auto *SF = dyn_cast<Function>(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<GlobalVariable>(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(Ty
>
>  /// 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<GlobalVariable>(GVal))
> -      NewGV = copyGlobalVariableProto(TypeMap, GVar);
> -    else {
> -      auto *F = dyn_cast<Function>(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);
> -}
> -
> -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);
> +                             SGA->getLinkage(), SGA->getName(), &DstM);
>  }
>
> -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<GlobalVariable>(SGV))
> -    NewGV = copyGlobalVariableProto(TypeMap, SGVar);
> +    NewGV = copyGlobalVariableProto(TypeMap, DstM, SGVar);
>    else if (auto *SF = dyn_cast<Function>(SGV))
> -    NewGV = copyFunctionProto(TypeMap, SF);
> +    NewGV = copyFunctionProto(TypeMap, DstM, SF);
>    else
> -    NewGV = copyGlobalAliasProto(TypeMap, cast<GlobalAlias>(SGV));
> +    NewGV = copyGlobalAliasProto(TypeMap, DstM, cast<GlobalAlias>(SGV));
>    copyGVAttributes(NewGV, SGV);
> -  setVisibility(NewGV, SGV, DGV);
>    return NewGV;
>  }
>
> @@ -890,7 +608,7 @@ Value *ValueMaterializerTy::materializeV
>    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<GlobalObject>(DGV)) {
> @@ -1024,9 +742,6 @@ bool ModuleLinker::shouldLinkFromSource(
>
>    // 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 SrcIsDeclaration = Src.isDeclarationForLinker();
>    bool DestIsDeclaration = Dest.isDeclarationForLinker();
>
> -  if (isPerformingImport()) {
> -    if (isa<Function>(&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<GlobalAlias>(&Src) && !DestIsDeclaration) {
> -      assert(isa<GlobalAlias>(&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 *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<GlobalVariable>(DGV),
>                                   cast<GlobalVariable>(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(
>            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 *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(
>        return false;
>      }
>
> -    NewGV = copyGlobalValueProto(TypeMap, SGV, DGV);
> +    NewGV = copyGlobalValueProto(TypeMap, *DstM, SGV);
>
>      if (DGV && isa<Function>(DGV))
>        if (auto *NewF = dyn_cast<Function>(NewGV))
> @@ -1421,6 +1108,7 @@ bool ModuleLinker::linkGlobalValueProto(
>    }
>
>    NewGV->setUnnamedAddr(HasUnnamedAddr);
> +  NewGV->setVisibility(Visibility);
>
>    if (auto *NewGO = dyn_cast<GlobalObject>(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;
>
> Modified: llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp (original)
> +++ llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp Mon Nov  2 16:17:32 2015
> @@ -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::hasFunctio
>  // function summary/index.
>  ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
>  FunctionIndexObjectFile::create(MemoryBufferRef Object, LLVMContext &Context,
> -                                const Module *ExportingModule, bool IsLazy) {
> +                                bool IsLazy) {
>    std::unique_ptr<FunctionInfoIndex> Index;
>
>    ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
>    if (!BCOrErr)
>      return BCOrErr.getError();
>
> -  ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex(
> -      BCOrErr.get(), Context, nullptr, ExportingModule, IsLazy);
> +  ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr =
> +      getFunctionInfoIndex(BCOrErr.get(), Context, nullptr, IsLazy);
>
>    if (std::error_code EC = IOrErr.getError())
>      return EC;
>
> Modified: llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp Mon Nov  2 16:17:32 2015
> @@ -49,46 +49,9 @@ ModulePass *llvm::createEliminateAvailab
>    return new EliminateAvailableExternally();
>  }
>
> -static void convertAliasToDeclaration(GlobalAlias &GA, Module &M) {
> -  GlobalValue *GVal = GA.getBaseObject();
> -  GlobalValue *NewGV;
> -  if (auto *GVar = dyn_cast<GlobalVariable>(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<Function>(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::runOn
>      GV.removeDeadConstantUsers();
>      GV.setLinkage(GlobalValue::ExternalLinkage);
>      NumVariables++;
> -    Changed = true;
>    }
>
>    // Drop the bodies of available externally functions.
> @@ -114,7 +76,6 @@ bool EliminateAvailableExternally::runOn
>        F.deleteBody();
>      F.removeDeadConstantUsers();
>      NumFunctions++;
> -    Changed = true;
>    }
>
>    return Changed;
>
> Removed: llvm/trunk/test/Linker/Inputs/funcimport.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/funcimport.ll?rev=251840&view=auto
> ==============================================================================
> --- llvm/trunk/test/Linker/Inputs/funcimport.ll (original)
> +++ llvm/trunk/test/Linker/Inputs/funcimport.ll (removed)
> @@ -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
>
> Removed: llvm/trunk/test/Linker/funcimport.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/funcimport.ll?rev=251840&view=auto
> ==============================================================================
> --- llvm/trunk/test/Linker/funcimport.ll (original)
> +++ llvm/trunk/test/Linker/funcimport.ll (removed)
> @@ -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
> -
> - at globalvar = global i32 1, align 4
> - at staticvar = internal global i32 1, align 4
> - at staticconstvar = internal unnamed_addr constant [2 x i32] [i32 10, i32 20], align 4
> - at commonvar = common global i32 0, align 4
> - at P = internal global void ()* null, align 8
> -
> - at weakalias = weak alias void (...), bitcast (void ()* @globalfunc1 to void (...)*)
> - at 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
> -}
>
> Modified: llvm/trunk/tools/llvm-link/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/CMakeLists.txt?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-link/CMakeLists.txt (original)
> +++ llvm/trunk/tools/llvm-link/CMakeLists.txt Mon Nov  2 16:17:32 2015
> @@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS
>    Core
>    IRReader
>    Linker
> -  Object
>    Support
>    )
>
>
> Modified: llvm/trunk/tools/llvm-link/LLVMBuild.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/LLVMBuild.txt?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-link/LLVMBuild.txt (original)
> +++ llvm/trunk/tools/llvm-link/LLVMBuild.txt Mon Nov  2 16:17:32 2015
> @@ -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
>
> Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=251841&r1=251840&r2=251841&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-link/llvm-link.cpp (original)
> +++ llvm/trunk/tools/llvm-link/llvm-link.cpp Mon Nov  2 16:17:32 2015
> @@ -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<std::string> OverridingI
>      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<std::string> 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<std::string> FunctionIndex("functionindex",
> -                                          cl::desc("Function index filename"),
> -                                          cl::init(""),
> -                                          cl::value_desc("filename"));
> -
>  static cl::opt<std::string>
>  OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
>                 cl::value_desc("filename"));
> @@ -137,90 +118,6 @@ static void diagnosticHandler(const Diag
>    errs() << '\n';
>  }
>
> -/// Load a function index if requested by the -functionindex option.
> -static ErrorOr<std::unique_ptr<FunctionInfoIndex>>
> -loadIndex(LLVMContext &Context, const Module *ExportingModule = nullptr) {
> -  assert(!FunctionIndex.empty());
> -  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
> -      MemoryBuffer::getFileOrSTDIN(FunctionIndex);
> -  std::error_code EC = FileOrErr.getError();
> -  if (EC)
> -    return EC;
> -  MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
> -  ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> 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<Module> 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<FunctionInfoIndex> Index;
> -    if (!FunctionIndex.empty()) {
> -      ErrorOr<std::unique_ptr<FunctionInfoIndex>> 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<std::string> &Files,
>                        unsigned Flags) {
> @@ -238,24 +135,10 @@ static bool linkFiles(const char *argv0,
>        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<FunctionInfoIndex> Index;
> -    if (!FunctionIndex.empty()) {
> -      ErrorOr<std::unique_ptr<FunctionInfoIndex>> 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;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



-- 
Teresa Johnson | Software Engineer | tejohnson at google.com | 408-460-2413


More information about the llvm-commits mailing list