如何让clang编译成llvm IR

pyt*_*nic 135 c llvm clang

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

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

Eli*_*sky 185

给出一些C/C++文件foo.c:

> clang -S -emit-llvm foo.c
Run Code Online (Sandbox Code Playgroud)

生成foo.ll哪个是LLVM IR文件.

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

> clang -cc1 foo.c -emit-llvm
Run Code Online (Sandbox Code Playgroud)

foo.ll与IR一起生产.-cc1添加了一些很酷的选项-ast-print.查看-cc1 --help更多详细信息.


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

> llc foo.ll
Run Code Online (Sandbox Code Playgroud)

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

  • @meawoppl:-S像在gcc中说发出文本汇编而不是汇编二进制 (11认同)
  • -S在这做什么? (5认同)
  • @cache:将每个编译成自己的IR文件,然后使用LLVM链接器进行组合 (4认同)

Chr*_*oph 20

使用

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
Run Code Online (Sandbox Code Playgroud)

  • 我建议保持扩展意义不变.IOW,`.o`应该引用二进制目标文件,`.s`引用汇编文件,其他东西(按照惯例`.ll`)引用LLVM IR文件.否则很容易混淆.Clang/LLVM现在没有自己的二进制对象链接器(尽管其中一个正在开发中).LLVM链接器`llvm-ld`只是将几个IR文件连接成一个 (9认同)
  • @EliBendersky:在文件扩展名方面你是正确的 - 如果使用 `.bc`,clang 前端实际上会做正确的事情;另外,请记住“llvm-ld”可以充当系统工具链的前端,即我之前使用“llvm-ld -native”的答案应该按预期工作...... (2认同)

Jer*_*wen 18

如果您有多个源文件,您可能实际上希望使用link-time-optimization为整个程序输出一个bitcode文件.给出的其他答案将导致您最终得到每个源文件的bitcode文件.

相反,您希望使用链接时优化进行编译

clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
Run Code Online (Sandbox Code Playgroud)

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

clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
Run Code Online (Sandbox Code Playgroud)

这为您提供一个已编译的程序和与之对应的bitcode(program.bc).然后,您可以以任何您喜欢的方式修改program.bc,并通过执行任何时候重新编译修改后的程序

clang program.bc -o program
Run Code Online (Sandbox Code Playgroud)

虽然请注意,您需要再次在此步骤中包含任何必要的链接器标志(对于外部库等).

请注意,您需要使用黄金链接器才能工作.如果要强制clang使用特定链接器,请在计算机上某处名为"fakebin"的特殊目录中为名为"ld"的链接器创建符号链接,并添加选项

-B/home/jeremy/fakebin
Run Code Online (Sandbox Code Playgroud)

到上面的任何链接步骤.


rot*_*lup 12

你看过clang文档了吗?你可能正在寻找-emit-llvm.


Kik*_*dez 12

如果你有多个文件,而且你不想输入每个文件,我建议你按照这些简单的步骤(我使用clang-3.8但你可以使用任何其他版本):

  1. 生成所有.ll文件

    clang-3.8 -S -emit-llvm *.c
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将它们链接成一个

    llvm-link-3.8 -S -v -o single.ll *.ll
    
    Run Code Online (Sandbox Code Playgroud)
  3. (可选)优化代码(可能是一些别名分析)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
    
    Run Code Online (Sandbox Code Playgroud)
  4. 生成程序集(生成optimised.s文件)

    llc-3.8 optimised.ll
    
    Run Code Online (Sandbox Code Playgroud)
  5. 创建可执行文件(命名a.out)

    clang-3.8 optimised.s
    
    Run Code Online (Sandbox Code Playgroud)