如何删除 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()
效用函数感兴趣。
我重复使用了 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();
}
}
}
我想从函数中删除多余的无条件分支。在下面的示例中,我想删除 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()
效用函数感兴趣。
我重复使用了 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();
}
}
}