LLVM Pass:删除IR中的所有分支发生错误

时间:2017-09-06 11:02:21

标签: llvm llvm-clang llvm-ir llvm-c++-api

我想通过LLVM传递删除IR代码中的分支指令。

以下代码是我的函数传递(Github):

virtual bool runOnFunction(Function &F) {
    for (auto &B : F) {
        for (auto &I : B) {
            auto op_name = I.getOpcodeName();
            if(strcmp(op_name, "br")==0) {
                I.eraseFromParent();
            }
        }
    }
    return true;
}

成功编译了Function Pass,但是当我在test.c上使用它时,会出现Pastebin

之类的错误

1 个答案:

答案 0 :(得分:0)

使用基于for循环的范围迭代修改容器将不起作用,因为不会重新评估结束表达式。此外,根据容器的不同,您可能会使正在删除的元素的迭代器无效。

cppreference解释了基于for循环的范围,直到C ++ 17为止:

{
    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr;
         // __end not reevaluated!
         __begin != __end; ++__begin) {

        range_declaration = *__begin;
        loop_statement

    }
}

eraseFromParent将删除基本块中的指令,因此在这种情况下您不能使用基于范围的for循环。然而,LLVM开发人员已经将它返回到下一个元素的迭代器,您可以使用它来继续循环。

virtual bool runOnFunction(Function &F) {
    for (auto &B : F) {
        auto It = B.begin()
        // we modify B, so we must reevaluate end()
        while(It != B.end()) {
            auto &I = *It;
            auto op_name = I.getOpcodeName();
            if(strcmp(op_name, "br")==0) {
                // we continue with the next element
                It = I.eraseFromParent();
            } else {
                ++It;
            }
        }
    }
    return true;
}