2012-02-06 158 views
11

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

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

回答

24

首先,解决一个明显的误解: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。

+0

谢谢Eli。你的回答非常有帮助。 – MetallicPriest 2012-02-07 09:14:43

+0

抬起头,我认为它应该是“parseIRFile”,小写字母p。 http://llvm.org/docs/doxygen/html/IRReader_2IRReader_8h_source.html – user2027722 2016-03-30 01:54:12

+0

@ user2027722:是的,LLVM API的变化非常频繁,所以保持样本保持最新状态非常困难。我有一个Github的回购:https://github.com/eliben/llvm-clang-samples,我尽可能保持同步,这是更多的真相来源比随机SO回答 – 2016-03-30 14:41:07

1

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

2

这通常通过实施LLVM传递/变换来完成。这样你就不必解析IR了,因为LLVM会为你做,而且你将在面向OO的内存中表示IR。

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

+0

这将是我最终会做的。但是现在,由于我处于学习阶段,我希望能够在文本文件中看到IR。 – MetallicPriest 2012-02-06 21:54:41

+3

我没有看到问题。大多数LLVM工具都可以读取/写入IR的文本表示。特别是,要发出文本表示,请将-S开关添加到您的命令行中。 (另外,请始终记住二进制和文本表示是完全相同的)。 – CAFxX 2012-02-06 21:59:54

1

Opt工具采用llvm IR代码,在其上运行一遍,然后在另一侧吐出已转换的llvm IR。

最容易开始黑客行为是lib \ Transforms \ Hello \ Hello.cpp。对它进行破解,通过选择源文件作为输入,检查输出。

除此之外,写入通行证的文档确实相当不错。

1

如上所述,最好的方法来写一个通行证。但是,如果您只是简单地遍历指令并使用LLVM提供的InstVisitor类进行操作。这是一个实现访问者模式的类。这对用户来说是非常直接的,所以如果你想避免学习如何实现通行证,你可以诉诸于此。