From 54d1e6cab2e2b557903d3be357531260945e21af Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 14 Feb 2002 19:44:09 +0000 Subject: [PATCH] Implement conversion of method pointer parameter in Call instruction to clean up MST benchmark. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1763 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/ExprTypeConvert.cpp | 71 ++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/ExprTypeConvert.cpp b/lib/Transforms/ExprTypeConvert.cpp index b61903578dc..5975a21ff3d 100644 --- a/lib/Transforms/ExprTypeConvert.cpp +++ b/lib/Transforms/ExprTypeConvert.cpp @@ -586,9 +586,11 @@ bool ValueConvertableToType(Value *V, const Type *Ty, // It is safe to convert the specified value to the specified type IFF all of // the uses of the value can be converted to accept the new typed value. // - for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) - if (!OperandConvertableToType(*I, V, Ty, ConvertedTypes)) - return false; + if (V->getType() != Ty) { + for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) + if (!OperandConvertableToType(*I, V, Ty, ConvertedTypes)) + return false; + } return true; } @@ -780,8 +782,44 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, assert (OI != I->op_end() && "Not using value!"); unsigned OpNum = OI - I->op_begin(); - if (OpNum == 0) - return false; // Can't convert method pointer type yet. FIXME + // Are we trying to change the method pointer value to a new type? + if (OpNum == 0) { + PointerType *PTy = dyn_cast(Ty); + if (PTy == 0) return false; // Can't convert to a non-pointer type... + MethodType *MTy = dyn_cast_or_null(PTy->getElementType()); + if (MTy == 0) return false; // Can't convert to a non ptr to method... + + // Perform sanity checks to make sure that new method type has the + // correct number of arguments... + // + unsigned NumArgs = I->getNumOperands()-1; // Don't include method ptr + + // Cannot convert to a type that requires more fixed arguments than + // the call provides... + // + if (NumArgs < MTy->getParamTypes().size()) return false; + + // Unless this is a vararg method type, we cannot provide more arguments + // than are desired... + // + if (!MTy->isVarArg() && NumArgs > MTy->getParamTypes().size()) + return false; + + // Okay, at this point, we know that the call and the method type match + // number of arguments. Now we see if we can convert the arguments + // themselves. + // + const MethodType::ParamTypes &PTs = MTy->getParamTypes(); + for (unsigned i = 0, NA = PTs.size(); i < NA; ++i) + if (!PTs[i]->isLosslesslyConvertableTo(I->getOperand(i+1)->getType())) + return false; // Operands must have compatible types! + + // Okay, at this point, we know that all of the arguments can be + // converted. We succeed if we can change the return type if + // neccesary... + // + return ValueConvertableToType(I, MTy->getReturnType(), CTMap); + } const PointerType *MPtr = cast(I->getOperand(0)->getType()); const MethodType *MTy = cast(MPtr->getElementType()); @@ -1010,11 +1048,26 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, Value *Meth = I->getOperand(0); std::vector Params(I->op_begin()+1, I->op_end()); - std::vector::iterator OI = - find(Params.begin(), Params.end(), OldVal); - assert (OI != Params.end() && "Not using value!"); + if (Meth == OldVal) { // Changing the method pointer? + PointerType *NewPTy = cast(NewVal->getType()); + MethodType *NewTy = cast(NewPTy->getElementType()); + const MethodType::ParamTypes &PTs = NewTy->getParamTypes(); + + // Convert over all of the call operands to their new types... but only + // convert over the part that is not in the vararg section of the call. + // + for (unsigned i = 0; i < PTs.size(); ++i) + Params[i] = ConvertExpressionToType(Params[i], PTs[i], VMC); + Meth = NewVal; // Update call destination to new value + + } else { // Changing an argument, must be in vararg area + std::vector::iterator OI = + find(Params.begin(), Params.end(), OldVal); + assert (OI != Params.end() && "Not using value!"); + + *OI = NewVal; + } - *OI = NewVal; Res = new CallInst(Meth, Params, Name); break; } -- 2.34.1