[llvm-dev] function call replacement
John Criswell via llvm-dev
llvm-dev at lists.llvm.org
Tue Jun 21 07:50:29 PDT 2016
On 6/21/16 3:10 AM, Pierre Gagelin wrote:
> 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:
>
> 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:
>
> bool FDPFunction::runOnFunction(Function &F) {
> bool res = false;
> 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.
You might be invalidating the iterator after inserting the first
CallInst. There are multiple ways to solve this problem:
1. 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.
2. 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.
3. 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
> With the break instruction the program is correctly instrumented for
> the first call (about that: what is the use of replaceAllUsesWith
> function? I thought it would replace all uses of the function... but
> just one is done). I can then link it and execute with lli (I still
> get a: "*** Error in `lli': corrupted double-linked list: 0xaddress
> ***" but after the whole execution is done).
>
> But if I remove the break and the if condition associated, well I get
> a null pointer exception : Assertion `Val && "isa<> used on a null
> pointer"' failed
>
> I tried to clone the current instruction to not modify the iterator
> but the ReplaceInstWithInst will cause troubles (probably because a
> copied instruction has no parents):
>
> #0 0x0000000002a95b5c llvm::sys::PrintStackTrace(llvm::raw_ostream&)
> /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:400:0
> #1 0x0000000002a95edf PrintStaI tried to clone the current instruction
> to not modify the iterator but the ReplaceInstWithInst will cause
> troublesckTraceSignalHandler(void*)
> /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:468:0
> #2 0x0000000002a94145 llvm::sys::RunSignalHandlers()
> /home/pierre/Desktop/llvm/lib/Support/Signals.cpp:44:0
> #3 0x0000000002a953a8 SignalHandler(int)
> /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:254:0
> #4 0x00007fe358d3dd10 __restore_rt
> (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10)
> #5 0x00000000011fe489 llvm::iplist<llvm::Instruction,
> llvm::SymbolTableListTraits<llvm::Instruction>
> >::insert(llvm::ilist_iterator<llvm::Instruction>, llvm::Instruction*)
> /home/pierre/Desktop/llvm/include/llvm/ADT/ilist.h:415:0
> #6 0x0000000002abc20d llvm::ReI tried to clone the current instruction
> to not modify the iterator but the ReplaceInstWithInst will cause
> troublesplaceInstWithInst(llvm::SymbolTableList<llvm::Instruction>&,
> llvm::ilist_iterator<llvm::Instruction>&, llvm::Instruction*)
> /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:198:0
> #7 0x0000000002abc2a5 llvm::ReplaceInstWithInst(llvm::Instruction*,
> llvm::Instruction*)
> /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:210:0
>
> Any idea on what could be the cause of the null pointer and how to
> avoid it?
>
> Thanks a lot for your time!
> Pierre
>
>
> On 20 June 2016 at 15:45, John Criswell <jtcriswel at gmail.com
> <mailto:jtcriswel at gmail.com>> wrote:
>
> On 6/20/16 6:17 AM, Pierre Gagelin via llvm-dev wrote:
>> 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.
>>
>> 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);
>>
>> 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?
>
> Do you have assertions enabled? If so, is the crash an assertion
> failure and, if so, which assertion is failing? It's nearly
> impossible to tell what the problem is just by knowing that it is
> crashing.
>
>>
>> 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?
>
> Yes. You need to place the new call instruction within the same
> basic block as the old call instruction. Placing it right before
> the old call instruction is a good place.
>
> The code that Ashutosh provided is what I'd use to do what you're
> doing.
>
> Regards,
>
> John Criswell
>
>>
>> Thanks for your help,
>> Pierre
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org <mailto:llvm-dev at 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
>
>
--
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160621/e3ed6c3e/attachment.html>
More information about the llvm-dev
mailing list