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

ned*_*eda 5 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();
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

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

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

Ram*_*Gad 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();
    }
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助


Grz*_*cki 3

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

SSA形式中,每条指令:

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

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

如果您尝试删除其结果(也称为“提供的值”)被其他指令使用的指令,那么您就会破坏指令链。

您可能有兴趣迭代您删除的指令的用户,使用:

LLVM 程序员手册:迭代 def-use 和 use-def 链。多亏了这一点,您可以迭代由指令提供的值的用户(u),您想要删除(inst),并将其引用更改为另一个(例如inst:add uv --> add X v)。如果您确定没有人在使用您想要删除的指令,请将其删除。(根据分析通道是否已完成,您可能需要让 llvm 通道管理器知道 CFG 分析需要更新 - 除非您自己更新)。