如何使用llvm生成机器代码

时间:2012-11-19 23:27:38

标签: c++ llvm machine-code

我目前正在使用llvm编写一个编译器项目。我已经遵循了各种教程,以便我有一个解析器来创建语法树,然后使用提供的IRBuilder将树转换为llvm模块。

我的目标是创建一个可执行文件,我很困惑,接下来要做什么。我发现的所有教程都是创建llvm模块并使用Module.dump()打印出程序集。另外,我能找到的唯一文档是llvm开发人员,而不是项目的最终用户。

如果我想生成机器代码,接下来的步骤是什么? llvm-mc项目看起来可能会做我想要的,但我找不到任何类型的文档。

也许我期待自己会做一些事情。我的期望是我可以构建一个模块,然后会有一个我可以使用模块调用的API,并且将生成一个目标三元组和一个目标文件。我找到了关于生成JIT的文档和示例,我对此并不感兴趣。我正在寻找如何生成编译的二进制文件。

我正在研究OS X,如果这有任何影响。

4 个答案:

答案 0 :(得分:16)

使用llc -filetype=obj从IR发出可链接的目标文件。您可以查看llc的代码,以查看它发出此类代码的LLVM API调用。至少对于Mac OS X和Linux,以这种方式发出的对象应该非常好(即现在这不是“alpha质量”选项)。

然而,

LLVM不包含链接器(但是!)。因此,要将此对象文件实际链接到某个可执行文件或共享库,您需要使用系统链接器。请注意,即使您有一个由单个目标文件组成的可执行文件,也必须将后者链接起来。 LLVM社区中的开发人员正在研究LLVM的真实链接器,称为lld。您可以访问its page或搜索邮件列表存档以了解其进度。

答案 1 :(得分:15)

正如您可以在the llc guide上阅读的那样,确实只是生成程序集,然后“然后可以通过本机汇编程序和链接程序传递汇编语言输出以生成本机可执行文件” - 例如gnu汇编程序(as)和链接程序(ld)。

所以这里的主要答案是使用原生工具进行组装和链接

但是,通过llc直接从IR文件生成本机对象的实验性支持:

-filetype      - Choose a file type (not all types are supported by all targets):
    =asm         -   Emit an assembly ('.s') file
    =obj         -   Emit a native object ('.o') file [experimental]

或者您可以使用llvm-mc.s文件中汇总它:

-filetype      - Choose an output file type:
    =asm         -   Emit an assembly ('.s') file
    =null        -   Don't emit anything (for timing purposes)
    =obj         -   Emit a native object ('.o') file
但是,我不知道连接器。

此外,我建议查看tools/bugpoint/ToolRunner.h文件,该文件公开了一个包含llc的包装器和平台的本机C工具链,用于生成机器代码。从标题评论:

  

该文件公开了一个围绕平台C编译器的抽象,用于编译C和汇编代码。

答案 2 :(得分:5)

llvm-c/TargetMachine.h

中查看这些功能
/** Emits an asm or object file for the given module to the filename. This
  wraps several c++ only classes (among them a file stream). Returns any
  error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
  char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);

/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
  LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);

答案 3 :(得分:1)

要运行示例BrainF程序,请编译并运行:

echo ,. > test.bf
./BrainF test.bf -o test.bc
llc -filetype=obj test.bc
gcc test.o -o a.out
./a.out

然后键入单个字母并按Enter键。它应该将这封信回复给你。 (这是,.的作用。)

以上测试使用LLVM版本3.5.0。