« 上一篇下一篇 »

代码生成之简述

我们的编译器模型的最后一个步骤是代码生成器。它以编译器前端生成的中间表示(IR)和相关的符号表信息作为输,输出语义等价的目标程序。

对代码生成器的要求是很严格的。目标程序必须保持源程序的语义含义,还必须具有很的质量。也就是说,它必须有效地利用目标机器上的可用资源。此外,代码生成器本身必须能高效运行。

具有挑战性的是,从数学上讲,为给定源程序生成一个最优的目标程序是不可判定问题码生成中碰到的很多子问题(比如寄存器分配)都具有难以处理的计算复杂性。在实践中,我们使用那些能够产生良好但不一定最优的代码的启发性技术。幸运的是,启发性技术已经非常成熟,一个精心设计的代码生成器所产生的代码要比那些由简单的生成器生成的代码快好几倍。

要产生高效目标程序的编译器都会在代码生成之前包含一个优化步骤。优化器把一个则射为另一个可用于产生高效代码的IR。编译器的代码优化和代码生成步骤通常被称为编译器的后端(back end)。它们可能在生成目标程序之前对IR作多趟处理。代码优化将在第9章中御讨论。不论代码生成之前有没有优化步骤,都可以使用本章所讨论的技术。

代码生成器有三个主要任务:指令选择、寄存器分配和指派、以及指令排序。指令选择考虑的问题是选择适当的目标机指令来实现IR语句。寄存器分配和指派考虑的问题是把哪个值放在哪个寄存器中。指令排序考虑的问题是按照什么顺序来安排指令的执行。

本篇给出了一些和代码生成相关的算法,代码生成器可以使用这些算法把输人的1R翻译成简单寄存器机器的目标语肓指令序列。论了复杂的现代机器的代码生成问题,这些现代机器支持在单一指令中的人量并行性。

在讨论了代码生成器设计中的众多难题之后,我们给出了 一个编译器需要生成什么样的目标代码,以支持常见源语言中所包含的抽象机制。我们概述了静态和栈式数据区分配的实现方法,并说明如何把IR中的名字转换成为目标代码中的地址。

很多代码生成器把1R指令分成“基本块”,每个基本块由-绀总是一起执行的指令组成。把IR划分成基本块,接下来介绍了针对基本块的一些简单的局部转换方法。从转 换得到的基本块出发可以生成更加高效的代码。虽然要到第9章才开始考虑更加深人的代码优 化理论,但这种转换已经是代码优化的初步形式。一个有用的局部转换的例子是在中间代码的罢次上寻找公共子表达式,然后相应地把算术运算替换为更简单的拷贝运算。

最后给出了一个简单的代码生成算法,它依次为每个语句生成代码,并把运算分量尽可能长时间地保留在寄存器中,这种代码生成器的输出可以很容易地使用窥孔优化技术进行优化。

其余的部分将研究指令选择和寄存器分配。

« 上一篇下一篇 »