diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h index b402a6090e2..88908fbd72a 100644 --- a/include/llvm/Linker.h +++ b/include/llvm/Linker.h @@ -57,7 +57,12 @@ class Linker { QuietWarnings = 2, ///< Don't print warnings to stderr. QuietErrors = 4 ///< Don't print errors to stderr. }; - + + enum LinkerMode { + DestroySource = 0, // Allow source module to be destroyed. + PreserveSource = 1 // Preserve the source module. + }; + /// @} /// @name Constructors /// @{ @@ -245,7 +250,7 @@ class Linker { Module* Src, ///< Module linked into \p Dest std::string* ErrorMsg = 0 /// Error/diagnostic string ) { - return LinkModules(Composite, Src, ErrorMsg ); + return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg ); } /// This is the heart of the linker. This method will take unconditional @@ -259,7 +264,8 @@ class Linker { /// error. /// @returns True if an error occurs, false otherwise. /// @brief Generically link two modules together. - static bool LinkModules(Module* Dest, Module* Src, std::string* ErrorMsg); + static bool LinkModules(Module* Dest, Module* Src, unsigned Mode, + std::string* ErrorMsg); /// This function looks through the Linker's LibPaths to find a library with /// the name \p Filename. If the library cannot be found, the returned path diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 62a416eed64..4ccabcf5860 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -14,9 +14,12 @@ #include "llvm/Linker.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ValueMapper.h" using namespace llvm; @@ -333,10 +336,16 @@ namespace { std::vector AppendingVars; + unsigned Mode; // Mode to treat source module. + + // Set of items not to link in from source. + SmallPtrSet DoNotLinkFromSource; + public: std::string ErrorMsg; - ModuleLinker(Module *dstM, Module *srcM) : DstM(dstM), SrcM(srcM) { } + ModuleLinker(Module *dstM, Module *srcM, unsigned mode) + : DstM(dstM), SrcM(srcM), Mode(mode) { } bool run(); @@ -596,9 +605,9 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); DstGV->eraseFromParent(); - // Zap the initializer in the source variable so we don't try to link it. - SrcGV->setInitializer(0); - SrcGV->setLinkage(GlobalValue::ExternalLinkage); + // Track the source variable so we don't try to link it. + DoNotLinkFromSource.insert(SrcGV); + return false; } @@ -633,11 +642,10 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { // Make sure to remember this mapping. ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); - // Destroy the source global's initializer (and convert it to a prototype) - // so that we don't attempt to copy it over when processing global - // initializers. - SGV->setInitializer(0); - SGV->setLinkage(GlobalValue::ExternalLinkage); + // Track the source global so that we don't attempt to copy it over when + // processing global initializers. + DoNotLinkFromSource.insert(SGV); + return false; } } @@ -682,8 +690,10 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { // Make sure to remember this mapping. ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); - // Remove the body from the source module so we don't attempt to remap it. - SF->deleteBody(); + // Track the function from the source module so we don't attempt to remap + // it. + DoNotLinkFromSource.insert(SF); + return false; } } @@ -722,8 +732,9 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { // Make sure to remember this mapping. ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); - // Remove the body from the source module so we don't attempt to remap it. - SGA->setAliasee(0); + // Track the alias from the source module so we don't attempt to remap it. + DoNotLinkFromSource.insert(SGA); + return false; } } @@ -779,7 +790,9 @@ void ModuleLinker::linkGlobalInits() { // Loop over all of the globals in the src module, mapping them over as we go for (Module::const_global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) { - if (!I->hasInitializer()) continue; // Only process initialized GV's. + + // Only process initialized GV's or ones not already in dest. + if (!I->hasInitializer() || DoNotLinkFromSource.count(I)) continue; // Grab destination global variable. GlobalVariable *DGV = cast(ValueMap[I]); @@ -805,31 +818,42 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { ValueMap[I] = DI; } - // Splice the body of the source function into the dest function. - Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); - - // At this point, all of the instructions and values of the function are now - // copied over. The only problem is that they are still referencing values in - // the Source function as operands. Loop through all of the operands of the - // functions and patch them up to point to the local versions. - for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap); - + if (Mode == Linker::DestroySource) { + // Splice the body of the source function into the dest function. + Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); + + // At this point, all of the instructions and values of the function are now + // copied over. The only problem is that they are still referencing values in + // the Source function as operands. Loop through all of the operands of the + // functions and patch them up to point to the local versions. + for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap); + + } else { + // Clone the body of the function into the dest function. + SmallVector Returns; // Ignore returns. + CloneFunctionInto(Dst, Src, ValueMap, false, Returns); + } + // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); I != E; ++I) ValueMap.erase(I); + } void ModuleLinker::linkAliasBodies() { for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); - I != E; ++I) + I != E; ++I) { + if (DoNotLinkFromSource.count(I)) + continue; if (Constant *Aliasee = I->getAliasee()) { GlobalAlias *DA = cast(ValueMap[I]); DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap)); } + } } /// linkNamedMDNodes - Insert all of the named mdnodes in Src into the Dest @@ -891,7 +915,6 @@ bool ModuleLinker::run() { 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(); @@ -928,7 +951,8 @@ bool ModuleLinker::run() { // Link in the function bodies that are defined in the source module into // DstM. for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) { - if (SF->isDeclaration()) continue; // No body if function is external. + // Skip if no body (function is external) or marked to skip. + if (SF->isDeclaration() || DoNotLinkFromSource.count(SF)) continue; linkFunctionBody(cast(ValueMap[SF]), SF); } @@ -957,8 +981,9 @@ bool ModuleLinker::run() { // 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, std::string *ErrorMsg) { - ModuleLinker TheLinker(Dest, Src); +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; diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index aa3e2906364..677d17887f4 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -127,7 +127,8 @@ bool BugDriver::addSources(const std::vector &Filenames) { outs() << "Linking in input file: '" << Filenames[i] << "'\n"; std::string ErrorMessage; - if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) { + if (Linker::LinkModules(Program, M.get(), Linker::DestroySource, + &ErrorMessage)) { errs() << ToolName << ": error linking in '" << Filenames[i] << "': " << ErrorMessage << '\n'; return true; diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 422ab62d820..7ff16dbf958 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -222,7 +222,7 @@ static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2, M1 = CloneModule(M1); M2 = CloneModule(M2); } - if (Linker::LinkModules(M1, M2, &ErrorMsg)) { + if (Linker::LinkModules(M1, M2, Linker::DestroySource, &ErrorMsg)) { errs() << BD.getToolName() << ": Error linking modules together:" << ErrorMsg << '\n'; exit(1); @@ -396,7 +396,8 @@ static bool ExtractLoops(BugDriver &BD, // Replace the current program with the loop extracted version, and try to // extract another loop. std::string ErrorMsg; - if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, &ErrorMsg)){ + if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, + Linker::DestroySource, &ErrorMsg)){ errs() << BD.getToolName() << ": Error linking modules together:" << ErrorMsg << '\n'; exit(1); @@ -575,7 +576,8 @@ static bool ExtractBlocks(BugDriver &BD, I->getFunctionType())); std::string ErrorMsg; - if (Linker::LinkModules(ProgClone, Extracted, &ErrorMsg)) { + if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource, + &ErrorMsg)) { errs() << BD.getToolName() << ": Error linking modules together:" << ErrorMsg << '\n'; exit(1); diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 3fb7ba42cd0..95ad1ca5a17 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -103,7 +103,8 @@ int main(int argc, char **argv) { if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n"; - if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) { + if (Linker::LinkModules(Composite.get(), M.get(), Linker::DestroySource, + &ErrorMessage)) { errs() << argv[0] << ": link error in '" << InputFilenames[i] << "': " << ErrorMessage << "\n"; return 1;