Daniel Liew
2013-Sep-15 08:59 UTC
[LLVMdev] Are instr_iterators invalidated when function inlining is performed?
I just realised I forgot to reply to this. Thanks for advise, it's good to know. Thanks, Dan Liew. On 30 August 2013 16:25, David Blaikie <dblaikie at gmail.com> wrote:> 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 llvm.cs.uiuc.edu >> lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Apparently Analagous Threads
- [LLVMdev] Are instr_iterators invalidated when function inlining is performed?
- [LLVMdev] Help with LLVM Bitcode function inlining and duplicating debug information on instructions
- [LLVMdev] MCJIT versus getLazyBitcodeModule?
- [LLVMdev] Inlining bitcast functions...
- [LLVMdev] Inlining bitcast functions...