理论教育 编译器设计:指令选择与优化方案

编译器设计:指令选择与优化方案

时间:2023-11-04 理论教育 版权反馈
【摘要】:指令选择的难易程度主要取决于目标机的指令集,并不能一概而论。这就意味着,可以达到相同功能的指令或指令序列可能并不唯一时,如何选择一个更优的方案是值得考虑的。在不考虑目标程序的效率的情况下,指令选择的实现是非常简单的。到底是指汇编指令的行数,还是机器指令的字节数?然而,对于某些指令码不等长的指令系统而言,试图准确预计机器指令的大小是比较困难的。

编译器设计:指令选择与优化方案

指令选择的难易程度主要取决于目标机的指令集,并不能一概而论。实践经验证明,CISC指令集比RISC指令集更有利于编译器实现,这是因为所拥有的资源(指令)相对较丰富。例如,试图在没有浮点运算指令的目标机上实现浮点数运算,那么,编译器设计者就不得不考虑如何使用整数运算指令模拟实现。当然,这并不是绝对的。在资源相对丰富的情况下,设计者可能会面临新的问题,那就是如何合理调配资源,使得目标结果相对更优。这就意味着,可以达到相同功能的指令或指令序列可能并不唯一时,如何选择一个更优的方案是值得考虑的。

在不考虑目标程序的效率的情况下,指令选择的实现是非常简单的。只需要根据IR的实际语义,为每种IR设计一个相对独立的目标代码片段。在代码生成期间,按照IR与目标代码片段的一一对应关系,将IR转换为语义等价的目标代码片段即可。在设计目标代码片段时,由于并不考虑各句IR之间的联系,因此,这种处理方案是完全可以保证安全的。那么,这种方案的缺点是什么呢?笔者引入一个简单的例子。例如,a、b、c都是integer型的全局变量,则IR(ADD 4 a'b,c)的目标代码序列如下:

在单机情况下,这种翻译方案始终是安全的。不过,这种代码生成方案的缺点是代码质量较差,极易产生冗余代码。例如,IR序列如下:

那么,得到的目标代码序列如下:

仔细观察这段代码序列,可以发现如下几个问题:(www.daowen.com)

(1)第4条指令是冗余的。当第3条指令执行完成后,eax寄存器中存储的值就是c变量的值,因此,再次从c变量内取值是冗余的。

(2)如果编译器可以确定以后将不存在c的引用,则第3条指令也是冗余的。计算机完全可以依赖eax内的计算结果直接参与运算,而不需要将其值映射到c单元中。

理论上讲,评价目标代码质量的标准是显而易见的,即执行效率与代码长度,这是指令选择需要关注的问题。不过,实践证明,有时这种评价是很难进行的。例如,代码长度的准确定义是什么?到底是指汇编指令的行数,还是机器指令的字节数?当然,理想情况下,人们更希望以后者作为评估标准。然而,对于某些指令码不等长的指令系统而言,试图准确预计机器指令的大小是比较困难的。有时,即使设计者竭尽所能,也是徒劳无功的。因此,退而求其次也是可以接受的。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈