Frank Winter
2015-Jun-20 15:03 UTC
[LLVMdev] 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
Daniel Berlin
2015-Jun-20 15:25 UTC
[LLVMdev] how to correctly erase a bunch of instructions
On Sat, Jun 20, 2015 at 8:03 AM, Frank Winter <fwinter at jlab.org> wrote:> 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 :) 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 :)> 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 :)> > Thanks > Frank > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev