[llvm-dev] function call replacement

Pierre Gagelin via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 21 01:10:04 PDT 2016


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. 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> 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 listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
> --
> John Criswell
> Assistant Professor
> Department of Computer Science, University of Rochesterhttp://www.cs.rochester.edu/u/criswell
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160621/9bed76a0/attachment.html>


More information about the llvm-dev mailing list