【问题标题】:LLVM Pass : DELETE all branch in the IR occurs errorsLLVM Pass : DELETE all branch in IR 发生错误
【发布时间】:2017-09-06 11:02:21
【问题描述】:

我想通过 LLVM pass 删除 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 之类的错误

【问题讨论】:

  • 我不太确定使用什么容器来存储指令,但这可能与您实质上是通过在迭代同一容器时进行擦除来修改基本块中的指令容器这一事实有关?

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


【解决方案1】:

在使用基于范围的 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;
}

【讨论】:

    猜你喜欢
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-05-19
    • 2011-08-13
    • 1970-01-01
    • 2016-12-24
    • 2013-11-17
    相关资源
    最近更新 更多