一些代码优化是在中间代码上执行的,因为
IMO :中间代码是机器无关的代码。因此,可以使用中间代码进行代码优化,因为给定的源代码可以转换为目标机器代码。因此,选项(1),但在某个地方解释的选项(2)也是正确的。
代码优化的目的是什么,在编译器的中间阶段有什么好处?
发布于 2015-10-17 22:03:00
编译器优化可移植性并不是在中间代码上执行许多优化的原因。然而,这是我们免费获得的一个好处。你说的其他三点是模糊的。不管怎么说,我们不需要讨论他们。
要回答您的问题,我必须了解一个典型的提前(AOT)编译器的操作(这个问题只适用于这种类型的编译器)。编译期间,编译器通常处理源代码的五种表示形式:
现在,让我们看看哪种表示最适合执行优化。使用前三种表示中的任何一种都会导致编译器极其缓慢,因为几乎任何优化都需要对输入表示进行广泛的分析和修改。我说这几乎是因为前端执行的优化很少(通常是在AST上)。一个常见的例子是常量折叠。在这个级别上执行这种优化的原因是它们所做的所有修改都是本地的(在表达式中)。因此,它们很便宜。此外,它们还使生成的IR代码更加简洁,更适合于进一步分析。另一方面,as能够很好地执行语义分析,以便编译器能够尽快发现任何错误,如果发现任何错误,则中止进一步的处理。
大多数编译器优化都接受IR代码作为输入,并生成(希望优化的) IR代码作为输出(嗯,一些编译器可能会逐渐降低IR,直到一个优化发布二进制代码为止)。中间语言是专门为应用优化设计的。首先,它有一个顺序表示 (类似于二进制代码),可以很容易地修改。其次,IR保存了AST中可用的大部分信息。这包括全局、本地和临时变量定义和类型。这种表现力使编译器能够更有效地优化代码。第三,它是低级的,它的指令是原始的,并且只有一个或几个连续的IL指令被映射到很少的目标ISA指令。这有助于代码生成器快速实现其目的。
在二进制代码上执行的优化很少。这包括第一次或第二次通过指令调度和第二通过寄存器分配.
在所有这些之后,链接器(如果需要的话)开始它的工作,这可能包括很少的其他优化。
请注意,大多数编译器优化也可以在二进制代码上执行(尽管不是那么有效)。这种类型的优化称为动态二进制优化,它们用于动态二进制转换和检测。
我想说几句关于便携性的话。IL使我们能够对多个源语言使用相同的后端。然而,即使我们确实知道只有一种语言将永远被支持,IL仍然是非常重要的,正如我刚才所解释的。而且,很少有非常重要的优化依赖于目标ISA。有许多优化可以将代码从IR转换为IR。这些显然是独立于目标的。这些优化确实是可移植的,可以在不同目标体系结构的后端之间共享。
https://stackoverflow.com/questions/33184269
复制相似问题