如何使clang编译成llvm IR

我想要clang编译我的C/C++代码到LLVM字节码而不是二进制可执行文件。 我怎样才能做到这一点? 如果我得到LLVM字节码,我怎么能把它进一步编译成二进制可执行文件。

基本上我想在编译成二进制可执行文件之前将我自己的一些代码添加到LLVM字节码中。

给定一些C / C ++文件foo.c

 > clang -S -emit-llvm foo.c 

生成foo.ll ,这是一个LLVM IR文件。

-emit-llvm选项也可以直接传递给编译器的前端,而不是通过-cc1传递给驱动程序:

 > clang -cc1 foo.c -emit-llvm 

用IR产生foo.ll -cc1添加了一些很酷的选项,如-ast-print 。 查看-cc1 --help了解更多详情。


要进一步编译LLVM IR,请使用llc工具:

 > llc foo.ll 

使用程序集生成foo.s (默认为运行它的机器体系结构)。 llc是LLVM工具之一 – 这是它的文档 。

使用

 clang -emit-llvm -o foo.bc -c foo.c clang -o foo foo.bc 

如果您有多个源文件,您可能实际上想要使用链接时优化为整个程序输出一个位码文件。 给出的其他答案将导致你最终为每个源文件的位码文件。

相反,您要编译链接时间优化

 clang -flto -c program1.c -o program1.o clang -flto -c program2.c -o program2.o 

并为最后的链接步骤添加参数-Wl,-plugin-opt = also-emit-llvm

 clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program 

这给你一个编译的程序和相应的位码(program.bc)。 然后你可以用你喜欢的方式修改program.bc,然后在任何时候重新编译修改过的程序

 clang program.bc -o program 

不过要注意,在这个步骤中你需要包含任何必要的链接器标志(对于外部库等)。

请注意,您需要使用黄金链接器才能正常工作。 如果要强制使用特定的链接器,请在计算机上的某个特定目录“fakebin”中创build一个名为“ld”的链接器的符号链接,然后添加选项

 -B/home/jeremy/fakebin 

到上面的任何链接步骤。

你读过clang文件吗? 你可能正在寻找-emit-llvm

如果你有多个文件,你不想input每个文件,我build议你遵循这些简单的步骤(我使用的是clang-3.8但你可以使用任何其他版本):

  1. 生成所有.ll文件

     clang-3.8 -S -emit-llvm *.c 
  2. 将它们链接成一个单一的

     llvm-link-3.8 -S -v -o single.ll *.ll 
  3. (可选)优化您的代码(也许一些别名分析)

     opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll 
  4. 生成程序集(生成一个optimised.s文件)

     llc-3.8 optimised.ll 
  5. 创build可执行文件(名为a.out

     clang-3.8 optimised.s