[LLVMdev] how to correctly erase a bunch of instructions

395 views
Skip to first unread message

Frank Winter

unread,
Jun 20, 2015, 11:08:47 AM6/20/15
to llv...@cs.uiuc.edu
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

_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Daniel Berlin

unread,
Jun 20, 2015, 11:31:03 AM6/20/15
to Frank Winter, llv...@cs.uiuc.edu
On Sat, Jun 20, 2015 at 8:03 AM, Frank Winter <fwi...@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 :)
Reply all
Reply to author
Forward
0 new messages