【问题标题】:Compiler output language - LLVM IR vs C编译器输出语言 - LLVM IR 与 C
【发布时间】:2012-05-03 03:00:46
【问题描述】:

对于编写编译器,将 LLVM IR 与 C 用于目标语言的优缺点是什么?我知道两者都被使用了,我想如果我使用 clang 编译 C,最终的机器代码会是相似的。那么还有什么需要考虑的呢?

【问题讨论】:

    标签: compiler-construction code-generation llvm llvm-ir


    【解决方案1】:

    我已经将 LLVM IR 用于一些编译器后端,并且使用过使用 C 作为后端的编译器。我发现给 LLVM IR 带来优势的一件事是它是类型化的。在不从 LLVM 库中获取错误的情况下,很难做出完全格式错误的输出。

    在我看来,保持源代码和 IR 之间的密切关联以进行调试也更容易。

    此外,您还可以使用所有很酷的 LLVM 命令行工具来分析和处理前端发出的 IR。

    【讨论】:

    • 输入 IR 是什么意思?不也是 C 类型的吗?
    • 对,输入了 C。但是在您尝试编译 C 代码之前,您不会得到错误指示。使用 LLVM IR,您在生成 IR 时会收到错误指示。更容易调试。
    【解决方案2】:

    LLVM 优势:

    1. JIT - 您可以动态编译和运行代码。当然,C 也可以实现相同的功能(例如,使用嵌入式 tcc),但它的健壮性和可移植性要差得多。
    2. 您可以在生成的 IR 上运行自己的优化过程。
    3. 免费反射 - 使用 LLVM 检查生成的代码要容易得多。
    4. LLVM 库不像大多数 C 编译器那么大(当然,不包括 tcc)。

    LLVM 缺点:

    1. 代码不可移植,您必须根据您的目标稍微更改它。 LLVM 有一个可移植的子集,但它仍然是一种狡猾的做法。
    2. 对 C++ 库的运行时依赖可能有点问题。

    【讨论】:

    • 您忘记了:如果您想要 C 互操作(哪种语言不需要?),您必须自己编写所有那些讨厌的 C ABI,因为 llvm 本身并不能全部完成(它将工作拆分为 50 /50 铿锵声)
    【解决方案3】:

    我怀疑您是否可以在以 C 为目标时为您的语言实现适当的调试支持。

    【讨论】:

    • 这正是我一直在寻找这个线程的原因。我认为调试符号上不可能有“源映射”,因为 C 编译器的调试符号生成器中存在向后不兼容的更改。每次更改受支持的 C 编译器时,都必须更新调试符号映射软件。
    【解决方案4】:

    明显没有 CLANG 或处于实验状态的架构和操作系统。

    C 被更广泛地接受,但 LLVM IR 允许你用勺子喂 LLVM 引擎。并非所有通往 IR 的路径都是平等的。

    【讨论】:

      【解决方案5】:

      我将使用 LLVM 来指代框架,并使用 LLVM IR 来指代目标语言。

      C 优势

      1. 跨平台
      2. 调试(请阅读下文。部分与第 4 点有关。)
      3. 互操作性
      4. 易于使用

      LLVM IR 优势

      1. 性能
      2. 自定义选项
      3. 内存占用
      4. 强大的打字/安全

      C

      1. 尽管 LLVM 最近获得了更多目标,但仍然存在适用于各种嵌入式系统的 C 编译器。可以说,在这一类别中,C 比 LLVM IR(中间表示)稍有优势。

      2. 以 C 而不是 LLVM 为目标的主要优点是生成的代码与 LLVM 相比处于更高级别。使用诸如 GDB 之类的标准化调试器,可以说更容易推理生成代码的行为。使用 GDB 等调试器也更容易为编译为 C 的语言构建调试器。

      3. 第三点。互操作性更麻烦。但是,C 具有标准化的应用程序二进制接口。因此更容易编写库并将这些库与用 C 和/或 C+ 编写的其他程序接口。尽管如此,许多语言(例如 Java)仍为 C 提供标准化接口。

      4. 可以说,以 C 为目标更容易上手并让某些东西发挥作用

      LLVM

      1. C 是一种相当高级的语言,如果不编写它,通常会降低性能(取决于目标编译器,以及所述编译器所做的假设)。 有一些论文如An llVM backend for GHC 这说明了 C 的一些缺点和 LLVM IR 作为目标语言的优点。

      2. 由于 LLVM(框架)是作为可重用单元的集合构建的,因此很容易为您的特定目标语言编写特定于目标语言的传递。编写自定义 GC (There is as of 2020 some support for this) 也更容易。在 C 的情况下也是可能的,并且有一些垃圾收集器,例如Boehm GC。但是,C 并非设计为中间语言。

      3. 内存占用。与 LLVM 位码相比,生成的 C 代码具有更大的内存占用。如果您正在编译和链接一个大型系统,您可能会获得针对 LLVM 的编译时间优势。

      4. 虽然 C 是弱类型语言。 LLVM IR 是一种强类型。因此,可以说以 LLVM IR 为目标更安全。

      【讨论】:

        猜你喜欢
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        • 2014-07-15
        • 1970-01-01
        • 2014-09-03
        • 2012-02-27
        相关资源
        最近更新 更多