Reputation: 5081
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:
foo()
I need to replaceCallInst
to bar()
CallInst::Create
with the arguments of foo()
ReplaceInstWithInst()
to have it workEverything 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
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