【问题标题】:Using the LLVM linker to produce C code使用 LLVM 链接器生成 C 代码
【发布时间】:2015-08-12 08:48:04
【问题描述】:

我尝试使用以下命令从llvm-g++ 编译的 C++ 代码生成 C 代码:

llvm-g++ -emit-llvm -c ./example.cpp -o example.o
llc -march=c example.o

我在运行 Ubuntu (Linux 3.16.0-45-generic) 的机器上尝试了这些命令。

但是,LLVM 静态链接器没有将 C 代码写入标准输出,而是报告编译的文件无效:error: expected top-level entity

如何使用 LLVM 链接器生成 C 代码?

【问题讨论】:

    标签: c++ c linker llvm


    【解决方案1】:

    原来的 C 后端 (llvm-cbe) 在 3.1 (release notes) 中被删除,但是有这个 Julia 项目,resurrected LLVM "C Backend", with improvements,它复活了它。

    【讨论】:

      【解决方案2】:

      不幸的是,在 Ubuntu 系统上发出 LLVM 位码可能会有点痛苦,因为它们将 DragonEgg 作为默认前端 - 请参阅 this questionthis bugreport

      如果您对上面生成的文件执行file example.o,您会发现它实际上不是 LLVM IR 位码(它解释了错误):

      $ file example.o
      example.o: ELF 64-bit LSB  relocatable, x86-64, version 1 (SYSV), not stripped
      

      在 Ubuntu 系统上获取 LLVM IR 位码的最简单方法是使用 clang:

      $ clang -emit-llvm -c example.cpp -o example.o
      $ file example.o
      example.o: LLVM IR bitcode
      

      也就是说,在 LLVM 3.1 中删除了 C 后端(请参阅 release notesthis question)。正如您从 llc -version 的输出中看到的那样,它没有被列出,并且尝试使用它会在我的 Ubuntu 14.04 系统上出现以下错误:

      llc-3.4: error: invalid target 'c'.
      

      【讨论】:

        【解决方案3】:

        正如手册页所说:

        The llc command compiles LLVM source inputs
        into assembly language for a specified architecture.
        

        它不会对目标文件进行逆向工程以生成 C 文件(这是您想要实现的),这对我来说毫无意义。

        要了解支持哪些架构(大致意思是可以使用哪个 CPU):

         llc -version
        

        (您会注意到“C”不是架构)。

        如果您尝试将一段 C++ 代码重写为 C,最好的办法是手动完成。您需要在 C 中重写所有 C++ 特定的东西(类、异常、模板等),这将花费或多或少的时间,具体取决于 C++ 代码的复杂性。

        【讨论】:

        • OP 想要将 LLVM IR 位码转换为 C(注意 -emit-llvm 选项,它应该生成位码而不是目标文件)。它在早期版本中受支持(例如,参见this FAQ),但在 3.1 中删除了 C 后端 (release notes)。
        猜你喜欢
        • 2015-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-22
        • 2012-04-07
        相关资源
        最近更新 更多