From e6315cd32b4983c1c1ab900c3e28fdfc4b5d003e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:13:18 +0000 Subject: Delete dead code from the linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181094 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/Linker.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index 74d24f2..06d2469 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -37,34 +37,3 @@ Linker::Linker(StringRef progname, Module* aModule, unsigned flags) : 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"; -} - -Module* -Linker::releaseModule() { - Module* result = Composite; - Error.clear(); - Composite = 0; - Flags = 0; - return result; -} -- cgit v1.1 From ae8f1f3fde1d9618bfcf8f629ffd68c26015f921 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:28:57 +0000 Subject: Remove unused members and constructor arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181096 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/Linker.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index 06d2469..f8bf21e 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -19,20 +19,14 @@ #include "llvm/Support/system_error.h" using namespace llvm; -Linker::Linker(StringRef progname, StringRef modname, - LLVMContext& C, unsigned flags): +Linker::Linker(StringRef modname, + LLVMContext& C): Context(C), - Composite(new Module(modname, C)), - Flags(flags), - Error(), - ProgramName(progname) { } + Composite(new Module(modname, C)) { } -Linker::Linker(StringRef progname, Module* aModule, unsigned flags) : +Linker::Linker(Module* aModule) : Context(aModule->getContext()), - Composite(aModule), - Flags(flags), - Error(), - ProgramName(progname) { } + Composite(aModule) { } Linker::~Linker() { delete Composite; -- cgit v1.1 From bcc6ac93bae207431efff90dfb3e741ffdf11469 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:34:41 +0000 Subject: Don't store the context in the Linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181097 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/Linker.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index f8bf21e..c80f817 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -21,11 +21,9 @@ using namespace llvm; Linker::Linker(StringRef modname, LLVMContext& C): - Context(C), Composite(new Module(modname, C)) { } Linker::Linker(Module* aModule) : - Context(aModule->getContext()), Composite(aModule) { } Linker::~Linker() { -- cgit v1.1 From 105193772d84057493968310c1d1c6dd0f1ae735 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:43:00 +0000 Subject: Don't construct or delete a module on the Linker. The linker is now responsible only for actually linking the modules, it is up to the clients to create and destroy them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181098 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/Linker.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index c80f817..ab99b98 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -19,13 +19,8 @@ #include "llvm/Support/system_error.h" using namespace llvm; -Linker::Linker(StringRef modname, - LLVMContext& C): - Composite(new Module(modname, C)) { } - Linker::Linker(Module* aModule) : Composite(aModule) { } Linker::~Linker() { - delete Composite; } -- cgit v1.1 From fca88631650af3e862f7df012f34d9c724a9ed7c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 03:06:50 +0000 Subject: Last batch of cleanups to Linker.h. Update comments, fix * placement, fix method names that are not used in clang, add a linkInModule that takes a Mode and put it in Linker.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181099 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/Linker.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/Linker') diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index ab99b98..83c7160 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -24,3 +24,7 @@ Linker::Linker(Module* aModule) : Linker::~Linker() { } + +bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { + return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg); +} -- cgit v1.1 From c7c35a9b8692ca7ac7a6b4b3f46ddb234ae159c7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 03:48:37 +0000 Subject: Now that Linker.cpp is almost empty, merge it into LinkModules.cpp. Also remove unused includes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181100 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/CMakeLists.txt | 1 - lib/Linker/LinkModules.cpp | 15 +++++++++------ lib/Linker/Linker.cpp | 30 ------------------------------ 3 files changed, 9 insertions(+), 37 deletions(-) delete mode 100644 lib/Linker/Linker.cpp (limited to 'lib/Linker') diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 28f1262..221b55a 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 74cbdad..161c269 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/raw_ostream.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Transforms/Utils/ValueMapper.h" -#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -1287,6 +1281,15 @@ bool ModuleLinker::run() { return false; } +Linker::Linker(Module *M) : Composite(M) {} + +Linker::~Linker() { +} + +bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { + return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg); +} + //===----------------------------------------------------------------------===// // LinkModules entrypoint. //===----------------------------------------------------------------------===// diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp deleted file mode 100644 index 83c7160..0000000 --- a/lib/Linker/Linker.cpp +++ /dev/null @@ -1,30 +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/raw_ostream.h" -#include "llvm/Support/system_error.h" -using namespace llvm; - -Linker::Linker(Module* aModule) : - Composite(aModule) { } - -Linker::~Linker() { -} - -bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { - return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg); -} -- cgit v1.1 From 2e013028f2dd99527044d50808a44ae89d6ba537 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 04:08:02 +0000 Subject: Implement Linker::LinkModules with Linker::linkInModule. Flipping which one is the implementation will let us optimize linkInModule. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181102 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 161c269..9801966 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -1287,7 +1287,13 @@ Linker::~Linker() { } bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { - return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg); + ModuleLinker TheLinker(Composite, Src, Mode); + if (TheLinker.run()) { + if (ErrorMsg) + *ErrorMsg = TheLinker.ErrorMsg; + return true; + } + return false; } //===----------------------------------------------------------------------===// @@ -1301,13 +1307,8 @@ bool Linker::linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg) { /// 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); } //===----------------------------------------------------------------------===// -- cgit v1.1 From cfb320f5f97717c309832e0f92b97835526977a8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 05:05:18 +0000 Subject: Fix a performance bug in the Linker. Now that we hava a convinient place to keep it, remeber the set of identified structs as we merge modules. This speeds up the linking of all the bitcode files in clang with the gold plugin and -plugin-opt=emit-llvm (i.e., link only, no codegen) from 5:25 minutes to 13.6 seconds! Patch by Xiaofei Wan! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181104 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 9801966..d2e13c9 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -29,6 +29,8 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace { + typedef SmallPtrSet TypeSet; + class TypeMapTy : public ValueMapTypeRemapper { /// MappedTypes - This is a mapping from a source type to a destination type /// to use. @@ -49,6 +51,9 @@ class TypeMapTy : public ValueMapTypeRemapper { SmallPtrSet 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. @@ -325,13 +330,20 @@ Type *TypeMapTy::getImpl(Type *Ty) { StructType *STy = cast(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; } @@ -373,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(); @@ -588,11 +600,6 @@ void ModuleLinker::computeTypeMapping() { SmallPtrSet SrcStructTypesSet(SrcStructTypes.begin(), SrcStructTypes.end()); - TypeFinder DstStructTypes; - DstStructTypes.run(*DstM, true); - SmallPtrSet DstStructTypesSet(DstStructTypes.begin(), - DstStructTypes.end()); - for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { StructType *ST = SrcStructTypes[i]; if (!ST->hasName()) continue; @@ -623,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); } @@ -1281,13 +1288,17 @@ bool ModuleLinker::run() { return false; } -Linker::Linker(Module *M) : Composite(M) {} +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, Src, Mode); + ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode); if (TheLinker.run()) { if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; -- cgit v1.1 From a84a83bbcdfaecadfc6574094272fd3edc429a23 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Tue, 28 May 2013 15:17:05 +0000 Subject: Extend RemapInstruction and friends to take an optional new parameter, a ValueMaterializer. Extend LinkModules to pass a ValueMaterializer to RemapInstruction and friends to lazily create Functions for lazily linked globals. This is a big win when linking small modules with large (mostly unused) library modules. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182776 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 127 +++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 50 deletions(-) (limited to 'lib/Linker') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index d2e13c9..f322112 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -353,12 +353,32 @@ Type *TypeMapTy::getImpl(Type *Ty) { //===----------------------------------------------------------------------===// namespace { + class ModuleLinker; + + /// ValueMaterializerTy - Creates prototypes for functions that are lazily + /// linked on the fly. This speeds up linking for modules with many + /// lazily linked functions of which few get used. + class ValueMaterializerTy : public ValueMaterializer { + TypeMapTy &TypeMap; + Module *DstM; + std::vector &LazilyLinkFunctions; + public: + ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM, + std::vector &LazilyLinkFunctions) : + ValueMaterializer(), TypeMap(TypeMap), DstM(DstM), + LazilyLinkFunctions(LazilyLinkFunctions) { + } + + virtual Value *materializeValueFor(Value *V); + }; + /// ModuleLinker - This is an implementation class for the LinkModules /// function, which is the entrypoint for this file. class ModuleLinker { Module *DstM, *SrcM; TypeMapTy TypeMap; + ValueMaterializerTy ValMaterializer; /// ValueMap - Mapping of values from what they used to be in Src, to what /// they are now in DstM. ValueToValueMapTy is a ValueMap, which involves @@ -386,7 +406,9 @@ namespace { std::string ErrorMsg; ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode) - : DstM(dstM), SrcM(srcM), TypeMap(Set), Mode(mode) { } + : DstM(dstM), SrcM(srcM), TypeMap(Set), + ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), + Mode(mode) { } bool run(); @@ -487,6 +509,20 @@ static bool isLessConstraining(GlobalValue::VisibilityTypes a, return false; } +Value *ValueMaterializerTy::materializeValueFor(Value *V) { + Function *SF = dyn_cast(V); + if (!SF) + return NULL; + + Function *DF = Function::Create(TypeMap.get(SF->getFunctionType()), + SF->getLinkage(), SF->getName(), DstM); + copyGVAttributes(DF, SF); + + LazilyLinkFunctions.push_back(SF); + return DF; +} + + /// getLinkageResult - This analyzes the two global values and determines what /// the result will look like in the destination module. In particular, it /// computes the resultant linkage type and visibility, computes whether the @@ -802,6 +838,14 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { } } + // If the function is to be lazily linked, don't create it just yet. + // The ValueMaterializerTy will deal with creating it if it's used. + if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || + SF->hasAvailableExternallyLinkage())) { + DoNotLinkFromSource.insert(SF); + return false; + } + // If there is no linkage to be performed or we are linking from the source, // bring SF over. Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()), @@ -814,13 +858,6 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { // Any uses of DF need to change to NewDF, with cast. DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType())); DGV->eraseFromParent(); - } else { - // Internal, LO_ODR, or LO linkage - stick in set to ignore and lazily link. - if (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || - SF->hasAvailableExternallyLinkage()) { - DoNotLinkFromSource.insert(SF); - LazilyLinkFunctions.push_back(SF); - } } ValueMap[SF] = NewDF; @@ -887,7 +924,7 @@ void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { SmallVector Elements; getArrayElements(AVI.DstInit, Elements); - Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap); + Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap, &ValMaterializer); getArrayElements(SrcInit, Elements); ArrayType *NewType = cast(AVI.NewGV->getType()->getElementType()); @@ -908,7 +945,7 @@ void ModuleLinker::linkGlobalInits() { GlobalVariable *DGV = cast(ValueMap[I]); // Figure out what the initializer looks like in the dest module. DGV->setInitializer(MapValue(I->getInitializer(), ValueMap, - RF_None, &TypeMap)); + RF_None, &TypeMap, &ValMaterializer)); } } @@ -938,12 +975,14 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { // 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); + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, + &TypeMap, &ValMaterializer); } else { // Clone the body of the function into the dest function. SmallVector Returns; // Ignore returns. - CloneFunctionInto(Dst, Src, ValueMap, false, Returns, "", NULL, &TypeMap); + CloneFunctionInto(Dst, Src, ValueMap, false, Returns, "", NULL, + &TypeMap, &ValMaterializer); } // There is no need to map the arguments anymore. @@ -961,7 +1000,8 @@ void ModuleLinker::linkAliasBodies() { continue; if (Constant *Aliasee = I->getAliasee()) { GlobalAlias *DA = cast(ValueMap[I]); - DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap)); + DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, + &TypeMap, &ValMaterializer)); } } } @@ -978,7 +1018,7 @@ void ModuleLinker::linkNamedMDNodes() { // Add Src elements into Dest node. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) DestNMD->addOperand(MapValue(I->getOperand(i), ValueMap, - RF_None, &TypeMap)); + RF_None, &TypeMap, &ValMaterializer)); } } @@ -1238,49 +1278,36 @@ bool ModuleLinker::run() { LinkedInAnyFunctions = false; for(std::vector::iterator I = LazilyLinkFunctions.begin(), - E = LazilyLinkFunctions.end(); I != E; ++I) { - if (!*I) - continue; - + E = LazilyLinkFunctions.end(); I != E; ++I) { Function *SF = *I; + if (!SF) + continue; + Function *DF = cast(ValueMap[SF]); - - if (!DF->use_empty()) { - - // Materialize if necessary. - if (SF->isDeclaration()) { - if (!SF->isMaterializable()) - continue; - if (SF->Materialize(&ErrorMsg)) - return true; - } - - // Link in function body. - linkFunctionBody(DF, SF); - SF->Dematerialize(); - // "Remove" from vector by setting the element to 0. - *I = 0; - - // Set flag to indicate we may have more functions to lazily link in - // since we linked in a function. - LinkedInAnyFunctions = true; + // Materialize if necessary. + if (SF->isDeclaration()) { + if (!SF->isMaterializable()) + continue; + if (SF->Materialize(&ErrorMsg)) + return true; } + + // Erase from vector *before* the function body is linked - linkFunctionBody could + // invalidate I. + LazilyLinkFunctions.erase(I); + + // Link in function body. + linkFunctionBody(DF, SF); + SF->Dematerialize(); + + // Set flag to indicate we may have more functions to lazily link in + // since we linked in a function. + LinkedInAnyFunctions = true; + break; } } while (LinkedInAnyFunctions); - // Remove any prototypes of functions that were not actually linked in. - for(std::vector::iterator I = LazilyLinkFunctions.begin(), - E = LazilyLinkFunctions.end(); I != E; ++I) { - if (!*I) - continue; - - Function *SF = *I; - Function *DF = cast(ValueMap[SF]); - if (DF->use_empty()) - DF->eraseFromParent(); - } - // Now that all of the types from the source are used, resolve any structs // copied over to the dest that didn't exist there. TypeMap.linkDefinedTypeBodies(); -- cgit v1.1