[LLVMdev] Clone a function and change signature

Arushi Aggarwal arushi987 at gmail.com
Tue Feb 22 11:31:55 PST 2011


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>


More information about the llvm-dev mailing list