Search code examples
llvmllvm-c++-api

Adding an Argument to a Function in LLVM


I wish to write an LLVM pass that two arguments of type i32 to select functions. My first try (sketched below) failed:

bool MyFunctionPass::runOnFunction(Function &f) 
{
    Type *int32 = Type::getInt32Ty(f.getParent()->getContext());
    Argument *xC = new Argument(int32, "__xC", &f);
    ...

The module verifier crashes if I try the above. The newly added argument type is junk 0xCDCDCDCD (uninitialized heap memory). The function type remains:

void (i32 addrspace(1)*, i32 addrspace(1)*, i32)

instead of being extended by the new i32.

Also, adding the parameter directly to the parameter list Function::getArgumentList() failed as the Argument constructor links itself to the function, and this is detected as a double link.

  • Do I need a ModulePass to do this, or will a FunctionPass suffice?
  • Is there an elegant way of doing this?

Thanks!


Solution

  • Adding arguments to a function is surprisingly tricky - as you've discovered, it's not as easy as modifying the argument list.

    The most foolproof way of doing it is probably to first create a new function with all the original arguments + the extra arguments, and then call CloneFunctionInto to embed the original function inside your new function.