LLVM做什么样的优化,其前端必须自己实现什么样的优化?

LLVM做什么样的优化,其前端必须自己实现什么样的优化?,llvm,compiler-optimization,Llvm,Compiler Optimization,注意:我注意到这一点与此有很大关系,所以如果你对我的问题感兴趣,你肯定也应该阅读另一个问题及其答案 我可以想到OOP语言前端可以做的一些优化,比如创建临时变量来保存按顺序调用的常量方法调用的值,而不需要对相关对象进行中间非常量调用,以切断函数调用,但我想不出更多。我想请大家创建一个较长的示例列表 我问这个问题是因为我想创建一个小型语言作为一个宠物项目,我不知道如何很好地学习这个主题。也许社区维基就是这样?LLVM后端所做的优化以及前端应该自己做的优化的综合列表,您认为如何 哦,我知道不同的前端可

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

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

我问这个问题是因为我想创建一个小型语言作为一个宠物项目,我不知道如何很好地学习这个主题。也许社区维基就是这样?LLVM后端所做的优化以及前端应该自己做的优化的综合列表,您认为如何


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

这可能因语言而异。。。clang(C/C++)在前端的优化方面做得很少,但却能侥幸逃脱。我认为只有优化才能完成生成代码的性能,即CLAN在前端做了一些C++虚拟化的方法。clang还进行了一些其他优化,如常量折叠和死代码消除,但这主要是为了加快编译速度,而不是为了提高生成代码的性能

实际上,考虑一下,我只记得一个更重要的C++优化的CLAN:CLAN知道C++中复制构造函数的一些技巧(谷歌为NRVO)。 在某些情况下,特定于语言的IR优化过程可能很有用。有一个SimpleLibCalls过程,它知道如何优化对C标准库的调用。对于新的Objective-C ARC语言特性,clang将一些特定于ARC的过程放入管道中;这些优化了对各种Objective-C运行时函数的out调用

一般来说,在代码中实现无法在IR中编码的属性(例如C++对象具有常数VTABLE指针)时,前端实现优化通常是有用的。实际上,您很可能希望首先实现哑代码生成,并查看是否存在未优化的重要情况。优化器可以进行一些异常复杂的转换


另见;适当地使用alloca是对优化器有很大帮助的一件事,尽管它本身并不是一个真正的优化。

有很多优化只需要保存尽可能多的信息,LLVM使用这些信息。SSA为从控制流、数据流方面进行分析提供了很多可能性

另一方面,LLVM语言非常复杂,许多高级信息丢失

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

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

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

我没想到clang没有做很多优化。我想它至少可以做5个或更多(再说一遍,我不理解这个主题,所以我说的一切都是随意猜测,哈哈)。如果你对你的答案很有把握,而且这个问题一点也不流行,我可以把它标记为被接受。只是等待你的确认;非常感谢;)这真的没什么用。。。这样想:如果一个优化可以表示为一个IR-to-IR转换,而这个转换不会改变语义,那么为什么要复制代码在ASTs上执行呢?(事实上,clang已经开发了一些非常强大的AST优化器,但我们使用这些优化器进行静态分析,而不是代码生成。)是的,我想象LLVM可能会从IR中挤出所有它能挤出的东西,但我对IR中的内容和丢失的内容没有清晰的认识(NRVO就是一个例子)。我想这里没有太多微妙的例子。NRVO、实现专门化(取决于可用硬件)、首选分支,它们都非常明显,在编写编译器时我不会错过它们。但是谢谢你的澄清,我现在感觉更自信了D