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>

llvm-svn: 178156
This commit is contained in:
Bill Wendling 2013-03-27 17:54:41 +00:00
parent 986d7049cd
commit fa2287825d
1 changed files with 29 additions and 44 deletions

View File

@ -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();