如何删除未使用的basicblocks llvm

如何删除未使用的basicblocks llvm,llvm,Llvm,我正在尝试从llvm中间代码中删除未使用的块 首先,通过从条目basicblock开始并从终止符指令中添加所有basicblock后续项,我构建了一个可访问basicblock的集合: bbset.insert(bbterm->getSuccessor(i)); 之后,我遍历无法访问的BasicBlock,并使用 DeleteDeadBlock(bb); 来自Utils/BasicBlockUtils.cpp 这是可行的,但在某些情况下,我会出错。以下是堆芯转储: opt: /home

我正在尝试从llvm中间代码中删除未使用的块

首先,通过从条目basicblock开始并从终止符指令中添加所有basicblock后续项,我构建了一个可访问basicblock的集合:

bbset.insert(bbterm->getSuccessor(i));
之后,我遍历无法访问的BasicBlock,并使用

DeleteDeadBlock(bb);
来自Utils/BasicBlockUtils.cpp

这是可行的,但在某些情况下,我会出错。以下是堆芯转储:

opt: /home/user/llvm-3.3.src/lib/Transforms/Utils/BasicBlockUtils.cpp:38: void llvm::DeleteDeadBlock(llvm::BasicBlock*): Assertion `(pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) && "Block is not dead!"' failed.
0  opt             0x0000000001756825 llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1  opt             0x0000000001756aa2
2  opt             0x000000000175651e
3  libpthread.so.0 0x00007fe1fe76dbb0
4  libc.so.6       0x00007fe1fdbaef77 gsignal + 55
5  libc.so.6       0x00007fe1fdbb25e8 abort + 328
6  libc.so.6       0x00007fe1fdba7d43
7  libc.so.6       0x00007fe1fdba7df2
8  opt             0x000000000138b004 llvm::DeleteDeadBlock(llvm::BasicBlock*) + 139
9  opt             0x0000000000d49c2e
10 opt             0x0000000001652942 llvm::FPPassManager::runOnFunction(llvm::Function&) + 290
11 opt             0x0000000001652ab2 llvm::FPPassManager::runOnModule(llvm::Module&) + 84
12 opt             0x0000000001652dd0 llvm::MPPassManager::runOnModule(llvm::Module&) + 502
13 opt             0x00000000016533a0 llvm::PassManagerImpl::run(llvm::Module&) + 244
14 opt             0x00000000016535ab llvm::PassManager::run(llvm::Module&) + 39
15 opt             0x00000000008c6cb6 main + 5698
16 libc.so.6       0x00007fe1fdb99de5 __libc_start_main + 245
17 opt             0x00000000008b8a39

你知道问题出在哪里吗?

这不是一个segfault,这是一个断言错误,它告诉你问题所在:前置列表不是空的。之所以出现此断言错误,是因为
DeleteDeadBlock
验证要删除的块没有直接的前导(除了它本身)

然而,该测试并不意味着该块是活动的;例如,在此场景中(假设直线是向下的箭头):

B和D都是死的,但是如果您尝试在B之前删除D,您将得到断言,因为D有一个前置(它本身不是)

如何解决这个问题?您可以执行以下操作之一:

  • 按拓扑顺序处理块
  • 从要删除的块中删除所有前置程序(例如,用
    不可访问的
    指令替换所有前置程序的终止符)
    
    • 您还可以先对所有标识为死块的块执行此操作,然后按任意顺序删除它们

  • 你可以用。它从入口块开始,对基本块执行深度优先搜索。这有助于识别“活动”块,这些块在删除“已死亡”的前辈后将变为“已死亡”。

    Oak,删除这些块后,我收到一些phinode指令问题。例如,在删除块%1之后,phi ins被替换为%x=phi i32[x,%label],[number,%0],我得到“PHINode应该为其父基本块的每个前置块都有一个条目!”因为%0与phi指令无关。您知道问题出在哪里吗?@gg.kaspersky每当您断开两个基本块(活动或不活动)时,您必须更新后续块的phi节点<代码>PHINode::removeIncomingValue
    可以在这里帮助您。
    entry
     /
    A   B
    |   |
    C   D
     \ /
      E