【问题标题】:What kinds of optimization LLVM does and what kinds of optimizations its frontends have to implement themselves?LLVM 做了哪些优化,它的前端必须自己实现哪些优化?
【发布时间】:2011-11-10 18:42:49
【问题描述】:

注意:我注意到this question 与这个问题有很大关系,所以如果你对我的问题感兴趣,你绝对应该阅读另一个问题及其答案。

我可以想到 OOP 语言前端可以做的一些优化,例如创建临时变量来保存按顺序调用的 const 方法调用的值,而不需要对相关对象进行中间非常量调用,以切断函数调用,但我想不出更多。我想请人们创建一个更长的示例列表。

我问这个是因为我想创建一个小型语言作为一个宠物项目,但我不确定如何很好地学习这个主题。也许这是社区维基的一个案例? LLVM 后端所做的优化以及前端应该自己做的优化列表,你怎么看?

哦,我知道不同的前端可能有很大不同的需求,但我的重点是过程/OOP 语言。

【问题讨论】:

    标签: llvm compiler-optimization


    【解决方案1】:

    这可能因语言而异... clang (C/C++) 在前端优化方面做得很少。我能想到的唯一优化是为了生成代码的性能,clang 在前端对 C++ 方法进行了一些去虚拟化。 clang 还做了一些其他优化,比如常量折叠和死代码消除,但这主要是为了加快编译时间,而不是为了提高生成代码的性能。

    编辑:实际上,再想一想,我只记得 clang 为 C++ 所做的一个更重要的优化:clang 知道在 C++ 中省略复制构造函数的一些技巧(google for NRVO)。

    在某些情况下,特定于语言的 IR 优化过程可能很有用。有一个 SimplifyLibCalls pass,它知道如何优化对 C 标准库的调用。对于新的 Objective-C ARC 语言特性,clang 将一些特定于 ARC 的传递放入管道;这些优化了对各种 Objective-C 运行时函数的调用。

    一般来说,只有在代码具有无法编码到 IR 中的属性时(例如,C++ 对象具有常量 vtable 指针),在前端实现优化通常才有帮助。在实践中,您很可能希望先实现哑代码生成,然后查看是否有未优化的重要案例。优化器可以进行一些令人惊讶的复杂转换。

    另见http://llvm.org/docs/tutorial/LangImpl7.html;适当地使用 alloca 是对优化器有很大帮助的一件事,尽管它本身并不是真正的优化。

    【讨论】:

    • 没想到clang没有做很多优化。我认为它至少会做 5 次或其他事情(同样,我不明白这个主题,所以我所说的一切都只是随意猜测,哈哈)。如果您非常确定自己的答案,并且由于这个问题根本没有流行,我可以将其标记为已接受。等待您的确认;非常感谢;)
    • 它真的没有那么多......这样想:如果优化可以表示为不改变语义的 IR 到 IR 转换,你为什么要复制代码到在 AST 上做吗? (实际上,clang 已经开发了一些非常强大的 AST 优化器,但我们将它们用于静态分析,而不是代码生成。)
    • 是的,我想象 LLVM 可能会从 IR 中挤出所有可能的东西,但我对 IR 中的内容和丢失的内容没有清晰的认识(NRVO 就是一个例子)。我想这里没有很多微妙的例子。 NRVO,取决于可用硬件的实现专业化,首选分支,它们都很明显,我在编写编译器时不会错过它们。但是谢谢你的澄清,我现在更有信心了! :D
    【解决方案2】:

    有很多很多优化只需要在 LLVM 使用的SSA form 中保存的信息。 SSA 为分析控制流、数据流提供了很多可能性。

    另一方面,LLVM 语言是RISC,所以丢失了很多高级信息。

    所以答案是:前端能够进行优化,需要在转换为 SSA 后丢失的信息。我想到的例子:

    • 首选分支优化,一些示例
      • 语言。诸如声明首选分支之类的扩展(在 Linux 内核中,一些分支被标记为几乎总是执行)
      • 抛出和捕获异常的实现
      • 协程实现和依赖信息
    • 指数增长的优化(如循环取消开关增长代码大小)可能需要根据高级信息应用于特定位置。 - 可能来自源代码(前端)。
    • 语言特征(可能是反射或其他)被翻译成“多指针”(如指向指针的指针......)相互关联的结构,在低级别可能难以猜测 - 就像在低级别, all 可能看起来像数组访问,虽然它可能有一些可能有助于优化的高级约束。
    • 复杂功能的实现可能因可用硬件而异。让我们举几个例子:矩阵乘法、FFT 变换(压缩和解压缩算法)、大数算术等......取决于底层硬件,它可能会以不同的方式实现以实现最大性能。在将内容转换为 LLVM 之后,使用更适合可用硬件的方式更改实现可能会非常非常非常昂贵(就计算复杂性而言)。也就是为什么编译到底层的时候要由前端来决定。

    这些只是一些想法,一个希望,展示了可能涉及的优化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2012-05-13
      • 2019-07-12
      • 2010-10-30
      • 2012-04-26
      • 1970-01-01
      相关资源
      最近更新 更多