Specutively revert r178130.
authorBill Wendling <isanbard@gmail.com>
Wed, 27 Mar 2013 17:54:41 +0000 (17:54 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 27 Mar 2013 17:54:41 +0000 (17:54 +0000)
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

lib/Linker/LinkModules.cpp

index 4fb83ebfc83fd74272989b55a003fd93494a645c..74cbdadd61eba980e69aa22c382beb5b8e9d5e94 100644 (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();