[LLVMdev] Are instr_iterators invalidated when function inlining is performed?
David Blaikie
dblaikie at gmail.com
Fri Aug 30 08:25:36 PDT 2013
On Fri, Aug 30, 2013 at 7:53 AM, Daniel Liew <daniel.liew at imperial.ac.uk> wrote:
> Hi,
>
> I'm trying to write a small piece of code that inlines all calls to a
> particular function. The codes is as follows
>
> Function* klee_check_divF = module->getFunction("klee_div_zero_check");
> assert(klee_check_divF != 0 && "Failed to find klee_div_zero_check function");
> // Hack inline checks
> for (Module::iterator f = module->begin(), fe = module->end(); f != fe; ++f) {
> for (inst_iterator i=inst_begin(f), ie = inst_end(f); i != ie; ++i) {
> if ( CallInst* ci = dyn_cast<CallInst>(&*i) )
> {
> if ( ci->getCalledFunction() == klee_check_divF)
> {
> std::cout << "Trying to inline klee_div_zero_check" << std::endl;
> InlineFunctionInfo IFI(0,0);
> if (InlineFunction(ci,IFI))
> {
> std::cout << "Did inline" << std::endl; std::cout.flush();
> }
> else
> std::cout << "Failed to inline" << std::endl;
> }
> }
>
> }
> }
>
> The problem I'm finding is after doing the first inline of a call
> (using InlineFunction(ci,IFI) ) the program then SEGFAULTS which I
> believe is happening because the instruction iterator is made invalid
> when I do inlining (looking in gdb one of its fields I see is
> NodePtr=0x0 ).
>
> Is this normal behaviour?
In many situations in C++ this is normal behavior (inlining
presumably, removes the instruction you pass it - because there's no
longer a call) - if you remove an element from a sequence (eg: using
std::list<T>::erase(iterator)) the current iterator becomes invalid.
The common idiom to deal with this is to copy the iterator and
increment the copy before the operation that invalidates the iterator:
instead of:
for (iter i = begin(); i != end(); ++i) {
if (cond)
erase(i); // next increment will be invalid
}
one would write:
for (iter i = begin(); i != end(); ) {
if (cond) {
iter t = i;
++i;
erase(t);
} else {
++i;
}
}
> If so what is the correct way to implement
> what I'm trying to do?
>
> For now I'm going to implement the code so that it instead collects a
> set of pointers to all the CallInstr of interest whilst iterating
> through the module. Then after iterating through the module, iterate
> through the set of collected CallInstr* and inline each one.
>
> Thanks,
> Dan Liew
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
More information about the llvm-dev
mailing list