[LLVMdev] Are instr_iterators invalidated when function inlining is performed?
Daniel Liew
daniel.liew at imperial.ac.uk
Sun Sep 15 01:59:06 PDT 2013
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 http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
More information about the llvm-dev
mailing list