Changes in directory llvm/lib/VMCore:
AutoUpgrade.cpp updated: 1.7 -> 1.8 --- Log message: Fix auto-upgrade of intrinsics to work properly with both assembly and bytecode reading. This code is crufty, the result of much hacking to get things working correctly. Cleanup patches will follow. --- Diffs of the changes: (+98 -28) AutoUpgrade.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 98 insertions(+), 28 deletions(-) Index: llvm/lib/VMCore/AutoUpgrade.cpp diff -u llvm/lib/VMCore/AutoUpgrade.cpp:1.7 llvm/lib/VMCore/AutoUpgrade.cpp:1.8 --- llvm/lib/VMCore/AutoUpgrade.cpp:1.7 Mon Jan 23 01:42:30 2006 +++ llvm/lib/VMCore/AutoUpgrade.cpp Fri Jan 27 05:49:27 2006 @@ -75,9 +75,26 @@ return 0; } +// This assumes the Function is one of the intrinsics we upgraded. +static inline const Type* getTypeFromFunction(Function *F) { + const Type* Ty = F->getReturnType(); + if (Ty->isFloatingPoint()) + return Ty; + if (Ty->isSigned()) + return Ty->getUnsignedVersion(); + if (Ty->isInteger()) + return Ty; + if (Ty == Type::BoolTy) { + Function::const_arg_iterator ArgIt = F->arg_begin(); + if (ArgIt != F->arg_end()) + return ArgIt->getType(); + } + return 0; +} + bool llvm::IsUpgradeableIntrinsicName(const std::string& Name) { // Quickly eliminate it, if it's not a candidate. - if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] != + if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') return false; @@ -140,23 +157,68 @@ return 0; } -Instruction* llvm::UpgradeIntrinsicCall(CallInst *CI) { + +Instruction* llvm::MakeUpgradedCall( + Function* F, const std::vector<Value*>& Params, BasicBlock* BB, + bool isTailCall, unsigned CallingConv) { + assert(F && "Need a Function to make a CallInst"); + assert(BB && "Need a BasicBlock to make a CallInst"); + + // Convert the params + bool signedArg = false; + std::vector<Value*> Oprnds; + for (std::vector<Value*>::const_iterator PI = Params.begin(), + PE = Params.end(); PI != PE; ++PI) { + const Type* opTy = (*PI)->getType(); + if (opTy->isSigned()) { + signedArg = true; + CastInst* cast = + new CastInst(*PI,opTy->getUnsignedVersion(), "autoupgrade_cast"); + BB->getInstList().push_back(cast); + Oprnds.push_back(cast); + } + else + Oprnds.push_back(*PI); + } + + Instruction* result = new CallInst(F,Oprnds,"autoupgrade_call"); + if (isTailCall) cast<CallInst>(result)->setTailCall(); + if (CallingConv) cast<CallInst>(result)->setCallingConv(CallingConv); + if (signedArg) { + const Type* newTy = F->getReturnType()->getUnsignedVersion(); + CastInst* final = new CastInst(result, newTy, "autoupgrade_uncast"); + BB->getInstList().push_back(result); + result = final; + } + return result; +} + +Instruction* llvm::UpgradeIntrinsicCall(CallInst *CI, Function* newF) { Function *F = CI->getCalledFunction(); - if (const Type* Ty = getTypeFromFunctionName(F)) { - Function* newF = UpgradeIntrinsicFunction(F); + if (const Type* Ty = + (newF ? getTypeFromFunction(newF) : getTypeFromFunctionName(F))) { std::vector<Value*> Oprnds; - for (User::op_iterator OI = CI->op_begin(), OE = CI->op_end(); - OI != OE; ++OI) - Oprnds.push_back(CI); - CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI); - if (Ty->isSigned()) { - const Type* newTy = Ty->getUnsignedVersion(); - newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, - "autoupgrade_cast", newCI)); - CastInst* final = new CastInst(newCI, Ty, "autoupgrade_uncast",newCI); - newCI->moveBefore(final); - return final; + User::op_iterator OI = CI->op_begin(); + ++OI; + for (User::op_iterator OE = CI->op_end() ; OI != OE; ++OI) { + const Type* opTy = OI->get()->getType(); + if (opTy->isSigned()) + Oprnds.push_back( + new CastInst(OI->get(),opTy->getUnsignedVersion(), + "autoupgrade_cast",CI)); + else + Oprnds.push_back(*OI); } + CallInst* newCI = new CallInst((newF?newF:F),Oprnds,"autoupgrade_call",CI); + newCI->setTailCall(CI->isTailCall()); + newCI->setCallingConv(CI->getCallingConv()); + if (const Type* oldType = CI->getCalledFunction()->getReturnType()) + if (oldType->isSigned()) { + CastInst* final = + new CastInst(newCI, oldType, "autoupgrade_uncast",newCI); + newCI->moveBefore(final); + return final; + } return newCI; } return 0; @@ -170,20 +232,28 @@ std::vector<Value*> Oprnds; User::op_iterator OI = CI->op_begin(); ++OI; - for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI) - Oprnds.push_back(*OI); - CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI); - const Type* Ty = Oprnds[0]->getType(); - if (Ty->isSigned()) { - const Type* newTy = Ty->getUnsignedVersion(); - newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, - "autoupgrade_cast", newCI)); - CastInst* final = new CastInst(newCI, Ty, "autoupgrade_uncast",newCI); - newCI->moveBefore(final); - CI->replaceAllUsesWith(final); - } else { - CI->replaceAllUsesWith(newCI); + for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI) { + const Type* opTy = OI->get()->getType(); + if (opTy->isSigned()) { + Oprnds.push_back( + new CastInst(OI->get(),opTy->getUnsignedVersion(), + "autoupgrade_cast",CI)); + } + else + Oprnds.push_back(*OI); } + CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI); + newCI->setTailCall(CI->isTailCall()); + newCI->setCallingConv(CI->getCallingConv()); + if (const Type* Ty = CI->getCalledFunction()->getReturnType()) + if (Ty->isSigned()) { + CastInst* final = + new CastInst(newCI, Ty, "autoupgrade_uncast",newCI); + newCI->moveBefore(final); + CI->replaceAllUsesWith(final); + } else { + CI->replaceAllUsesWith(newCI); + } CI->eraseFromParent(); } } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits