solidak
solidak

Reputation: 5081

Placing an existing function's arguments in a call to another function in an LLVM Function Pass

I'm writing an LLVM function pass. I have a function foo(int a, int b), where in some instances, I'll need to replace it's call with bar(int a, int b).

The way I wanted to do it is to basically:

Everything is working just fine, but the arguments of foo() are not getting copied to bar(). When the replacement call is executed, the arguments of bar() are just null.

Here's the relevant code:

bool runOnFunction(Function& F) override
{
    CallInst* call_to_foo = 0;
    Function* foo_func = 0;

    /*
    Loop over all calls in the function and populate foo_func when you find it.

    If we reached below, that means the current function we're in has a call to
    foo() (inside call_to_foo) that we need to replace with bar(). Also, foo_func
    is pointing to a foo Function
    */

    Function* bar_func = get_bar_func();

    // Collect foo args
    // I believe here is the issue: the arguments are not copied
    //  properly or there must be a deep-copy of sorts for it to work
    std::vector<Value*> bar_func_args;
    for (size_t i = 0; i < foo_func->arg_size(); i++) {
        Argument* arg = foo_func->arg_begin() + i;
        bar_func_args.push_back(arg);
    }

    auto* inst_to_replace = CallInst::Create(
        bar_func, ArrayRef<Value*>(bar_func_args),
        "bar_func");

    ReplaceInstWithInst(
    call_inst->getParent()->getInstList(),
    BBI, inst_to_replace);

    return true;
}

Any help would be tremendously appreciated.

Upvotes: 1

Views: 538

Answers (1)

arnt
arnt

Reputation: 9675

The arguments you want are in the call instruction, not in the function being called, so you ned to populate the new call using the operands from the previous cal instruction.

Upvotes: 1

Related Questions