为什么我们使用中间语言而不是AST?

时间:2013-12-03 15:28:37

标签: optimization gcc compiler-construction abstract-syntax-tree

中间语言和AST有什么区别?据我所知,它们都提供了流量分析信息,编译器可以将这些信息用于优化目的。我知道GCC使用两个中间表示 - AST和IL。这是什么原因?

3 个答案:

答案 0 :(得分:7)

海湾合作委员会使用的不仅仅是两个中间代表,而且远远少于应该使用的代表。

有一种编译器设计方法,称为“nanopass”:编译器由一系列非常简单的代码重写构成,从解析器生成的原始AST开始,最后以低级代码结束。每个变换都是微不足道的,相邻中间语言之间的差异是微妙的。

这种方式很容易推理每个变换,易于理解整个链并易于添加新功能。丰富的语言可能有很多语法糖,例如,在进行任何类型检查之前,可以用更简单的语言结构来表达。

当然,这个链中的每种语言都表示为AST,但通常只有第一个由解析器生成的语言称为“AST”,其他所有语言都称为“中间”语言”。当然,术语可能因不同的思想流派而异。我个人更喜欢一直使用术语“AST”。

答案 1 :(得分:2)

不同的表示允许不同的优化。

AST是一种中间表示形式,它不是您键入的字符串,也不是机器代码。 AST对某些优化非常有用

  1. 恒定折叠
  2. 一些内联
  3. 重写规则
  4. 但是对于其他一些事情来说这很可怕,例如,想象一下试图找出AST中的寄存器泄漏,或者机器代码本身?编译器通常被构造为一个管道,每一步都有它自己的IL和它自己要执行的任务集。

    这样,每个IL都可以自定义,易于从以前的IL编译,并且易于以任何方式进行优化。 GCC例如IIRC有一个IL,它基本上就像汇编一样,这对于进行基于寄存器的优化非常有用,比如用什么时候加载什么来进行jiggering。这也可以变成真正的装配或直接的机器代码。

    GCC由许多这些小型IL组成,它们仅作为数据结构存在于编译器中并被创建,稍微混淆,然后编译为较低级别的IL。

答案 2 :(得分:0)

AST没有任何流信息。

然而,流信息在生成高效代码方面非常有用。所以你没有任何选择:如果你想要流量信息,你除了AST之外还需要一些东西。

这不是GCC独有的;几乎大多数编译器都这样做。

AI人员的一个关键见解是“表示可以很容易地提取某些感兴趣的事实”,并且不同的表示形式对于不同类型的事实都是有益的。

这在实践中意味着编译器可能有多个或多个程序表示(控制流程图,符号表,数据流图,“三元组”(一种IL),机器代码模型,...)取决于该编译器需要哪些信息来完成其工作。