如何删除 LLVM 中的不规则分支?
how to remove an unconditonal branch in LLVM?
我想从函数中删除一个多余的无条件分支。在下面的示例中,我想删除br label %26
并将它们合并到一个基本块中。
; <label>:9: ; preds = %7
%10 = fadd float %5, %8
%11 = fmul float %5, %8
%12 = fadd float %10, %11
%13 = fdiv float %5, %8
%14 = fadd float %13, %12
br label %15
; <label>:15: ; preds = %9
br label %26
我试图通过以下方式做到这一点,
for(auto it1 = F.begin(); it1 != F.end(); it1++){
BasicBlock& bb = *it1;
auto BI = dyn_cast<BranchInst>(bb.getTerminator());
if(BI && BI->isUnconditional() && bb.size() == 1){
for (BasicBlock *pred : predecessors(&bb)) {
auto predBI = dyn_cast<BranchInst>(pred->getTerminator());
if(predBI && predBI->isUnconditional()){
predBI->setSuccessor(0, bb.getSingleSuccessor());
BI->dropAllReferences();
BI->removeFromParent();
}
}
}
}
但这给了我一个错误。我正在使用 LLVM 6.0.0
#0 0x000056166a0bcfba (opt+0x11fbfba)
#1 0x000056166a0bb01e (opt+0x11fa01e)
#2 0x000056166a0bb16c (opt+0x11fa16c)
#3 0x00007f2d009cb890 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12890)
#4 0x0000561669b8ce4c (opt+0xccbe4c)
#5 0x00007f2cff43bdb1 mergeBlocks /home/charitha/workspace/rocm/hcc/compiler/lib/Transforms/lcs/MergePass.cpp:103:0
#6 0x00007f2cff43bdb1 (anonymous namespace)::SkeletonPass::runOnFunction(llvm::Function&) /home/charitha/workspace/rocm/hcc/compiler/lib/Transforms/lcs/MergePass.cpp:51:0
#7 0x0000561669bb4f5a (opt+0xcf3f5a)
#8 0x0000561669bb5003 (opt+0xcf4003)
#9 0x0000561669bb4b14 (opt+0xcf3b14)
#10 0x000056166924c765 (opt+0x38b765)
#11 0x00007f2cff65fb97 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b97)
#12 0x000056166929f5fa (opt+0x3de5fa)
您可能对llvm/Transform/Utils/BasicBlockUtils.h
文件中定义的实用程序函数感兴趣llvm::MergeBlockIntoPredecessor()
。
见 https://llvm.org/doxygen/BasicBlockUtils_8h.html
我在llvm/Transform/Utils/BasicBlockUtils.h
中重用了代码,它起作用了。
for(auto it1 = F.begin(); it1 != F.end(); it1++){
BasicBlock* BB = &*it1;
auto BI = dyn_cast<BranchInst>(BB->getTerminator());
if(BI && BI->isUnconditional() && BB->size() == 1){
// code taken from BasicBlockUtils
auto PredBB = BB->getUniquePredecessor();
if(PredBB){
PredBB->getInstList().pop_back();
BB->replaceAllUsesWith(PredBB);
PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
if (!PredBB->hasName())
PredBB->takeName(BB);
it1 = BB->eraseFromParent();
}
}
}
相关文章:
- IPC使用多个管道和分支进程来运行Python程序
- 如何删除peer if else分支中的冗长句子
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 如何正确地将分支添加到已存在的树中
- 如何将分支添加到已存在的TTree:ROOT
- 如何删除 LLVM 中的不规则分支?
- 如果以下行不包含决策或分支,GDB 无法单步跳过函数
- 函数指针与条件分支
- 分支未在 Linux 上采用
- 如何删除分支因子不一致的树,最大为 30,40
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 更改 git 分支名称后,在项目的 Visual Studio 代码中丢失智能感知(建议,转到定义C++
- 条件分支评估
- 是否可以使用函数指针数组来删除分支
- 基于派生类型的编译时行为分支
- L 系统树无法正确分支
- Antlr4 C++访问模棱两可的分支
- 如何为不同的分支使用不同的 Xcode 版本(或具有不同 Clang 版本的最新 Xcode)?
- 如何防止特定的QTreeView分支被拖动?