*我会删除循环。我使用了以下代码:
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 堆栈转储:
您有什么建议来解决这个问题?*
答案 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)中进行对抗?