diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index aa483322940..d0512593abf 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -181,11 +181,11 @@ let Properties = [InstrNoMem] in { //===------------------------ Debugger Intrinsics -------------------------===// // -def int_dbg_stoppoint : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty, +def int_dbg_stoppoint : Intrinsic<[llvm_void_ty, llvm_uint_ty, llvm_uint_ty, llvm_descriptor_ty]>; -def int_dbg_region_start : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; -def int_dbg_region_end : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; -def int_dbg_func_start : Intrinsic<[llvm_anchor_ty, llvm_descriptor_ty]>; +def int_dbg_region_start : Intrinsic<[llvm_void_ty]>; +def int_dbg_region_end : Intrinsic<[llvm_void_ty]>; +def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>; // dbg_declare, // Declare a local object diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 501bd62d6e1..61b194ab39a 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -1861,8 +1861,8 @@ void BytecodeReader::ParseFunctionBody(Function* F) { if (!upgradedFunctions.empty()) { for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI) for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); - II != IE; ++II) - if (CallInst* CI = dyn_cast(II)) { + II != IE;) + if (CallInst* CI = dyn_cast(II++)) { std::map::iterator FI = upgradedFunctions.find(CI->getCalledFunction()); if (FI != upgradedFunctions.end()) diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 82ca3c254b2..316d1ad2f64 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -403,8 +403,6 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: case Intrinsic::dbg_func_start: - if (CI->getType() != Type::VoidTy) - CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); break; // Simply strip out debugging intrinsics case Intrinsic::memcpy_i32: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index f1afeb93e3d..27e90877a2c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -966,19 +966,19 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::dbg_stoppoint: { MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); - if (DebugInfo && DebugInfo->Verify(I.getOperand(4))) { + if (DebugInfo && DebugInfo->Verify(I.getOperand(3))) { std::vector Ops; // Input Chain Ops.push_back(getRoot()); // line number - Ops.push_back(getValue(I.getOperand(2))); + Ops.push_back(getValue(I.getOperand(1))); // column - Ops.push_back(getValue(I.getOperand(3))); + Ops.push_back(getValue(I.getOperand(2))); - DebugInfoDesc *DD = DebugInfo->getDescFor(I.getOperand(4)); + DebugInfoDesc *DD = DebugInfo->getDescFor(I.getOperand(3)); assert(DD && "Not a debug information descriptor"); CompileUnitDesc *CompileUnit = dyn_cast(DD); assert(CompileUnit && "Not a compile unit"); diff --git a/lib/Debugger/ProgramInfo.cpp b/lib/Debugger/ProgramInfo.cpp index ebca794320f..9ed0db2f12d 100644 --- a/lib/Debugger/ProgramInfo.cpp +++ b/lib/Debugger/ProgramInfo.cpp @@ -63,11 +63,11 @@ static const GlobalVariable *getNextStopPoint(const Value *V, unsigned &LineNo, if (F->getIntrinsicID() == Intrinsic::dbg_stoppoint) { unsigned CurLineNo = ~0, CurColNo = ~0; const GlobalVariable *CurDesc = 0; - if (const ConstantInt *C = dyn_cast(CI->getOperand(2))) + if (const ConstantInt *C = dyn_cast(CI->getOperand(1))) CurLineNo = C->getRawValue(); - if (const ConstantInt *C = dyn_cast(CI->getOperand(3))) + if (const ConstantInt *C = dyn_cast(CI->getOperand(2))) CurColNo = C->getRawValue(); - const Value *Op = CI->getOperand(4); + const Value *Op = CI->getOperand(3); if ((CurDesc = dyn_cast(Op)) && (LineNo < LastLineNo || diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 57723b44ca1..43b4b71c2b2 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) { case Intrinsic::dbg_stoppoint: { // If we use writeOperand directly we get a "u" suffix which is rejected // by gcc. - ConstantUInt *SI = cast(I.getOperand(2)); - GlobalVariable *GV = cast(I.getOperand(4)); + ConstantUInt *SI = cast(I.getOperand(1)); + GlobalVariable *GV = cast(I.getOperand(3)); ConstantStruct *CS = cast(GV->getInitializer()); std::string FileName = CS->getOperand(4)->getStringValue(); std::string Directory = CS->getOperand(5)->getStringValue(); diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 57723b44ca1..43b4b71c2b2 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -1691,8 +1691,8 @@ void CWriter::visitCallInst(CallInst &I) { case Intrinsic::dbg_stoppoint: { // If we use writeOperand directly we get a "u" suffix which is rejected // by gcc. - ConstantUInt *SI = cast(I.getOperand(2)); - GlobalVariable *GV = cast(I.getOperand(4)); + ConstantUInt *SI = cast(I.getOperand(1)); + GlobalVariable *GV = cast(I.getOperand(3)); ConstantStruct *CS = cast(GV->getInitializer()); std::string FileName = CS->getOperand(4)->getStringValue(); std::string Directory = CS->getOperand(5)->getStringValue(); diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index 8fcbdd16e5a..fce787c78b5 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -116,7 +116,7 @@ bool StripSymbols::runOnModule(Module &M) { Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); while (!StopPoint->use_empty()) { CallInst *CI = cast(StopPoint->use_back()); - Value *Arg = CI->getOperand(4); + Value *Arg = CI->getOperand(3); CI->replaceAllUsesWith(RV); CI->eraseFromParent(); if (Arg->use_empty()) diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 689a32f958d..08f6869de50 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Assembly/AutoUpgrade.h" +#include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Module.h" @@ -73,6 +74,31 @@ static Function *getUpgradedIntrinsic(Function *F) { if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") return getUpgradedUnaryFn(F); break; + case 'd': + if (Name == "llvm.dbg.stoppoint") { + if (F->getReturnType() != Type::VoidTy) { + return M->getOrInsertFunction(Name, Type::VoidTy, + Type::UIntTy, + Type::UIntTy, + F->getFunctionType()->getParamType(3), + NULL); + } + } else if (Name == "llvm.dbg.func.start") { + if (F->getReturnType() != Type::VoidTy) { + return M->getOrInsertFunction(Name, Type::VoidTy, + F->getFunctionType()->getParamType(0), + NULL); + } + } else if (Name == "llvm.dbg.region.start") { + if (F->getReturnType() != Type::VoidTy) { + return M->getOrInsertFunction(Name, Type::VoidTy, NULL); + } + } else if (Name == "llvm.dbg.region.end") { + if (F->getReturnType() != Type::VoidTy) { + return M->getOrInsertFunction(Name, Type::VoidTy, NULL); + } + } + break; case 'i': if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) { if (F->arg_begin()->getType() == Type::FloatTy) @@ -106,6 +132,29 @@ static Function *getUpgradedIntrinsic(Function *F) { return 0; } +// Occasionally upgraded function call site arguments need to be permutated to +// some new order. The result of getArgumentPermutation is an array of size +// F->getFunctionType()getNumParams() indicating the new operand order. A value +// of zero in the array indicates replacing with UndefValue for the arg type. +// NULL is returned if there is no permutation. It's assumed that the function +// name is in the form "llvm.?????" +static unsigned *getArgumentPermutation(Function* F) { + // Get the Function's name. + const std::string& Name = F->getName(); + switch (Name[5]) { + case 'd': + if (Name == "llvm.dbg.stoppoint") { + static unsigned Permutation[] = { 2, 3, 4 }; + assert(F->getFunctionType()->getNumParams() == + (sizeof(Permutation) / sizeof(unsigned)) && + "Permutation is wrong length"); + return Permutation; + } + break; + } + return NULL; +} + // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to // their non-overloaded variants by appending the appropriate suffix based on // the argument types. @@ -157,72 +206,75 @@ Instruction* llvm::MakeUpgradedCall(Function *F, return result; } -// UpgradeIntrinsicCall - In the BC reader, change a call to some intrinsic to -// be a called to the specified intrinsic. We expect the callees to have the -// same number of arguments, but their types may be different. +// UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be +// a call to an upgraded intrinsic. We may have to permute the order or promote +// some arguments with a cast. void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Function *F = CI->getCalledFunction(); const FunctionType *NewFnTy = NewFn->getFunctionType(); std::vector Oprnds; - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) { - Value *V = CI->getOperand(i); - if (V->getType() != NewFnTy->getParamType(i-1)) - V = new CastInst(V, NewFnTy->getParamType(i-1), V->getName(), CI); - Oprnds.push_back(V); + + unsigned *Permutation = getArgumentPermutation(NewFn); + unsigned N = NewFnTy->getNumParams(); + + if (Permutation) { + for (unsigned i = 0; i != N; ++i) { + unsigned p = Permutation[i]; + + if (p) { + Value *V = CI->getOperand(p); + if (V->getType() != NewFnTy->getParamType(i)) + V = new CastInst(V, NewFnTy->getParamType(i), V->getName(), CI); + Oprnds.push_back(V); + } else + Oprnds.push_back(UndefValue::get(NewFnTy->getParamType(i))); + } + } else { + assert(N == (CI->getNumOperands() - 1) && + "Upgraded function needs permutation"); + for (unsigned i = 0; i != N; ++i) { + Value *V = CI->getOperand(i + 1); + if (V->getType() != NewFnTy->getParamType(i)) + V = new CastInst(V, NewFnTy->getParamType(i), V->getName(), CI); + Oprnds.push_back(V); + } } - CallInst *NewCI = new CallInst(NewFn, Oprnds, CI->getName(), CI); + + bool NewIsVoid = NewFn->getReturnType() == Type::VoidTy; + + CallInst *NewCI = new CallInst(NewFn, Oprnds, + NewIsVoid ? "" : CI->getName(), + CI); NewCI->setTailCall(CI->isTailCall()); NewCI->setCallingConv(CI->getCallingConv()); if (!CI->use_empty()) { - Instruction *RetVal = NewCI; - if (F->getReturnType() != NewFn->getReturnType()) { - RetVal = new CastInst(NewCI, NewFn->getReturnType(), - NewCI->getName(), CI); - NewCI->moveBefore(RetVal); + if (NewIsVoid) { + CI->replaceAllUsesWith(UndefValue::get(CI->getType())); + } else { + Instruction *RetVal = NewCI; + + if (F->getReturnType() != NewFn->getReturnType()) { + RetVal = new CastInst(NewCI, NewFn->getReturnType(), + NewCI->getName(), CI); + NewCI->moveBefore(RetVal); + } + + CI->replaceAllUsesWith(RetVal); } - CI->replaceAllUsesWith(RetVal); } CI->eraseFromParent(); } bool llvm::UpgradeCallsToIntrinsic(Function* F) { - if (Function* newF = UpgradeIntrinsicFunction(F)) { + if (Function* NewFn = UpgradeIntrinsicFunction(F)) { for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); UI != UE; ) { - if (CallInst* CI = dyn_cast(*UI++)) { - std::vector Oprnds; - 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, Oprnds, - CI->hasName() ? "autoupcall" : "", CI); - newCI->setTailCall(CI->isTailCall()); - newCI->setCallingConv(CI->getCallingConv()); - if (CI->use_empty()) { - // noop - } else if (CI->getType() != newCI->getType()) { - CastInst *final = new CastInst(newCI, CI->getType(), - "autoupgrade_uncast", newCI); - newCI->moveBefore(final); - CI->replaceAllUsesWith(final); - } else { - CI->replaceAllUsesWith(newCI); - } - CI->eraseFromParent(); - } + if (CallInst* CI = dyn_cast(*UI++)) + UpgradeIntrinsicCall(CI, NewFn); } - if (newF != F) + if (NewFn != F) F->eraseFromParent(); return true; }