diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:41:23 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:41:23 +0000 | 
| commit | 4a16efa3e43e35f0cc9efe3a67f620f0017c3d36 (patch) | |
| tree | 06099edc18d30894081a822b756f117cbe0b8207 /lib/Linker | |
| parent | 482e7bddf617ae804dc47133cb07eb4aa81e45de (diff) | |
Diffstat (limited to 'lib/Linker')
| -rw-r--r-- | lib/Linker/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | lib/Linker/LLVMBuild.txt | 2 | ||||
| -rw-r--r-- | lib/Linker/LinkArchives.cpp | 197 | ||||
| -rw-r--r-- | lib/Linker/LinkItems.cpp | 241 | ||||
| -rw-r--r-- | lib/Linker/LinkModules.cpp | 303 | ||||
| -rw-r--r-- | lib/Linker/Linker.cpp | 113 | 
6 files changed, 138 insertions, 720 deletions
diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 0b6d2f4218e3..28f1262a4398 100644 --- a/lib/Linker/CMakeLists.txt +++ b/lib/Linker/CMakeLists.txt @@ -1,6 +1,4 @@  add_llvm_library(LLVMLinker -  LinkArchives.cpp -  LinkItems.cpp    LinkModules.cpp    Linker.cpp    ) diff --git a/lib/Linker/LLVMBuild.txt b/lib/Linker/LLVMBuild.txt index 2b4c232b8067..0bb26d0c2aea 100644 --- a/lib/Linker/LLVMBuild.txt +++ b/lib/Linker/LLVMBuild.txt @@ -19,4 +19,4 @@  type = Library  name = Linker  parent = Libraries -required_libraries = Archive BitReader Core Support TransformUtils +required_libraries = Core Support TransformUtils diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp deleted file mode 100644 index c16d1958cdfb..000000000000 --- a/lib/Linker/LinkArchives.cpp +++ /dev/null @@ -1,197 +0,0 @@ -//===- lib/Linker/LinkArchives.cpp - Link LLVM objects and libraries ------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains routines to handle linking together LLVM bitcode files, -// and to handle annoying things like static libraries. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Linker.h" -#include "llvm/Module.h" -#include "llvm/ADT/SetOperations.h" -#include "llvm/Bitcode/Archive.h" -#include <memory> -#include <set> -using namespace llvm; - -/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still -/// exist in an LLVM module. This is a bit tricky because there may be two -/// symbols with the same name but different LLVM types that will be resolved to -/// each other but aren't currently (thus we need to treat it as resolved). -/// -/// Inputs: -///  M - The module in which to find undefined symbols. -/// -/// Outputs: -///  UndefinedSymbols - A set of C++ strings containing the name of all -///                     undefined symbols. -/// -static void -GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) { -  std::set<std::string> DefinedSymbols; -  UndefinedSymbols.clear(); - -  // If the program doesn't define a main, try pulling one in from a .a file. -  // This is needed for programs where the main function is defined in an -  // archive, such f2c'd programs. -  Function *Main = M->getFunction("main"); -  if (Main == 0 || Main->isDeclaration()) -    UndefinedSymbols.insert("main"); - -  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) -    if (I->hasName()) { -      if (I->isDeclaration()) -        UndefinedSymbols.insert(I->getName()); -      else if (!I->hasLocalLinkage()) { -        assert(!I->hasDLLImportLinkage() -               && "Found dllimported non-external symbol!"); -        DefinedSymbols.insert(I->getName()); -      }       -    } - -  for (Module::global_iterator I = M->global_begin(), E = M->global_end(); -       I != E; ++I) -    if (I->hasName()) { -      if (I->isDeclaration()) -        UndefinedSymbols.insert(I->getName()); -      else if (!I->hasLocalLinkage()) { -        assert(!I->hasDLLImportLinkage() -               && "Found dllimported non-external symbol!"); -        DefinedSymbols.insert(I->getName()); -      }       -    } - -  for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); -       I != E; ++I) -    if (I->hasName()) -      DefinedSymbols.insert(I->getName()); - -  // Prune out any defined symbols from the undefined symbols set... -  for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); -       I != UndefinedSymbols.end(); ) -    if (DefinedSymbols.count(*I)) -      UndefinedSymbols.erase(I++);  // This symbol really is defined! -    else -      ++I; // Keep this symbol in the undefined symbols list -} - -/// LinkInArchive - opens an archive library and link in all objects which -/// provide symbols that are currently undefined. -/// -/// Inputs: -///  Filename - The pathname of the archive. -/// -/// Return Value: -///  TRUE  - An error occurred. -///  FALSE - No errors. -bool -Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) { -  // Make sure this is an archive file we're dealing with -  if (!Filename.isArchive()) -    return error("File '" + Filename.str() + "' is not an archive."); - -  // Open the archive file -  verbose("Linking archive file '" + Filename.str() + "'"); - -  // Find all of the symbols currently undefined in the bitcode program. -  // If all the symbols are defined, the program is complete, and there is -  // no reason to link in any archive files. -  std::set<std::string> UndefinedSymbols; -  GetAllUndefinedSymbols(Composite, UndefinedSymbols); - -  if (UndefinedSymbols.empty()) { -    verbose("No symbols undefined, skipping library '" + Filename.str() + "'"); -    return false;  // No need to link anything in! -  } - -  std::string ErrMsg; -  std::auto_ptr<Archive> AutoArch ( -    Archive::OpenAndLoadSymbols(Filename, Context, &ErrMsg)); - -  Archive* arch = AutoArch.get(); - -  if (!arch) -    return error("Cannot read archive '" + Filename.str() + -                 "': " + ErrMsg); -  if (!arch->isBitcodeArchive()) { -    is_native = true; -    return false; -  } -  is_native = false; - -  // Save a set of symbols that are not defined by the archive. Since we're -  // entering a loop, there's no point searching for these multiple times. This -  // variable is used to "set_subtract" from the set of undefined symbols. -  std::set<std::string> NotDefinedByArchive; - -  // Save the current set of undefined symbols, because we may have to make -  // multiple passes over the archive: -  std::set<std::string> CurrentlyUndefinedSymbols; - -  do { -    CurrentlyUndefinedSymbols = UndefinedSymbols; - -    // Find the modules we need to link into the target module.  Note that arch -    // keeps ownership of these modules and may return the same Module* from a -    // subsequent call. -    SmallVector<Module*, 16> Modules; -    if (!arch->findModulesDefiningSymbols(UndefinedSymbols, Modules, &ErrMsg)) -      return error("Cannot find symbols in '" + Filename.str() +  -                   "': " + ErrMsg); - -    // If we didn't find any more modules to link this time, we are done -    // searching this archive. -    if (Modules.empty()) -      break; - -    // Any symbols remaining in UndefinedSymbols after -    // findModulesDefiningSymbols are ones that the archive does not define. So -    // we add them to the NotDefinedByArchive variable now. -    NotDefinedByArchive.insert(UndefinedSymbols.begin(), -        UndefinedSymbols.end()); - -    // Loop over all the Modules that we got back from the archive -    for (SmallVectorImpl<Module*>::iterator I=Modules.begin(), E=Modules.end(); -         I != E; ++I) { - -      // Get the module we must link in. -      std::string moduleErrorMsg; -      Module* aModule = *I; -      if (aModule != NULL) { -        if (aModule->MaterializeAll(&moduleErrorMsg)) -          return error("Could not load a module: " + moduleErrorMsg); - -        verbose("  Linking in module: " + aModule->getModuleIdentifier()); - -        // Link it in -        if (LinkInModule(aModule, &moduleErrorMsg)) -          return error("Cannot link in module '" + -                       aModule->getModuleIdentifier() + "': " + moduleErrorMsg); -      }  -    } -     -    // Get the undefined symbols from the aggregate module. This recomputes the -    // symbols we still need after the new modules have been linked in. -    GetAllUndefinedSymbols(Composite, UndefinedSymbols); - -    // At this point we have two sets of undefined symbols: UndefinedSymbols -    // which holds the undefined symbols from all the modules, and -    // NotDefinedByArchive which holds symbols we know the archive doesn't -    // define. There's no point searching for symbols that we won't find in the -    // archive so we subtract these sets. -    set_subtract(UndefinedSymbols, NotDefinedByArchive); - -    // If there's no symbols left, no point in continuing to search the -    // archive. -    if (UndefinedSymbols.empty()) -      break; -  } while (CurrentlyUndefinedSymbols != UndefinedSymbols); - -  return false; -} diff --git a/lib/Linker/LinkItems.cpp b/lib/Linker/LinkItems.cpp deleted file mode 100644 index 52a0d175a5cd..000000000000 --- a/lib/Linker/LinkItems.cpp +++ /dev/null @@ -1,241 +0,0 @@ -//===- lib/Linker/LinkItems.cpp - Link LLVM objects and libraries ---------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains routines to handle linking together LLVM bitcode files, -// and to handle annoying things like static libraries. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Linker.h" -#include "llvm/Module.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/system_error.h" -using namespace llvm; - -// LinkItems - This function is the main entry point into linking. It takes a -// list of LinkItem which indicates the order the files should be linked and -// how each file should be treated (plain file or with library search). The -// function only links bitcode and produces a result list of items that are -// native objects.  -bool -Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) { -  // Clear the NativeItems just in case -  NativeItems.clear(); - -  // For each linkage item ... -  for (ItemList::const_iterator I = Items.begin(), E = Items.end(); -       I != E; ++I) { -    if (I->second) { -      // Link in the library suggested. -      bool is_native = false; -      if (LinkInLibrary(I->first, is_native)) -        return true; -      if (is_native) -        NativeItems.push_back(*I); -    } else { -      // Link in the file suggested -      bool is_native = false; -      if (LinkInFile(sys::Path(I->first), is_native)) -        return true; -      if (is_native) -        NativeItems.push_back(*I); -    } -  } - -  // At this point we have processed all the link items provided to us. Since -  // we have an aggregated module at this point, the dependent libraries in -  // that module should also be aggregated with duplicates eliminated. This is -  // now the time to process the dependent libraries to resolve any remaining -  // symbols. -  bool is_native; -  for (Module::lib_iterator I = Composite->lib_begin(), -         E = Composite->lib_end(); I != E; ++I) { -    if(LinkInLibrary(*I, is_native)) -      return true; -    if (is_native) -      NativeItems.push_back(std::make_pair(*I, true)); -  } - -  return false; -} - - -/// LinkInLibrary - links one library into the HeadModule. -/// -bool Linker::LinkInLibrary(StringRef Lib, bool& is_native) { -  is_native = false; -  // Determine where this library lives. -  sys::Path Pathname = FindLib(Lib); -  if (Pathname.isEmpty()) -    return error("Cannot find library '" + Lib.str() + "'"); - -  // If its an archive, try to link it in -  std::string Magic; -  Pathname.getMagicNumber(Magic, 64); -  switch (sys::IdentifyFileType(Magic.c_str(), 64)) { -    default: llvm_unreachable("Bad file type identification"); -    case sys::Unknown_FileType: -      return warning("Supposed library '" + Lib.str() + "' isn't a library."); - -    case sys::Bitcode_FileType: -      // LLVM ".so" file. -      if (LinkInFile(Pathname, is_native)) -        return true; -      break; - -    case sys::Archive_FileType: -      if (LinkInArchive(Pathname, is_native)) -        return error("Cannot link archive '" + Pathname.str() + "'"); -      break; - -    case sys::ELF_Relocatable_FileType: -    case sys::ELF_SharedObject_FileType: -    case sys::Mach_O_Object_FileType: -    case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: -    case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: -    case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: -    case sys::COFF_FileType: -      is_native = true; -      break; -  } -  return false; -} - -/// LinkLibraries - takes the specified library files and links them into the -/// main bitcode object file. -/// -/// Inputs: -///  Libraries  - The list of libraries to link into the module. -/// -/// Return value: -///  FALSE - No error. -///  TRUE  - Error. -/// -bool Linker::LinkInLibraries(const std::vector<std::string> &Libraries) { - -  // Process the set of libraries we've been provided. -  bool is_native = false; -  for (unsigned i = 0; i < Libraries.size(); ++i) -    if (LinkInLibrary(Libraries[i], is_native)) -      return true; - -  // At this point we have processed all the libraries provided to us. Since -  // we have an aggregated module at this point, the dependent libraries in -  // that module should also be aggregated with duplicates eliminated. This is -  // now the time to process the dependent libraries to resolve any remaining -  // symbols. -  const Module::LibraryListType& DepLibs = Composite->getLibraries(); -  for (Module::LibraryListType::const_iterator I = DepLibs.begin(), -         E = DepLibs.end(); I != E; ++I) -    if (LinkInLibrary(*I, is_native)) -      return true; - -  return false; -} - -/// LinkInFile - opens a bitcode file and links in all objects which -/// provide symbols that are currently undefined. -/// -/// Inputs: -///  File - The pathname of the bitcode file. -/// -/// Outputs: -///  ErrorMessage - A C++ string detailing what error occurred, if any. -/// -/// Return Value: -///  TRUE  - An error occurred. -///  FALSE - No errors. -/// -bool Linker::LinkInFile(const sys::Path &File, bool &is_native) { -  is_native = false; -   -  // Check for a file of name "-", which means "read standard input" -  if (File.str() == "-") { -    std::auto_ptr<Module> M; -    OwningPtr<MemoryBuffer> Buffer; -    error_code ec; -    if (!(ec = MemoryBuffer::getSTDIN(Buffer))) { -      if (!Buffer->getBufferSize()) { -        Error = "standard input is empty"; -      } else { -        M.reset(ParseBitcodeFile(Buffer.get(), Context, &Error)); -        if (M.get()) -          if (!LinkInModule(M.get(), &Error)) -            return false; -      } -    } -    return error("Cannot link stdin: " + ec.message()); -  } - -  // Determine what variety of file it is. -  std::string Magic; -  if (!File.getMagicNumber(Magic, 64)) -    return error("Cannot find linker input '" + File.str() + "'"); - -  switch (sys::IdentifyFileType(Magic.c_str(), 64)) { -    default: llvm_unreachable("Bad file type identification"); -    case sys::Unknown_FileType: -      return warning("Ignoring file '" + File.str() +  -                   "' because does not contain bitcode."); - -    case sys::Archive_FileType: -      // A user may specify an ar archive without -l, perhaps because it -      // is not installed as a library. Detect that and link the archive. -      if (LinkInArchive(File, is_native)) -        return true; -      break; - -    case sys::Bitcode_FileType: { -      verbose("Linking bitcode file '" + File.str() + "'"); -      std::auto_ptr<Module> M(LoadObject(File)); -      if (M.get() == 0) -        return error("Cannot load file '" + File.str() + "': " + Error); -      if (LinkInModule(M.get(), &Error)) -        return error("Cannot link file '" + File.str() + "': " + Error); - -      verbose("Linked in file '" + File.str() + "'"); -      break; -    } - -    case sys::ELF_Relocatable_FileType: -    case sys::ELF_SharedObject_FileType: -    case sys::Mach_O_Object_FileType: -    case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: -    case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: -    case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: -    case sys::COFF_FileType: -      is_native = true; -      break; -  } -  return false; -} - -/// LinkFiles - takes a module and a list of files and links them all together. -/// It locates the file either in the current directory, as its absolute -/// or relative pathname, or as a file somewhere in LLVM_LIB_SEARCH_PATH. -/// -/// Inputs: -///  Files      - A vector of sys::Path indicating the LLVM bitcode filenames -///               to be linked.  The names can refer to a mixture of pure LLVM -///               bitcode files and archive (ar) formatted files. -/// -/// Return value: -///  FALSE - No errors. -///  TRUE  - Some error occurred. -/// -bool Linker::LinkInFiles(const std::vector<sys::Path> &Files) { -  bool is_native; -  for (unsigned i = 0; i < Files.size(); ++i) -    if (LinkInFile(Files[i], is_native)) -      return true; -  return false; -} diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index a6599bfe4fb2..74cbdadd61eb 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -12,21 +12,21 @@  //===----------------------------------------------------------------------===//  #include "llvm/Linker.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/TypeFinder.h" +#include "llvm-c/Linker.h"  #include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/Optional.h"  #include "llvm/ADT/SetVector.h"  #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/TypeFinder.h"  #include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Transforms/Utils/Cloning.h"  #include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm-c/Linker.h"  #include <cctype>  using namespace llvm; @@ -180,7 +180,7 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) {      if (DATy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements())        return false;    } else if (VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { -    if (DVTy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements()) +    if (DVTy->getNumElements() != cast<VectorType>(SrcTy)->getNumElements())        return false;    } @@ -421,13 +421,6 @@ namespace {      }      void computeTypeMapping(); -    bool categorizeModuleFlagNodes(const NamedMDNode *ModFlags, -                                   DenseMap<MDString*, MDNode*> &ErrorNode, -                                   DenseMap<MDString*, MDNode*> &WarningNode, -                                   DenseMap<MDString*, MDNode*> &OverrideNode, -                                   DenseMap<MDString*, -                                   SmallSetVector<MDNode*, 8> > &RequireNodes, -                                   SmallSetVector<MDString*, 16> &SeenIDs);      bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV);      bool linkGlobalProto(GlobalVariable *SrcGV); @@ -613,7 +606,8 @@ void ModuleLinker::computeTypeMapping() {      // Check to see if there is a dot in the name followed by a digit.      size_t DotPos = ST->getName().rfind('.');      if (DotPos == 0 || DotPos == StringRef::npos || -        ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1])) +        ST->getName().back() == '.' || +        !isdigit(static_cast<unsigned char>(ST->getName()[DotPos+1])))        continue;      // Check to see if the destination module has a struct with the prefix name. @@ -987,76 +981,16 @@ void ModuleLinker::linkNamedMDNodes() {    }  } -/// categorizeModuleFlagNodes - Categorize the module flags according to their -/// type: Error, Warning, Override, and Require. -bool ModuleLinker:: -categorizeModuleFlagNodes(const NamedMDNode *ModFlags, -                          DenseMap<MDString*, MDNode*> &ErrorNode, -                          DenseMap<MDString*, MDNode*> &WarningNode, -                          DenseMap<MDString*, MDNode*> &OverrideNode, -                          DenseMap<MDString*, -                            SmallSetVector<MDNode*, 8> > &RequireNodes, -                          SmallSetVector<MDString*, 16> &SeenIDs) { -  bool HasErr = false; - -  for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { -    MDNode *Op = ModFlags->getOperand(I); -    assert(Op->getNumOperands() == 3 && "Invalid module flag metadata!"); -    assert(isa<ConstantInt>(Op->getOperand(0)) && -           "Module flag's first operand must be an integer!"); -    assert(isa<MDString>(Op->getOperand(1)) && -           "Module flag's second operand must be an MDString!"); - -    ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); -    MDString *ID = cast<MDString>(Op->getOperand(1)); -    Value *Val = Op->getOperand(2); -    switch (Behavior->getZExtValue()) { -    default: -      assert(false && "Invalid behavior in module flag metadata!"); -      break; -    case Module::Error: { -      MDNode *&ErrNode = ErrorNode[ID]; -      if (!ErrNode) ErrNode = Op; -      if (ErrNode->getOperand(2) != Val) -        HasErr = emitError("linking module flags '" + ID->getString() + -                           "': IDs have conflicting values"); -      break; -    } -    case Module::Warning: { -      MDNode *&WarnNode = WarningNode[ID]; -      if (!WarnNode) WarnNode = Op; -      if (WarnNode->getOperand(2) != Val) -        errs() << "WARNING: linking module flags '" << ID->getString() -               << "': IDs have conflicting values"; -      break; -    } -    case Module::Require:  RequireNodes[ID].insert(Op);     break; -    case Module::Override: { -      MDNode *&OvrNode = OverrideNode[ID]; -      if (!OvrNode) OvrNode = Op; -      if (OvrNode->getOperand(2) != Val) -        HasErr = emitError("linking module flags '" + ID->getString() + -                           "': IDs have conflicting override values"); -      break; -    } -    } - -    SeenIDs.insert(ID); -  } - -  return HasErr; -} -  /// linkModuleFlagsMetadata - Merge the linker flags in Src into the Dest  /// module.  bool ModuleLinker::linkModuleFlagsMetadata() { +  // If the source module has no module flags, we are done.    const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();    if (!SrcModFlags) return false; -  NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata(); -    // If the destination module doesn't have module flags yet, then just copy    // over the source module's flags. +  NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata();    if (DstModFlags->getNumOperands() == 0) {      for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)        DstModFlags->addOperand(SrcModFlags->getOperand(I)); @@ -1064,89 +998,137 @@ bool ModuleLinker::linkModuleFlagsMetadata() {      return false;    } -  bool HasErr = false; +  // First build a map of the existing module flags and requirements. +  DenseMap<MDString*, MDNode*> Flags; +  SmallSetVector<MDNode*, 16> Requirements; +  for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { +    MDNode *Op = DstModFlags->getOperand(I); +    ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); +    MDString *ID = cast<MDString>(Op->getOperand(1)); -  // Otherwise, we have to merge them based on their behaviors. First, -  // categorize all of the nodes in the modules' module flags. If an error or -  // warning occurs, then emit the appropriate message(s). -  DenseMap<MDString*, MDNode*> ErrorNode; -  DenseMap<MDString*, MDNode*> WarningNode; -  DenseMap<MDString*, MDNode*> OverrideNode; -  DenseMap<MDString*, SmallSetVector<MDNode*, 8> > RequireNodes; -  SmallSetVector<MDString*, 16> SeenIDs; - -  HasErr |= categorizeModuleFlagNodes(SrcModFlags, ErrorNode, WarningNode, -                                      OverrideNode, RequireNodes, SeenIDs); -  HasErr |= categorizeModuleFlagNodes(DstModFlags, ErrorNode, WarningNode, -                                      OverrideNode, RequireNodes, SeenIDs); - -  // Check that there isn't both an error and warning node for a flag. -  for (SmallSetVector<MDString*, 16>::iterator -         I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { -    MDString *ID = *I; -    if (ErrorNode[ID] && WarningNode[ID]) -      HasErr = emitError("linking module flags '" + ID->getString() + -                         "': IDs have conflicting behaviors"); +    if (Behavior->getZExtValue() == Module::Require) { +      Requirements.insert(cast<MDNode>(Op->getOperand(2))); +    } else { +      Flags[ID] = Op; +    }    } -  // Early exit if we had an error. -  if (HasErr) return true; - -  // Get the destination's module flags ready for new operands. -  DstModFlags->dropAllReferences(); - -  // Add all of the module flags to the destination module. -  DenseMap<MDString*, SmallVector<MDNode*, 4> > AddedNodes; -  for (SmallSetVector<MDString*, 16>::iterator -         I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { -    MDString *ID = *I; -    if (OverrideNode[ID]) { -      DstModFlags->addOperand(OverrideNode[ID]); -      AddedNodes[ID].push_back(OverrideNode[ID]); -    } else if (ErrorNode[ID]) { -      DstModFlags->addOperand(ErrorNode[ID]); -      AddedNodes[ID].push_back(ErrorNode[ID]); -    } else if (WarningNode[ID]) { -      DstModFlags->addOperand(WarningNode[ID]); -      AddedNodes[ID].push_back(WarningNode[ID]); +  // Merge in the flags from the source module, and also collect its set of +  // requirements. +  bool HasErr = false; +  for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { +    MDNode *SrcOp = SrcModFlags->getOperand(I); +    ConstantInt *SrcBehavior = cast<ConstantInt>(SrcOp->getOperand(0)); +    MDString *ID = cast<MDString>(SrcOp->getOperand(1)); +    MDNode *DstOp = Flags.lookup(ID); +    unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); + +    // If this is a requirement, add it and continue. +    if (SrcBehaviorValue == Module::Require) { +      // If the destination module does not already have this requirement, add +      // it. +      if (Requirements.insert(cast<MDNode>(SrcOp->getOperand(2)))) { +        DstModFlags->addOperand(SrcOp); +      } +      continue; +    } + +    // If there is no existing flag with this ID, just add it. +    if (!DstOp) { +      Flags[ID] = SrcOp; +      DstModFlags->addOperand(SrcOp); +      continue;      } -    for (SmallSetVector<MDNode*, 8>::iterator -           II = RequireNodes[ID].begin(), IE = RequireNodes[ID].end(); -         II != IE; ++II) -      DstModFlags->addOperand(*II); -  } +    // Otherwise, perform a merge. +    ConstantInt *DstBehavior = cast<ConstantInt>(DstOp->getOperand(0)); +    unsigned DstBehaviorValue = DstBehavior->getZExtValue(); + +    // If either flag has override behavior, handle it first. +    if (DstBehaviorValue == Module::Override) { +      // Diagnose inconsistent flags which both have override behavior. +      if (SrcBehaviorValue == Module::Override && +          SrcOp->getOperand(2) != DstOp->getOperand(2)) { +        HasErr |= emitError("linking module flags '" + ID->getString() + +                            "': IDs have conflicting override values"); +      } +      continue; +    } else if (SrcBehaviorValue == Module::Override) { +      // Update the destination flag to that of the source. +      DstOp->replaceOperandWith(0, SrcBehavior); +      DstOp->replaceOperandWith(2, SrcOp->getOperand(2)); +      continue; +    } -  // Now check that all of the requirements have been satisfied. -  for (SmallSetVector<MDString*, 16>::iterator -         I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { -    MDString *ID = *I; -    SmallSetVector<MDNode*, 8> &Set = RequireNodes[ID]; - -    for (SmallSetVector<MDNode*, 8>::iterator -           II = Set.begin(), IE = Set.end(); II != IE; ++II) { -      MDNode *Node = *II; -      assert(isa<MDNode>(Node->getOperand(2)) && -             "Module flag's third operand must be an MDNode!"); -      MDNode *Val = cast<MDNode>(Node->getOperand(2)); - -      MDString *ReqID = cast<MDString>(Val->getOperand(0)); -      Value *ReqVal = Val->getOperand(1); - -      bool HasValue = false; -      for (SmallVectorImpl<MDNode*>::iterator -             RI = AddedNodes[ReqID].begin(), RE = AddedNodes[ReqID].end(); -           RI != RE; ++RI) { -        MDNode *ReqNode = *RI; -        if (ReqNode->getOperand(2) == ReqVal) { -          HasValue = true; -          break; -        } +    // Diagnose inconsistent merge behavior types. +    if (SrcBehaviorValue != DstBehaviorValue) { +      HasErr |= emitError("linking module flags '" + ID->getString() + +                          "': IDs have conflicting behaviors"); +      continue; +    } + +    // Perform the merge for standard behavior types. +    switch (SrcBehaviorValue) { +    case Module::Require: +    case Module::Override: assert(0 && "not possible"); break; +    case Module::Error: { +      // Emit an error if the values differ. +      if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { +        HasErr |= emitError("linking module flags '" + ID->getString() + +                            "': IDs have conflicting values"); +      } +      continue; +    } +    case Module::Warning: { +      // Emit a warning if the values differ. +      if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { +        errs() << "WARNING: linking module flags '" << ID->getString() +               << "': IDs have conflicting values";        } +      continue; +    } +    case Module::Append: { +      MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); +      MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); +      unsigned NumOps = DstValue->getNumOperands() + SrcValue->getNumOperands(); +      Value **VP, **Values = VP = new Value*[NumOps]; +      for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i, ++VP) +        *VP = DstValue->getOperand(i); +      for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i, ++VP) +        *VP = SrcValue->getOperand(i); +      DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), +                                               ArrayRef<Value*>(Values, +                                                                NumOps))); +      delete[] Values; +      break; +    } +    case Module::AppendUnique: { +      SmallSetVector<Value*, 16> Elts; +      MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); +      MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); +      for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i) +        Elts.insert(DstValue->getOperand(i)); +      for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i) +        Elts.insert(SrcValue->getOperand(i)); +      DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), +                                               ArrayRef<Value*>(Elts.begin(), +                                                                Elts.end()))); +      break; +    } +    } +  } -      if (!HasValue) -        HasErr = emitError("linking module flags '" + ReqID->getString() + -                           "': does not have the required value"); +  // Check all of the requirements. +  for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { +    MDNode *Requirement = Requirements[I]; +    MDString *Flag = cast<MDString>(Requirement->getOperand(0)); +    Value *ReqValue = Requirement->getOperand(1); + +    MDNode *Op = Flags[Flag]; +    if (!Op || Op->getOperand(2) != ReqValue) { +      HasErr |= emitError("linking module flags '" + Flag->getString() + +                          "': does not have the required value"); +      continue;      }    } @@ -1187,19 +1169,6 @@ bool ModuleLinker::run() {                                 SrcM->getModuleInlineAsm());    } -  // Update the destination module's dependent libraries list with the libraries -  // from the source module. There's no opportunity for duplicates here as the -  // Module ensures that duplicate insertions are discarded. -  for (Module::lib_iterator SI = SrcM->lib_begin(), SE = SrcM->lib_end(); -       SI != SE; ++SI) -    DstM->addLibrary(*SI); -   -  // If the source library's module id is in the dependent library list of the -  // destination library, remove it since that module is now linked in. -  StringRef ModuleId = SrcM->getModuleIdentifier(); -  if (!ModuleId.empty()) -    DstM->removeLibrary(sys::path::stem(ModuleId)); -      // Loop over all of the linked values to compute type mappings.    computeTypeMapping(); @@ -1323,7 +1292,7 @@ bool ModuleLinker::run() {  //===----------------------------------------------------------------------===//  /// LinkModules - This function links two modules together, with the resulting -/// left module modified to be the composite of the two input modules.  If an +/// Dest module modified to be the composite of the two input modules.  If an  /// error occurs, true is returned and ErrorMsg (if not null) is set to indicate  /// the problem.  Upon failure, the Dest module could be in a modified state,  /// and shouldn't be relied on to be consistent. diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index 7c6cf4f3dd78..74d24f278b77 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -12,9 +12,8 @@  //===----------------------------------------------------------------------===//  #include "llvm/Linker.h" -#include "llvm/Module.h"  #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/Path.h" +#include "llvm/IR/Module.h"  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Support/system_error.h" @@ -24,7 +23,6 @@ Linker::Linker(StringRef progname, StringRef modname,                 LLVMContext& C, unsigned flags):    Context(C),    Composite(new Module(modname, C)), -  LibPaths(),    Flags(flags),    Error(),    ProgramName(progname) { } @@ -32,7 +30,6 @@ Linker::Linker(StringRef progname, StringRef modname,  Linker::Linker(StringRef progname, Module* aModule, unsigned flags) :    Context(aModule->getContext()),    Composite(aModule), -  LibPaths(),    Flags(flags),    Error(),    ProgramName(progname) { } @@ -63,119 +60,11 @@ Linker::verbose(StringRef message) {      errs() << "  " << message << "\n";  } -void -Linker::addPath(const sys::Path& path) { -  LibPaths.push_back(path); -} - -void -Linker::addPaths(const std::vector<std::string>& paths) { -  for (unsigned i = 0, e = paths.size(); i != e; ++i) -    LibPaths.push_back(sys::Path(paths[i])); -} - -void -Linker::addSystemPaths() { -  sys::Path::GetBitcodeLibraryPaths(LibPaths); -  LibPaths.insert(LibPaths.begin(),sys::Path("./")); -} -  Module*  Linker::releaseModule() {    Module* result = Composite; -  LibPaths.clear();    Error.clear();    Composite = 0;    Flags = 0;    return result;  } - -// LoadObject - Read in and parse the bitcode file named by FN and return the -// module it contains (wrapped in an auto_ptr), or auto_ptr<Module>() and set -// Error if an error occurs. -std::auto_ptr<Module> -Linker::LoadObject(const sys::Path &FN) { -  std::string ParseErrorMessage; -  Module *Result = 0; - -  OwningPtr<MemoryBuffer> Buffer; -  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FN.c_str(), Buffer)) -    ParseErrorMessage = "Error reading file '" + FN.str() + "'" + ": " -                      + ec.message(); -  else -    Result = ParseBitcodeFile(Buffer.get(), Context, &ParseErrorMessage); - -  if (Result) -    return std::auto_ptr<Module>(Result); -  Error = "Bitcode file '" + FN.str() + "' could not be loaded"; -  if (ParseErrorMessage.size()) -    Error += ": " + ParseErrorMessage; -  return std::auto_ptr<Module>(); -} - -// IsLibrary - Determine if "Name" is a library in "Directory". Return -// a non-empty sys::Path if its found, an empty one otherwise. -static inline sys::Path IsLibrary(StringRef Name, -                                  const sys::Path &Directory) { - -  sys::Path FullPath(Directory); - -  // Try the libX.a form -  FullPath.appendComponent(("lib" + Name).str()); -  FullPath.appendSuffix("a"); -  if (FullPath.isArchive()) -    return FullPath; - -  // Try the libX.bca form -  FullPath.eraseSuffix(); -  FullPath.appendSuffix("bca"); -  if (FullPath.isArchive()) -    return FullPath; - -  // Try the libX.so (or .dylib) form -  FullPath.eraseSuffix(); -  FullPath.appendSuffix(sys::Path::GetDLLSuffix()); -  if (FullPath.isDynamicLibrary())  // Native shared library? -    return FullPath; -  if (FullPath.isBitcodeFile())    // .so file containing bitcode? -    return FullPath; - -  // Try libX form, to make it possible to add dependency on the -  // specific version of .so, like liblzma.so.1.0.0 -  FullPath.eraseSuffix(); -  if (FullPath.isDynamicLibrary())  // Native shared library? -    return FullPath; -  if (FullPath.isBitcodeFile())    // .so file containing bitcode? -    return FullPath; - -  // Not found .. fall through - -  // Indicate that the library was not found in the directory. -  FullPath.clear(); -  return FullPath; -} - -/// FindLib - Try to convert Filename into the name of a file that we can open, -/// if it does not already name a file we can open, by first trying to open -/// Filename, then libFilename.[suffix] for each of a set of several common -/// library suffixes, in each of the directories in LibPaths. Returns an empty -/// Path if no matching file can be found. -/// -sys::Path -Linker::FindLib(StringRef Filename) { -  // Determine if the pathname can be found as it stands. -  sys::Path FilePath(Filename); -  if (FilePath.canRead() && -      (FilePath.isArchive() || FilePath.isDynamicLibrary())) -    return FilePath; - -  // Iterate over the directories in Paths to see if we can find the library -  // there. -  for (unsigned Index = 0; Index != LibPaths.size(); ++Index) { -    sys::Path Directory(LibPaths[Index]); -    sys::Path FullPath = IsLibrary(Filename, Directory); -    if (!FullPath.isEmpty()) -      return FullPath; -  } -  return sys::Path(); -}  | 
