diff options
author | Chris Lattner <sabre@nondot.org> | 2003-04-28 01:23:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-04-28 01:23:29 +0000 |
commit | 1fd95afab3d49d16c6d0e1e174e4537336548ab1 (patch) | |
tree | 2c791a94abd11601826eaffbcfeb8da4be890a3d | |
parent | b53a1986137752d0f9871f93af2b9fcd0bd4eee8 (diff) |
Fix several bugs:
* 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
-rw-r--r-- | lib/Transforms/IPO/FunctionResolution.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/lib/Transforms/IPO/FunctionResolution.cpp b/lib/Transforms/IPO/FunctionResolution.cpp index 3e530e0708..1b1065e3e9 100644 --- a/lib/Transforms/IPO/FunctionResolution.cpp +++ b/lib/Transforms/IPO/FunctionResolution.cpp @@ -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); } } |