Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

delete loop by eraseFromParent command in llvm

Tags:

llvm

*I would delete the Loop. I used the following code:

cout << "begin to delete loop" << endl;
for (Loop::block_iterator bi = L->block_begin(), bi2; bi != L->block_end(); bi = bi2) {
    bi2 = bi;
    bi2++;
    BasicBlock * BB = *bi;
    for (BasicBlock::iterator ii = BB->begin(), ii2; ii != BB->end(); ii= ii2) {
        ii2 = ii;
        ii2++;
        Instruction *inst = ii;
        inst->eraseFromParent();
    }
    BB->eraseFromParent();
}

But I get the following error:

Use still stuck around after Def is destroyed: %t1 = icmp sle i32 %t0, 9 opt: /home/llvm/src/lib/VMCore/Value.cpp:75: virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed. 0 opt 0x0848e569 Stack dump:

What suggestions do you have for solve this problem?*

like image 637
neda Avatar asked Oct 06 '11 07:10

neda


3 Answers

The solution of you problem is as follows:

make sure that for each instruction in the loop to drop all references, then simply erase all the BasicBlocks of the loop.

here is my sample code

for (Loop::block_iterator block = CPLoop->block_begin(), end = CPLoop->block_end(); block != end; block++) {
        BasicBlock * bb = *block;
        for (BasicBlock::iterator II = bb->begin(); II != bb->end(); ++II) {
            Instruction * insII = &(*II);
            insII->dropAllReferences();
        }
    }
    for (Loop::block_iterator block = CPLoop->block_begin(), end = CPLoop->block_end(); block != end; block++) {
        BasicBlock * bb = *block;
        bb->removeFromParent();
    }

I hope this helps

like image 66
Ramy Gad Avatar answered Dec 31 '22 20:12

Ramy Gad


What I write is only a guess, cause I am just starting with LLVM, but I hope it will be helpful.

In SSA form each instruction:

  • uses values provided by previously executed instructions
  • provides value (with is result of executing this instruction), which is used by others.

Those are called use-def and def-use chains.

If you try to remove instruction which result (a.k.a. "provided Value") is used by other instructions, than you break instruction chain.

You might be interested in iteratating over users of instruction you remove, using :

LLVM Programmer's Manual : Iterating over def-use & use-def chains. Thanks to that, you can iterate over users (u) of value provided by instruction, you want to remove (inst), and change their reference to another one (like inst: add u v --> add X v). Ones you make sure no one is using instruction you want to remove, remove it. (Depending if analysis passes are already made you might be required to let llvm pass manager know that CFG analysis needs to be updated - unless you update them by yourself).

like image 33
Grzegorz Wierzowiecki Avatar answered Dec 31 '22 18:12

Grzegorz Wierzowiecki


You are invalidating the iterator with the call to

inst->eraseFromParent();

Store all Instruction* in an std::vector or similar and batch delete them at the end of your pass.

This should solve your problem.

like image 44
sweisgerber.dev Avatar answered Dec 31 '22 20:12

sweisgerber.dev