Few things you have to be careful with:
1) Create args properly and make sure the actual and formal parameter types should be same.
If not add a cast.
2) Make sure the return types are same.
3) Set the calling conventions if any.
4) Replace use if any.
5) Then replace the instruction.
CallSite CS(Call);
SmallVector<Value *, 8> Args(CS.arg_begin(), CS.arg_end());
CallInst *NewCI = CallInst::Create(NewFunc, Args);
NewCI->setCallingConv(NewFunc->getCallingConv());
if (!Call->use_empty())
Call->replaceAllUsesWith(NewCI);
ReplaceInstWithInst(Call, NewCI);
Regards,
Ashutosh
Hi everyone,I am trying to replace the call of a certain function with a call to another function. It would for example replace the following:
%call = tail call noalias i8* @func(i64 10)
by
%call = tail call noalias i8* @other_func(i64 10)
I managed to declare other_func correctly but I am having troubles to understand how I should proceed to do the replacement.
LLVM builds correctly but the instrumentation crashes at optimization time. I know this isn't the correct way to do it because IRBuilder generates IR and I just want to have an instance of a CallInst. But I don't see how it is supposed to be done?
I tried to use ReplaceInstWithInst function as follows:
CallInst *call_to_other_func_inst = IRBuilder.CreateCall(ptr_to_other_func, args);
ReplaceInstWithInst(call_to_func_inst, newI);
There are methods to create CallInst in the Instruction.h file but those needs to give an inserting point. Shoud I insert the call to other_func before the one to func and just remove the call instruction to func?
Thanks for your help,
Pierre
_______________________________________________ LLVM Developers mailing list llvm...@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-- John Criswell Assistant Professor Department of Computer Science, University of Rochester http://www.cs.rochester.edu/u/criswell
bool res = false;I am doing this replacement operation in a FunctionPass (this is no restriction, I could do it on a ModulePass if that's a solution). On each Function given I do an iteration over the instructions and replace (if it's a call to the right function) the call. It's like this:Hi,Thanks both of you for the help. I just missed that Create function had many optional arguments... sorry for that. However my problem wasn't coming from here (IRBuilder CreateCall function still return a pointer to CallInst so I just added 2 times the call?). I didn't wanted to detail the all issue previously because I knew I had a problem with my syntax. So here's my problem:
bool FDPFunction::runOnFunction(Function &F) {
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
Instruction *I = &*i;
if (!I) {
errs() << "error: null pointer instruction\n";
break;
} else if (isMyFunctionCall(I, TLI)) {
errs() << "found a call to the function to replace\n";
res = true;
replacement_function(I);
} else {
errs() << "default: trash instruction\n";
}
}
return res;
}
The problem is that after the first replacement, the iterator becomes a null pointer.
- Make your pass derive from the InstVistor class and implement a visitCallInst() method. I believe the iterators in the InstVistor class do not get invalidated when new instructions are added.
- Iterate over all the instructions first and record the ones to replace in a container (e.g., a std::vector<>). A second loop iterates over the container and replaces all the CallInsts stored therein.
- Look up the iterator invalidation rules for the instruction iterator and use the iterator in a way that does not invalidate the iterator.
Regards,
John Criswell