通过llvm中的eraseFromParent命令删除循环

时间:2011-10-06 07:39:26

标签: llvm

*我会删除循环。我使用了以下代码:

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();
}

但是我收到以下错误:

在销毁Def后仍然使用:%t1 = icmp sle i32%t0,9 opt:/home/llvm/src/lib/VMCore/Value.cpp:75:virtual llvm :: Value :: ~Value():断言`use_empty()&amp;&amp; “当价值被破坏时,使用仍然存在!”'失败了。 0选择0x0848e569 堆栈转储:

您有什么建议来解决这个问题?*

4 个答案:

答案 0 :(得分:6)

你问题的解决方案如下:

确保循环中的每条指令都删除所有引用,然后简单地擦除循环的所有BasicBlock。

这是我的示例代码

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();
    }

我希望这会有所帮助

答案 1 :(得分:3)

我写的只是猜测,因为我刚开始使用LLVM,但我希望它会有所帮助。

SSA中形成每条指令:

  • 使用先前执行的指令提供的值
  • 提供值(由执行此指令的结果),由其他人使用。

这些被称为use-def和def-use链。

如果你试图删除其他指令使用的结果(a.k.a。“提供的值”)的指令,那么你就会破坏指令链。

您可能对使用以下内容删除指令的用户感兴趣:

LLVM Programmer's Manual : Iterating over def-use & use-def chains。多亏了这一点,您可以迭代指令提供的值的用户( u ),您想删除( inst ),并将其引用更改为另一个(如< em> inst:添加uv - &gt;添加X v )。你确定没有人使用你想删除的指令,删除它。 (根据是否已经进行了分析,您可能需要让llvm通过经理知道需要更新CFG分析 - 除非您自己更新)。

答案 2 :(得分:2)

您通过调用

使迭代器无效
inst->eraseFromParent();

将所有Instruction*存储在std::vector或类似内容中,并在传递结束时批量删除它们。

这可以解决您的问题。

答案 3 :(得分:0)

有一种“删除”循环的替代解决方案:只需永久禁用它即可。即从某事物修改IR代码。像这样:

  ...
  br label %loop
loop:
  <loop body>
  br i1 %exitcond, label %exit, label %loop
exit:
  ...
某事。像这样:

...
  br i1 0, label %loop, label %exit
loop:
  <loop body>
  br i1 %exitcond, label %exit, label %loop
exit:
  ...

您可能会在生成的IR上运行优化(例如死代码消除),那么为什么要与所有对循环的引用(例如在LoopInfo s或ValueMap s)中进行对抗?