我希望能够读取(解析)保存在文本文件中的LLVM IR代码,并向其中添加一些自己的代码。我需要一些例子来展示如何使用LLVM提供的库来完成这个目的。所以,基本上我想要做的是从文本文件中将IR代码读入内存(也许LLVM库会将其表示为AST形式,我不知道),进行修改,例如在AST中添加一些节点,最后将AST写回IR文本文件。
虽然我需要读取和修改IR代码,但如果有人能够提供或引用一些仅读取(解析)它的示例,我将不胜感激。
首先澄清一个明显的误解: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 并将其写回。
(*) LLVM 中没有 AST 表示 IR,因为它是一种类似汇编的简单语言。如果你往上走一步,到达 C 或 C++,你可以使用 Clang 将其解析为 AST,并在 AST 级别进行操作。然后,Clang 知道如何从其 AST 生成 LLVM IR。但是,你必须从 C/C++ 开始,而不是 LLVM IR。如果你只关心 LLVM IR,那就忘记 AST 吧。
Opt工具接收LLVM IR代码,对其运行一个Pass,然后在另一端输出转换后的LLVM IR。
最容易开始编写的是lib\Transforms\Hello\Hello.cpp。修改它,使用源文件作为输入通过opt运行,检查输出。
除此之外,编写Pass的文档非常好。