Hi, I want to clone a given function, and add an argument to it. I then want to add a call to that new function. I have a callInstruction CI, which I want to transform to call this new function, and to take a new argument. The code I added was as follows CI->getCalledFunction()->dump(); Function* DirectF = CloneFunction(CI->getCalledFunction()); DirectF->setName(CI->getCalledFunction()->getNameStr() + "_SPEC"); DirectF->setLinkage(GlobalValue::InternalLinkage); // add the extra argument new Argument(GEP->getPointerOperand()->getType(),"arg",DirectF); M.getFunctionList().push_back(DirectF); DirectF->dump(); SmallVector<Value*, 8> Args; for(unsigned j =1;j<CI->getNumOperands();j++) { Args.push_back(CI->getOperand(j)); } //Add the extra parameter Args.push_back(GEP->getPointerOperand()); CallInst *CallI = CallInst::Create(DirectF,Args.begin(), Args.end(),"", CI); CallI->dump(); But I get the following exception call void @point_DIRECT(i16* %tmp1324mod, i16* %tmp1322mod) nounwind define internal void @point_DIRECT(i16* %x, i16* %y) nounwind { entry: %xx = alloca i32 ; <i32*> [#uses=3] %yy = alloca i32 ; <i32*> [#uses=3] %tmp = load %struct.MT** @mt, align 8, !dbg !1018 ; <%struct.MT*> [#uses=1] %tmp1 = icmp eq %struct.MT* %tmp, null, !dbg !1018 ; <i1> [#uses=1] br i1 %tmp1, label %return, label %bb, !dbg !1018 bb: ; preds = %entry %tmp2 = load i16* %x, align 2, !dbg !1023 ; <i16> [#uses=1] %tmp3 = sext i16 %tmp2 to i32, !dbg !1023 ; <i32> [#uses=1] store i32 %tmp3, i32* %xx, align 4, !dbg !1023 %tmp4 = load i16* %y, align 2, !dbg !1024 ; <i16> [#uses=1] %tmp5 = sext i16 %tmp4 to i32, !dbg !1024 ; <i32> [#uses=1] store i32 %tmp5, i32* %yy, align 4, !dbg !1024 %tmp6 = load %struct.MT** @mt, align 8, !dbg !1025 ; <%struct.MT*> [#uses=1] call void @MTPoint_DIRECT(%struct.MT* %tmp6, i32* %xx, i32* %yy) nounwind %tmp8 = load i32* %xx, align 4, !dbg !1026 ; <i32> [#uses=1] %tmp9 = trunc i32 %tmp8 to i16, !dbg !1026 ; <i16> [#uses=1] store i16 %tmp9, i16* %x, align 2, !dbg !1026 %tmp10 = load i32* %yy, align 4, !dbg !1027 ; <i32> [#uses=1] %tmp11 = trunc i32 %tmp10 to i16, !dbg !1027 ; <i16> [#uses=1] store i16 %tmp11, i16* %y, align 2, !dbg !1027 ret void return: ; preds = %entry ret void } define internal void @point_DIRECT_SPEC(i16* %x, i16* %y, %struct.termbox* %arg) nounwind { entry: %xx = alloca i32 ; <i32*> [#uses=3] %yy = alloca i32 ; <i32*> [#uses=3] %tmp = load %struct.MT** @mt, align 8, !dbg !1018 ; <%struct.MT*> [#uses=1] %tmp1 = icmp eq %struct.MT* %tmp, null, !dbg !1018 ; <i1> [#uses=1] br i1 %tmp1, label %return, label %bb, !dbg !1018 bb: ; preds = %entry %tmp2 = load i16* %x, align 2, !dbg !1023 ; <i16> [#uses=1] %tmp3 = sext i16 %tmp2 to i32, !dbg !1023 ; <i32> [#uses=1] store i32 %tmp3, i32* %xx, align 4, !dbg !1023 %tmp4 = load i16* %y, align 2, !dbg !1024 ; <i16> [#uses=1] %tmp5 = sext i16 %tmp4 to i32, !dbg !1024 ; <i32> [#uses=1] store i32 %tmp5, i32* %yy, align 4, !dbg !1024 %tmp6 = load %struct.MT** @mt, align 8, !dbg !1025 ; <%struct.MT*> [#uses=1] call void @MTPoint_DIRECT(%struct.MT* %tmp6, i32* %xx, i32* %yy) nounwind %tmp8 = load i32* %xx, align 4, !dbg !1026 ; <i32> [#uses=1] %tmp9 = trunc i32 %tmp8 to i16, !dbg !1026 ; <i16> [#uses=1] store i16 %tmp9, i16* %x, align 2, !dbg !1026 %tmp10 = load i32* %yy, align 4, !dbg !1027 ; <i32> [#uses=1] %tmp11 = trunc i32 %tmp10 to i16, !dbg !1027 ; <i16> [#uses=1] store i16 %tmp11, i16* %y, align 2, !dbg !1027 ret void return: ; preds = %entry ret void } opt: /home/vadve/aggarwa4/llvm27/llvm-2.7/lib/VMCore/Instructions.cpp:307: void llvm::CallInst::init(llvm::Value*, llvm::Value* const*, unsigned int): Assertion `(NumParams == FTy->getNumParams() || (FTy->isVarArg() && NumParams > FTy->getNumParams())) && "Calling a function with bad signature!"' failed. When I looked at the excption, it occurs when creating the CallInst. The type of the function being called at that point is still the old type, without the extra parameter, though the extra parameter seems to have been added when I dump DirectF. Can I get any pointers to what I am doing wrong, and what might be a potential solution. Thanks, Arushi -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110222/618028cf/attachment.html>
On 2/22/11 1:31 PM, Arushi Aggarwal wrote:> Hi, > > I want to clone a given function, and add an argument to it. I then > want to add a call to that new function. I have a callInstruction CI, > which I want to transform to call this new function, and to take a new > argument.If I understand correctly, you're cloning the function first and then adding a new argument to the clone. Do I understand correctly? If so, I don't believe you can do that. IIRC, you have to first create a new, empty function with the additional argument and then use CloneFunctionInto() to clone the body of the original function into the new function. I believe that's what poolalloc does and what I did the last time I had to add function arguments to a function. -- John T.> > The code I added was as follows > > CI->getCalledFunction()->dump(); > Function* DirectF = CloneFunction(CI->getCalledFunction()); > DirectF->setName(CI->getCalledFunction()->getNameStr() + "_SPEC"); > DirectF->setLinkage(GlobalValue::InternalLinkage); > // add the extra argument > new Argument(GEP->getPointerOperand()->getType(),"arg",DirectF); > M.getFunctionList().push_back(DirectF); > DirectF->dump(); > > SmallVector<Value*, 8> Args; > for(unsigned j =1;j<CI->getNumOperands();j++) { > Args.push_back(CI->getOperand(j)); > } > //Add the extra parameter > Args.push_back(GEP->getPointerOperand()); > CallInst *CallI = CallInst::Create(DirectF,Args.begin(), > Args.end(),"", CI); > CallI->dump(); > > > But I get the following exception > > call void @point_DIRECT(i16* %tmp1324mod, i16* %tmp1322mod) nounwind > > define internal void @point_DIRECT(i16* %x, i16* %y) nounwind { > entry: > %xx = alloca i32 ; <i32*> [#uses=3] > %yy = alloca i32 ; <i32*> [#uses=3] > %tmp = load %struct.MT** @mt, align 8, !dbg !1018 ; <%struct.MT*> > [#uses=1] > %tmp1 = icmp eq %struct.MT* %tmp, null, !dbg !1018 ; <i1> [#uses=1] > br i1 %tmp1, label %return, label %bb, !dbg !1018 > > bb: ; preds = %entry > %tmp2 = load i16* %x, align 2, !dbg !1023 ; <i16> [#uses=1] > %tmp3 = sext i16 %tmp2 to i32, !dbg !1023 ; <i32> [#uses=1] > store i32 %tmp3, i32* %xx, align 4, !dbg !1023 > %tmp4 = load i16* %y, align 2, !dbg !1024 ; <i16> [#uses=1] > %tmp5 = sext i16 %tmp4 to i32, !dbg !1024 ; <i32> [#uses=1] > store i32 %tmp5, i32* %yy, align 4, !dbg !1024 > %tmp6 = load %struct.MT** @mt, align 8, !dbg !1025 ; <%struct.MT*> > [#uses=1] > call void @MTPoint_DIRECT(%struct.MT* %tmp6, i32* %xx, i32* %yy) > nounwind > %tmp8 = load i32* %xx, align 4, !dbg !1026 ; <i32> [#uses=1] > %tmp9 = trunc i32 %tmp8 to i16, !dbg !1026 ; <i16> [#uses=1] > store i16 %tmp9, i16* %x, align 2, !dbg !1026 > %tmp10 = load i32* %yy, align 4, !dbg !1027 ; <i32> [#uses=1] > %tmp11 = trunc i32 %tmp10 to i16, !dbg !1027 ; <i16> [#uses=1] > store i16 %tmp11, i16* %y, align 2, !dbg !1027 > ret void > > return: ; preds = %entry > ret void > } > > > define internal void @point_DIRECT_SPEC(i16* %x, i16* %y, > %struct.termbox* %arg) nounwind { > entry: > %xx = alloca i32 ; <i32*> [#uses=3] > %yy = alloca i32 ; <i32*> [#uses=3] > %tmp = load %struct.MT** @mt, align 8, !dbg !1018 ; <%struct.MT*> > [#uses=1] > %tmp1 = icmp eq %struct.MT* %tmp, null, !dbg !1018 ; <i1> [#uses=1] > br i1 %tmp1, label %return, label %bb, !dbg !1018 > > bb: ; preds = %entry > %tmp2 = load i16* %x, align 2, !dbg !1023 ; <i16> [#uses=1] > %tmp3 = sext i16 %tmp2 to i32, !dbg !1023 ; <i32> [#uses=1] > store i32 %tmp3, i32* %xx, align 4, !dbg !1023 > %tmp4 = load i16* %y, align 2, !dbg !1024 ; <i16> [#uses=1] > %tmp5 = sext i16 %tmp4 to i32, !dbg !1024 ; <i32> [#uses=1] > store i32 %tmp5, i32* %yy, align 4, !dbg !1024 > %tmp6 = load %struct.MT** @mt, align 8, !dbg !1025 ; <%struct.MT*> > [#uses=1] > call void @MTPoint_DIRECT(%struct.MT* %tmp6, i32* %xx, i32* %yy) > nounwind > %tmp8 = load i32* %xx, align 4, !dbg !1026 ; <i32> [#uses=1] > %tmp9 = trunc i32 %tmp8 to i16, !dbg !1026 ; <i16> [#uses=1] > store i16 %tmp9, i16* %x, align 2, !dbg !1026 > %tmp10 = load i32* %yy, align 4, !dbg !1027 ; <i32> [#uses=1] > %tmp11 = trunc i32 %tmp10 to i16, !dbg !1027 ; <i16> [#uses=1] > store i16 %tmp11, i16* %y, align 2, !dbg !1027 > ret void > > return: ; preds = %entry > ret void > } > > opt: > /home/vadve/aggarwa4/llvm27/llvm-2.7/lib/VMCore/Instructions.cpp:307: > void llvm::CallInst::init(llvm::Value*, llvm::Value* const*, unsigned > int): Assertion `(NumParams == FTy->getNumParams() || (FTy->isVarArg() > && NumParams > FTy->getNumParams())) && "Calling a function with bad > signature!"' failed. > > > When I looked at the excption, it occurs when creating the CallInst. > > The type of the function being called at that point is still the old > type, without the extra parameter, though the extra parameter seems to > have been added when I dump DirectF. > > Can I get any pointers to what I am doing wrong, and what might be a > potential solution. > > Thanks, > Arushi
On Feb 22, 2011, at 11:46 AM, John Criswell wrote:> On 2/22/11 1:31 PM, Arushi Aggarwal wrote: >> Hi, >> >> I want to clone a given function, and add an argument to it. I then >> want to add a call to that new function. I have a callInstruction CI, >> which I want to transform to call this new function, and to take a new >> argument. > > If I understand correctly, you're cloning the function first and then > adding a new argument to the clone. Do I understand correctly? > > If so, I don't believe you can do that. IIRC, you have to first create > a new, empty function with the additional argument and then use > CloneFunctionInto() to clone the body of the original function into the > new function. I believe that's what poolalloc does and what I did the > last time I had to add function arguments to a function.Right, you can also take a look at the dead argument elimination or argument promotion passes for examples. -Chris
Apparently Analagous Threads
- [LLVMdev] Clone a function and change signature
- [LLVMdev] LLVMdev Digest, Vol 80, Issue 37-Help to unsubscribe
- [LLVMdev] Missing Optimization Opportunities
- [LLVMdev] Question about NoWrap flag for SCEVAddRecExpr
- [LLVMdev] Question about NoWrap flag for SCEVAddRecExpr