diff options
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Linker/LinkModules.cpp | 63 | ||||
-rw-r--r-- | lib/Linker/Linker.cpp | 91 |
3 files changed, 39 insertions, 116 deletions
diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 28f1262a43..221b55a9c4 100644 --- a/lib/Linker/CMakeLists.txt +++ b/lib/Linker/CMakeLists.txt @@ -1,4 +1,3 @@ add_llvm_library(LLVMLinker LinkModules.cpp - Linker.cpp ) diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 2fdb8cc9cd..156b536353 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -13,21 +13,15 @@ #include "llvm/Linker.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 <cctype> using namespace llvm; //===----------------------------------------------------------------------===// @@ -35,6 +29,8 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace { + typedef SmallPtrSet<StructType*, 32> TypeSet; + class TypeMapTy : public ValueMapTypeRemapper { /// MappedTypes - This is a mapping from a source type to a destination type /// to use. @@ -55,6 +51,9 @@ class TypeMapTy : public ValueMapTypeRemapper { SmallPtrSet<StructType*, 16> DstResolvedOpaqueTypes; public: + TypeMapTy(TypeSet &Set) : DstStructTypesSet(Set) {} + + TypeSet &DstStructTypesSet; /// addTypeMapping - Indicate that the specified type in the destination /// module is conceptually equivalent to the specified type in the source /// module. @@ -331,13 +330,20 @@ Type *TypeMapTy::getImpl(Type *Ty) { StructType *STy = cast<StructType>(Ty); // If the type is opaque, we can just use it directly. - if (STy->isOpaque()) + if (STy->isOpaque()) { + // A named structure type from src module is used. Add it to the Set of + // identified structs in the destination module. + DstStructTypesSet.insert(STy); return *Entry = STy; + } // Otherwise we create a new type and resolve its body later. This will be // resolved by the top level of get(). SrcDefinitionsToResolve.push_back(STy); StructType *DTy = StructType::create(STy->getContext()); + // A new identified structure type was created. Add it to the set of + // identified structs in the destination module. + DstStructTypesSet.insert(DTy); DstResolvedOpaqueTypes.insert(DTy); return *Entry = DTy; } @@ -379,8 +385,8 @@ namespace { public: std::string ErrorMsg; - ModuleLinker(Module *dstM, Module *srcM, unsigned mode) - : DstM(dstM), SrcM(srcM), Mode(mode) { } + ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode) + : DstM(dstM), SrcM(srcM), TypeMap(Set), Mode(mode) { } bool run(); @@ -594,11 +600,6 @@ void ModuleLinker::computeTypeMapping() { SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(), SrcStructTypes.end()); - TypeFinder DstStructTypes; - DstStructTypes.run(*DstM, true); - SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(), - DstStructTypes.end()); - for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { StructType *ST = SrcStructTypes[i]; if (!ST->hasName()) continue; @@ -629,7 +630,7 @@ void ModuleLinker::computeTypeMapping() { // we prefer to take the '%C' version. So we are then left with both // '%C.1' and '%C' being used for the same types. This leads to some // variables using one type and some using the other. - if (!SrcStructTypesSet.count(DST) && DstStructTypesSet.count(DST)) + if (!SrcStructTypesSet.count(DST) && TypeMap.DstStructTypesSet.count(DST)) TypeMap.addTypeMapping(DST, ST); } @@ -1300,24 +1301,38 @@ bool ModuleLinker::run() { return false; } +Linker::Linker(Module *M) : Composite(M) { + TypeFinder StructTypes; + StructTypes.run(*M, true); + IdentifiedStructTypes.insert(StructTypes.begin(), StructTypes.end()); +} + +Linker::~Linker() { +} + +bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { + ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode); + if (TheLinker.run()) { + if (ErrorMsg) + *ErrorMsg = TheLinker.ErrorMsg; + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // LinkModules entrypoint. //===----------------------------------------------------------------------===// /// 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. bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode, std::string *ErrorMsg) { - ModuleLinker TheLinker(Dest, Src, Mode); - if (TheLinker.run()) { - if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; - return true; - } - - return false; + Linker L(Dest); + return L.linkInModule(Src, Mode, ErrorMsg); } //===----------------------------------------------------------------------===// diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp deleted file mode 100644 index c8ea8ff0a9..0000000000 --- a/lib/Linker/Linker.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//===- lib/Linker/Linker.cpp - Basic Linker functionality ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains basic Linker functionality that all usages will need. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Linker.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" -using namespace llvm; - -Linker::Linker(StringRef progname, StringRef modname, - LLVMContext& C, unsigned flags): - Context(C), - Composite(new Module(modname, C)), - LibPaths(), - Flags(flags), - Error(), - ProgramName(progname) { } - -Linker::Linker(StringRef progname, Module* aModule, unsigned flags) : - Context(aModule->getContext()), - Composite(aModule), - LibPaths(), - Flags(flags), - Error(), - ProgramName(progname) { } - -Linker::~Linker() { - delete Composite; -} - -bool -Linker::error(StringRef message) { - Error = message; - if (!(Flags&QuietErrors)) - errs() << ProgramName << ": error: " << message << "\n"; - return true; -} - -bool -Linker::warning(StringRef message) { - Error = message; - if (!(Flags&QuietWarnings)) - errs() << ProgramName << ": warning: " << message << "\n"; - return false; -} - -void -Linker::verbose(StringRef message) { - if (Flags&Verbose) - 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; -} |