[llvm-dev] Placing an existing function's arguments in a call to another function in an LLVM Function Pass

Joseph via llvm-dev llvm-dev at lists.llvm.org
Mon Apr 6 08:52:13 PDT 2020


Hey,

I'm writing an LLVM function pass. So far, the "Programmer's Manual" was 
a tremendous help.

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:
* Locate the `foo()` I need to replace
* Make a `CallInst` to `bar()`
* Populate `CallInst::Create` with the arguments of `foo()`
* Make a call to `ReplaceInstWithInst()` to have it work

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:

```c
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.

-- 
Joseph



More information about the llvm-dev mailing list