]> granicus.if.org Git - llvm/commitdiff
Fix several bugs:
authorChris Lattner <sabre@nondot.org>
Mon, 28 Apr 2003 01:23:29 +0000 (01:23 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 28 Apr 2003 01:23:29 +0000 (01:23 +0000)
  * Warnings were emitted all of the time and were really annoying
  * Functions could not be resolved unless they had external linkage.  Linkonce
    linkage was not allowed
  * ConstantPointerRef's were not handled when linking functions
    we now actually handle cast (CPR) to X -> cast (NewCPR) to X

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5967 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/FunctionResolution.cpp

index 3e530e070814f5e750d48837ca02c23ce7a80b31..1b1065e3e926da092b31307e1cc9c094ae687b5a 100644 (file)
@@ -128,7 +128,7 @@ static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
       const FunctionType *OldMT = Old->getFunctionType();
       const FunctionType *ConcreteMT = Concrete->getFunctionType();
       
-      if (OldMT->getParamTypes().size() < ConcreteMT->getParamTypes().size() &&
+      if (OldMT->getParamTypes().size() > ConcreteMT->getParamTypes().size() &&
           !ConcreteMT->isVarArg())
         if (!Old->use_empty()) {
           std::cerr << "WARNING: Linking function '" << Old->getName()
@@ -155,14 +155,13 @@ static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
             return Changed;
           }
       
-      // Attempt to convert all of the uses of the old function to the
-      // concrete form of the function.  If there is a use of the fn that
-      // we don't understand here we punt to avoid making a bad
-      // transformation.
+      // Attempt to convert all of the uses of the old function to the concrete
+      // form of the function.  If there is a use of the fn that we don't
+      // understand here we punt to avoid making a bad transformation.
       //
-      // At this point, we know that the return values are the same for
-      // our two functions and that the Old function has no varargs fns
-      // specified.  In otherwords it's just <retty> (...)
+      // At this point, we know that the return values are the same for our two
+      // functions and that the Old function has no varargs fns specified.  In
+      // otherwords it's just <retty> (...)
       //
       for (unsigned i = 0; i < Old->use_size(); ) {
         User *U = *(Old->use_begin()+i);
@@ -183,6 +182,18 @@ static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                       << " argument or something!" << CI;
             ++i;
           }
+        } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(U)) {
+          if (CPR->use_size() == 1 && isa<ConstantExpr>(CPR->use_back()) &&
+              cast<ConstantExpr>(CPR->use_back())->getOpcode() == 
+                Instruction::Cast) {
+            ConstantExpr *CE = cast<ConstantExpr>(CPR->use_back());
+            Constant *NewCPR = ConstantPointerRef::get(Concrete);
+            CE->replaceAllUsesWith(ConstantExpr::getCast(NewCPR,CE->getType()));
+            CPR->destroyConstant();
+          } else {
+            std::cerr << "Cannot convert use of function: " << CPR << "\n";
+            ++i;
+          }
         } else {
           std::cerr << "Cannot convert use of function: " << U << "\n";
           ++i;
@@ -337,7 +348,7 @@ bool FunctionResolvingPass::run(Module &M) {
         GlobalValue *GV = cast<GlobalValue>(PI->second);
         assert(PI->first == GV->getName() &&
                "Global name and symbol table do not agree!");
-        if (GV->hasExternalLinkage())  // Only resolve decls to external fns
+        if (!GV->hasInternalLinkage())  // Only resolve decls to external fns
           Globals[PI->first].push_back(GV);
       }
     }