summaryrefslogtreecommitdiff
path: root/lib/Linker
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-03-27 17:54:41 +0000
committerBill Wendling <isanbard@gmail.com>2013-03-27 17:54:41 +0000
commitd99a29e9847815d628791e246dbdd50c6371c43d (patch)
tree9d9b76eebba0beeadfbb59d4e557da785c1354d0 /lib/Linker
parent354504320b4984eebf918bec02dc4c248e0b309b (diff)
downloadllvm-d99a29e9847815d628791e246dbdd50c6371c43d.tar.gz
llvm-d99a29e9847815d628791e246dbdd50c6371c43d.tar.bz2
llvm-d99a29e9847815d628791e246dbdd50c6371c43d.tar.xz
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.cpp73
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();