Daniel Liew
2013-Aug-30 14:53 UTC
[LLVMdev] Are instr_iterators invalidated when function inlining is performed?
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? 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
David Blaikie
2013-Aug-30 15:25 UTC
[LLVMdev] Are instr_iterators invalidated when function inlining is performed?
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
Seemingly Similar 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] Inlining bitcast functions...
- [LLVMdev] Inlining bitcast functions...
- [LLVMdev] Wondering how best to run inlining on a single function.