From 58890d52eb6f9ba44e70c8fc651201f1d429489e Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 19 Mar 2013 15:26:24 +0000 Subject: The Linker interface has some dead code after the cleanup in r172749 (and possibly others). The attached patch removes it, and tries to update comments accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177406 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Linker/LinkModules.cpp') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 0acbcfadaf..74cbdadd61 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -17,13 +17,13 @@ #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" -- cgit v1.2.3-18-g5258 From cfe99ef9dc734f29d4bab3cc1b91a64add4500c9 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Wed, 27 Mar 2013 10:23:32 +0000 Subject: Improve performance of LinkModules when linking with modules with large numbers of functions which link lazily. Instead of creating and destroying function prototypes irrespective of if they are used, only create them if they are used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178130 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 73 ++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 29 deletions(-) (limited to 'lib/Linker/LinkModules.cpp') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 74cbdadd61..4fb83ebfc8 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -370,11 +370,16 @@ namespace { unsigned Mode; // Mode to treat source module. + struct LazyLinkEntry { + Function *Fn; + llvm::SmallPtrSet Uses; + }; + // Set of items not to link in from source. SmallPtrSet DoNotLinkFromSource; // Vector of functions to lazily link in. - std::vector LazilyLinkFunctions; + std::vector LazilyLinkFunctions; public: std::string ErrorMsg; @@ -801,6 +806,18 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { } } + // If the function is to be lazily linked, don't create it just yet. + // Instead, remember its current set of uses to diff against later. + if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || + SF->hasAvailableExternallyLinkage())) { + LazyLinkEntry LLE; + LLE.Fn = SF; + LLE.Uses.insert(SF->use_begin(), SF->use_end()); + LazilyLinkFunctions.push_back(LLE); + 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()), @@ -813,13 +830,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; @@ -1236,16 +1246,33 @@ bool ModuleLinker::run() { do { LinkedInAnyFunctions = false; - for(std::vector::iterator I = LazilyLinkFunctions.begin(), - E = LazilyLinkFunctions.end(); I != E; ++I) { - if (!*I) + for(std::vector::iterator I = LazilyLinkFunctions.begin(), + E = LazilyLinkFunctions.end(); I != E; ++I) { + Function *SF = I->Fn; + if (!SF) continue; - Function *SF = *I; - Function *DF = cast(ValueMap[SF]); - - if (!DF->use_empty()) { - + // If the number of uses of this function is the same as it was at the + // start of the link, it is not used in this link. + if (SF->getNumUses() != I->Uses.size()) { + Function *DF = Function::Create(TypeMap.get(SF->getFunctionType()), + SF->getLinkage(), SF->getName(), DstM); + copyGVAttributes(DF, SF); + + // Now, copy over any uses of SF that were from DstM to DF. + for (Function::use_iterator UI = SF->use_begin(), UE = SF->use_end(); + UI != UE;) { + if (I->Uses.count(*UI) == 0) { + Use &U = UI.getUse(); + // Increment UI before performing the set to ensure the iterator + // remains valid. + ++UI; + U.set(DF); + } else { + ++UI; + } + } + // Materialize if necessary. if (SF->isDeclaration()) { if (!SF->isMaterializable()) @@ -1259,7 +1286,7 @@ bool ModuleLinker::run() { SF->Dematerialize(); // "Remove" from vector by setting the element to 0. - *I = 0; + I->Fn = 0; // Set flag to indicate we may have more functions to lazily link in // since we linked in a function. @@ -1268,18 +1295,6 @@ bool ModuleLinker::run() { } } 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.2.3-18-g5258 From d99a29e9847815d628791e246dbdd50c6371c43d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 27 Mar 2013 17:54:41 +0000 Subject: Specutively revert r178130. This may be causing a failure on some buildbots: Referencing function in another module! tail call fastcc void @_ZL11EvaluateOpstPtRj(i16 zeroext %17, i16* %Vals, i32* %NumVals), !dbg !219 Referencing function in another module! tail call fastcc void @_ZL11EvaluateOpstPtRj(i16 zeroext %19, i16* %Vals, i32* %NumVals), !dbg !221 Broken module found, compilation aborted! Stack dump: 0. Running pass 'Function Pass Manager' on module 'ld-temp.o'. 1. Running pass 'Module Verifier' on function '@_ZL11EvaluateOpstPtRj' clang: error: unable to execute command: Illegal instruction: 4 clang: error: linker command failed due to signal (use -v to see invocation) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178156 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 73 ++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 44 deletions(-) (limited to 'lib/Linker/LinkModules.cpp') diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 4fb83ebfc8..74cbdadd61 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -370,16 +370,11 @@ namespace { unsigned Mode; // Mode to treat source module. - struct LazyLinkEntry { - Function *Fn; - llvm::SmallPtrSet Uses; - }; - // Set of items not to link in from source. SmallPtrSet DoNotLinkFromSource; // Vector of functions to lazily link in. - std::vector LazilyLinkFunctions; + std::vector LazilyLinkFunctions; public: std::string ErrorMsg; @@ -806,18 +801,6 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { } } - // If the function is to be lazily linked, don't create it just yet. - // Instead, remember its current set of uses to diff against later. - if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || - SF->hasAvailableExternallyLinkage())) { - LazyLinkEntry LLE; - LLE.Fn = SF; - LLE.Uses.insert(SF->use_begin(), SF->use_end()); - LazilyLinkFunctions.push_back(LLE); - 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()), @@ -830,6 +813,13 @@ 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; @@ -1246,33 +1236,16 @@ bool ModuleLinker::run() { do { LinkedInAnyFunctions = false; - for(std::vector::iterator I = LazilyLinkFunctions.begin(), - E = LazilyLinkFunctions.end(); I != E; ++I) { - Function *SF = I->Fn; - if (!SF) + for(std::vector::iterator I = LazilyLinkFunctions.begin(), + E = LazilyLinkFunctions.end(); I != E; ++I) { + if (!*I) continue; - // If the number of uses of this function is the same as it was at the - // start of the link, it is not used in this link. - if (SF->getNumUses() != I->Uses.size()) { - Function *DF = Function::Create(TypeMap.get(SF->getFunctionType()), - SF->getLinkage(), SF->getName(), DstM); - copyGVAttributes(DF, SF); - - // Now, copy over any uses of SF that were from DstM to DF. - for (Function::use_iterator UI = SF->use_begin(), UE = SF->use_end(); - UI != UE;) { - if (I->Uses.count(*UI) == 0) { - Use &U = UI.getUse(); - // Increment UI before performing the set to ensure the iterator - // remains valid. - ++UI; - U.set(DF); - } else { - ++UI; - } - } - + Function *SF = *I; + Function *DF = cast(ValueMap[SF]); + + if (!DF->use_empty()) { + // Materialize if necessary. if (SF->isDeclaration()) { if (!SF->isMaterializable()) @@ -1286,7 +1259,7 @@ bool ModuleLinker::run() { SF->Dematerialize(); // "Remove" from vector by setting the element to 0. - I->Fn = 0; + *I = 0; // Set flag to indicate we may have more functions to lazily link in // since we linked in a function. @@ -1295,6 +1268,18 @@ bool ModuleLinker::run() { } } 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.2.3-18-g5258