代码之家  ›  专栏  ›  技术社区  ›  gnometorule

编译器代码优化:AST与IR

  •  8
  • gnometorule  · 技术社区  · 10 年前

    ,其中我将IR定义为3地址代码类型表示(我意识到也可以用它来表示AST表示)。

    我的理解是,在为 命令式语言 ,代码优化既发生在AST上(可能最好使用访问者模式),也发生在AST生成的IR上。

    (a) 这是正确的吗?

    (b) 哪种类型的优化步骤在产生IR之前最好在AST上处理?(参考在线欢迎的文章/列表,只要它涉及命令性语言)

    我正在研究的编译器是Decaf(有些人可能知道),它有相当深的CFG到(单个)类继承;我将添加不属于它的功能,例如类型强制。它将完全手动编码(不使用任何工具)。这不是家庭作业;写它是为了好玩。

    3 回复  |  直到 6 年前
        1
  •  4
  •   user207421    10 年前

    (a) 是的。

    (b) 恒定折叠就是一个例子;CSE是另一个;事实上几乎与表达式求值无关。IR阶段优化更多的是流分析的结果。

        2
  •  4
  •   SK-logic    10 年前

    IR是AST的一种形式(通常是“扁平化”的,但也有深树IR),可能不容易区分它们,特别是如果编译器被实现为一系列非常小的重写,从原始AST一直到适合指令选择的最终IR。

    优化可能发生在这个链上的任何地方,但一些表示更适合于广泛的优化,最明显的是SSA形式,大多数现代编译器使用SSA形式来进行几乎所有的优化。

        3
  •  2
  •   david.pfx    10 年前

    优化(创造一个短语)永远不会太早。因此,在AST创建之前和创建过程中,对AST本身、IR(如果您有)和生成代码进行了优化。在类C语言和编译成机器代码的语言中,工作将进入后期阶段。在以VM为目标的编译器中,我认为在那个阶段改进的空间较小。

    一些早期优化显然比其他优化效果更好。我对Decaf了解不多,但有一些显而易见的东西,比如常量折叠和常量表达式求值。如果在生成任何代码之前以树形形式获取整个程序,则可以找到常见的子表达式、执行代码迁移、消除死代码/死存储、提升不变量、消除尾部递归和某些强度降低。

    这在很大程度上取决于你想工作的努力程度和你的目标是什么。