how to correctly erase a bunch of instructions

I have a basic block BB and a SetVector<Value*> for_erasure. The set vector contains the instructions which should be erased from BB but they are in no particular order. Thus something like this

for ( Value* v: for_erasure ) {
     if (Instruction *Inst = dyn_cast<Instruction>(v)) {
       Inst->dropAllReferences();
       Inst->eraseFromParent();
     }
   }

results in

While deleting: float* %
Use still stuck around after Def is destroyed: <badref> = getelementptr

I was thinking of reverse iterating through the basic block and testing each instruction whether it is contained in the set vector. I have however no success with it (segfaults). I think it's because erasing the instruction invalidates the (reverse) iterator.

Can I somehow declare instructions as dead and then happily erase them (so that the above error's not happening)?

What's the standard way of erasing instructions in the given case? Some pseudo-codewould be appreciated.

Thanks
Frank

I have a basic block BB and a SetVector<Value*> for_erasure. The set vector
contains the instructions which should be erased from BB but they are in no
particular order. Thus something like this

for ( Value* v: for_erasure ) {
    if (Instruction *Inst = dyn_cast<Instruction>(v)) {
      Inst->dropAllReferences();
      Inst->eraseFromParent();
    }
  }

results in

While deleting: float* %
Use still stuck around after Def is destroyed: <badref> = getelementptr

You need to replace all the uses with something. It's not enough to
drop all references, dropping all refs just makes badrefs, as you've
seen :slight_smile:

If the remaining uses are in, say, unreachable blocks, or whatever,
the right thing to do is to replace the remaining uses with undef.

I was thinking of reverse iterating through the basic block and testing each
instruction whether it is contained in the set vector. I have however no
success with it (segfaults). I think it's because erasing the instruction
invalidates the (reverse) iterator.

I fixed this in trunk. The eraseFromParent()'s now return an
instruction you can use to create an iterator.
IE, the following now works:

  for (auto I = BB.rbegin(), E = BB.rend(); I
!= E; ++I) {

    Instruction& inst = *I;
     I = inst.eraseFromParent();
}

Can I somehow declare instructions as dead and then happily erase them (so
that the above error's not happening)?

The above error is simply because you haven't replaced all the uses.
So replace them :slight_smile:

What's the standard way of erasing instructions in the given case? Some
pseudo-codewould be appreciated.

The following should fix the above, if you insert it before the eraseFromParent

if (!Inst->use_empty())
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));

Obviously, you should examine why it still has uses hanging around,
and whether you care about them, before you apply this :slight_smile: