【问题标题】:Parsing and Modifying LLVM IR code解析和修改 LLVM IR 代码
【发布时间】:2012-02-06 21:13:46
【问题描述】:

我想读取(解析)LLVM IR 代码(保存在文本文件中)并向其中添加一些我自己的代码。我需要一些这样做的例子,也就是说,这是如何通过使用 LLVM 提供的库来完成的。所以基本上我想要的是将IR代码从文本文件读入内存(也许LLVM库以AST形式表示它,我不知道),进行修改,比如在AST中添加更多节点,然后最后写在 IR 文本文件中返回 AST。

虽然我需要阅读和修改 IR 代码,但如果有人能提供或参考一些刚刚阅读(解析)它的示例,我将不胜感激。

【问题讨论】:

    标签: c++ c llvm


    【解决方案1】:

    首先,纠正一个明显的误解:LLVM 是一个用于操作 IR 格式代码的框架。看不到 AST (*) - 您读取 IR,转换/操作/分析它,然后将 IR 写回。

    阅读 IR 真的很简单:

    int main(int argc, char** argv)
    {
        if (argc < 2) {
            errs() << "Expected an argument - IR file name\n";
            exit(1);
        }
    
        LLVMContext &Context = getGlobalContext();
        SMDiagnostic Err;
        Module *Mod = ParseIRFile(argv[1], Err, Context);
    
        if (!Mod) {
            Err.print(argv[0], errs());
            return 1;
        }
    
        [...]
      }
    

    此代码接受文件名。这应该是一个 LLVM IR 文件(文本)。然后它继续将其解析为Module,它表示 LLVM 内部内存格式的 IR 模块。然后可以使用 LLVM 拥有的各种通行证进行操作,或者您自己添加。查看 LLVM 代码库中的一些示例(例如 lib/Transforms/Hello/Hello.cpp)并阅读此内容 - http://llvm.org/docs/WritingAnLLVMPass.html

    将 IR 吐回到文件中更加容易。 Module 类只是将自身写入流:

     some_stream << *Mod;
    

    就是这样。

    现在,如果您对想要对 IR 代码进行的具体修改有任何具体问题,那么您真的应该问一些更集中的问题。我希望这个答案能告诉你如何解析 IR 并将其写回。


    (*) IR 在 LLVM 中没有 AST 表示,因为它是一种简单的类汇编语言。如果您更上一层楼,使用 C 或 C++,您可以使用 Clang 将其解析为 AST,然后在 AST 级别进行操作。然后,Clang 知道如何从其 AST 生成 LLVM IR。但是,您必须从这里开始使用 C/C++,而不是 LLVM IR。如果你只关心 LLVM IR,那就别管 AST。

    【讨论】:

    【解决方案2】:

    这通常通过实现 LLVM 传递/转换来完成。这样,您根本不必解析 IR,因为 LLVM 会为您完成它,并且您将在 IR 的面向对象的内存表示中进行操作。

    This 是编写 LLVM pass 的入口点。然后,您可以查看与 LLVM 捆绑在一起的任何已实现的标准通行证(查看 lib/Transforms)。

    【讨论】:

    • 这就是我最终要做的。但此时,由于我处于学习阶段,我希望能够在文本文件中看到 IR。
    • 我没有看到问题。大多数 LLVM 工具可以读/写 IR 的文本表示。特别是,要发出文本表示,请将 -S 开关添加到命令行。 (另外,永远记住二进制和文本表示是绝对等价的)。
    【解决方案3】:

    Opt 工具获取 llvm IR 代码,对其运行一次传递,然后在另一侧输出转换后的 llvm IR。

    最容易开始黑客攻击的是 lib\Transforms\Hello\Hello.cpp。破解它,使用您的源文件作为输入运行 opt,检查输出。

    除此之外,写pass的文档真的很不错。

    【讨论】:

      【解决方案4】:

      最简单的方法是查看现有工具之一并从中窃取代码。在这种情况下,您可能需要查看 llc 的源代码。它可以采用位码或 .ll 文件作为输入。你可以以任何你想要的方式修改输入文件,然后如果你想要一个文本文件,则使用类似于 llvm-dis 中的代码的东西写出文件。

      【讨论】:

        【解决方案5】:

        如上所述最好的方法就是写一个pass。但是,如果您想简单地遍历指令并使用 LLVM 提供的 InstVisitor 类做一些事情。它是一个实现访问者模式以获取指令的类。这对用户来说非常直接,所以如果你想避免学习如何实现通行证,你可以求助于它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-07
          • 2012-03-13
          • 2012-01-23
          • 1970-01-01
          相关资源
          最近更新 更多