diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-03-27 17:54:41 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-03-27 17:54:41 +0000 |
commit | d99a29e9847815d628791e246dbdd50c6371c43d (patch) | |
tree | 9d9b76eebba0beeadfbb59d4e557da785c1354d0 /lib/Linker | |
parent | 354504320b4984eebf918bec02dc4c248e0b309b (diff) |
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)
<rdar://problem/13516485>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178156 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 73 |
1 files changed, 29 insertions, 44 deletions
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<User*, 4> Uses; - }; - // Set of items not to link in from source. SmallPtrSet<const Value*, 16> DoNotLinkFromSource; // Vector of functions to lazily link in. - std::vector<LazyLinkEntry> LazilyLinkFunctions; + std::vector<Function*> 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<LazyLinkEntry>::iterator I = LazilyLinkFunctions.begin(), - E = LazilyLinkFunctions.end(); I != E; ++I) { - Function *SF = I->Fn; - if (!SF) + for(std::vector<Function*>::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<Function>(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<Function*>::iterator I = LazilyLinkFunctions.begin(), + E = LazilyLinkFunctions.end(); I != E; ++I) { + if (!*I) + continue; + + Function *SF = *I; + Function *DF = cast<Function>(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(); |