insertions with inst_iterators?

I am looping through all instructions in a Function and depending on
what I found I may or may not insert code. Despite the fact that I'm
only actually inserting *before* instruction I have a infinite loop
when I do something like below. For awhile it was simple enough to
just increment i enough times but now I need something better.

for(inst_iterator i = inst_begin(F); i != inst_end(F); ++i) {
...
// possible insertions of unknown size
...
}

I tried storing the storing the initial iterator and reverting back to
it(along with storing the next element) and I am still left with a
infinite loop. I see some discussion online about weather insertions
with iterators in C++ is allowed period, so what is the correct way to
do something like this in LLVM? This must be a common problem.

Thank you

Have you tried this?

for(inst_iterator i = inst_begin(F); i != inst_end(F); ) {
        Instruction *Inst = *i++;
        ...
        // possible insertions of unknown size
        ...
}

?

-bw

In general, this sort of thing depends on the container you’re iterating over. Different containers have different iterator invalidation semantics.

In this case, probably what you need to do is:

i = insert(i, …);

containers backed by contiguous sequences (like std::vector, and I assume the inst list - but I could be wrong) can invalidate all iterators on insertion (since they might need to reallocate memory - moving all the contents of the vector to a new, larger, buffer) - so generally they give you a new, valid iterator as a return result from any insertion operation.

(I assume your infinite loop that occured when you reset the iterator back to the start was caused by your own algorithm repeatedly inserting/restarting over and over again, and not by weirdness surrounding insertion iterator invalidation semantics)

[also note that the LLVM coding guidelines suggest storing end once & then using that in eahc loop iteration - you should do this, but you’ll hit iterator invalidation on insertion for the end iterator too, so you’ll have to re-initialize it after any insertion that might invalidate the end iterator]

  • David

That just gives me

"error: cannot convert ‘llvm::Instruction’ to ‘llvm::Instruction*’ in
initialization"

I'm guessing you ment

Instruction *Inst = &*i++;

Which also leaves me with a infinite loop

Thanks

When I'm iterating through I only directly add BitCastInsts and a
single CallInst(Im assuming the functions I also created are
elsewhere). Unfortunately it doesnt look like theres is a good way to
convert between the the iterator I and a CallInst *. Am I missing
something?

Thanks

When I’m iterating through I only directly add BitCastInsts and a
single CallInst(Im assuming the functions I also created are
elsewhere). Unfortunately it doesnt look like theres is a good way to
convert between the the iterator I and a CallInst *. Am I missing
something?

I’m not entirely sure how this relates to my explanation/suggestion.

How does your algorithm work? If you, say, add an extra CallInst every time you see a call, then you’re going to loop infinitely (inserting calls on the calls you just inserted, etc) unless you make sure you skip over everything you insert… that would be an algorithmic bug in your code, nothing to do with iterator invalidation semantics.

Once you’ve got that figured out, we can see what kind of loop you’ll need to write/how to deal with iterator invalidation.

  • David

I insert a function call to a function I generate right before when I
find something "interesting", a assignment on a function pointer or a
call on a function pointer. So I don't think its anything inherit with
my algorithm, just my use of iterators.

I attached the main body of my loop incase anyone feels like taking a
look. When it runs it prints "here"(line 138) endlessly.

Thanks again