编译器开发_中国多少人能写编译器_编译器设计(第2版)
本文关键词:编译器设计,由笔耕文化传播整理发布。
> 其他综合 > 编译器设计(第2版) 1.2 编译器结构 2012-12-18 08:37:48 我要投稿
本文所属图书 > 编译器设计(第2版)
云计算彻底改变了应用程序的开发与使用方式,甚至也改变了应用程序原本的定义。有了云计算,应用不再运行在用户桌面计算机上,而是分布式地运行于网络上,与全世界千万用户同时使用计算资源。它还具有传统应用程... 立即去当当网订购
编译器是一个庞大、复杂的软件系统。编译器社区自1955年以来一直在构建编译器,多年以来,关于如何设计编译器的结构,我们已经学习了许多经验教训。早期,我们将编译器描述为一个简单的盒子,能够将源程序转换为目标程序即可。当然,现实比这个简单的图景更为复杂。
单盒模型指出,编译器必须理解输入源程序并将其功能映射到目标机。这两项任务截然不同的性质暗示着一种可能的任务划分,并最终导致了一种将编译分解为两个主要部分的设计:前端和后端。
前端专注于理解源语言程序。后端专注于将程序映射到目标机。对于编译器的设计和实现,这种关注点的分离隐含着几个重要结论。
前端必须将其对源程序的认识编码到某种结构中,以供后端稍后使用。中间表示(IR)成为了编译器对所转换代码的权威表示。在编译过程中的每个点,编译器都有一个权威表示。实际上,随着编译过程的进展,可以使用几种不同的IR,但在每个点上,都只有一种表示会成为权威的IR。我们可以将权威IR看做编译器各个独立阶段之间所传递程序的版本,就像是前述图中从前端传递到后端的IR一样。
IR
编译器使用一些数据结构来表示它处理的代码,这种形式称为中间表示(Intermediate Representation,IR)。
在一个两阶段编译器中,前端必须确保源程序是良构的,而且必须将输入的代码映射到IR。后端必须将IR程序映射到目标机的指令集和有限的资源上。由于后端仅处理前端生成的IR,因此它可以认为IR不包括任何语法和语义错误。
生在这个时代真好
就编译器的设计和实现而言,这是一个令人激动的时代。在20世纪80年代,几乎所有的编译器都是庞大的单块式系统。它们将一种语言作为输入,产生针对某种特定计算机的汇编代码。生成的汇编代码与其他编译过程产生的代码(包括系统库和应用程序库)粘贴在一起,最终形成一个可执行文件。这个可执行文件存储在磁盘上,最终的可执行代码在适当的时间从磁盘移动到内存并执行。
今天,编译器技术应用于各种不同环境下。随着计算机在各种不同的场合获得应用,编译器必须处理新的不同的限制。速度不再是用于判断编译后代码的唯一标准。当今,判断代码质量的规则很可能是代码“占地”有多小,代码执行时耗能多少,代码能压缩到多小,代码执行时产生多少个缺页异常,等等。
同时,编译技术已经脱离了80年代单块式系统的窠臼,它们出现在许多新场合。Java编译器采用部分编译的程序(Java“字节码”格式)作为输入,并将其转换为目标机的本机码。在这种环境中,成功意味着编译时间加上运行时间的总和必须小于解释执行的代价。分析整个程序的技术正在从编译时转向链接时,链接器可以分析整个应用程序的汇编代码并利用该认识来改进程序。最后,可以在运行时调用编译器生成定制的代码,以利用仅能从运行时得知的事实获利。如果编译花费的时间保持在比较短的水准上,而生成定制代码的获利较大,那么这种策略可以产生显著的改进。
在输出目标程序之前,编译器可以在代码的IR形式上进行多趟迭代。多遍迭代可能会生成更好的代码,因为编译器实际上可以在一个阶段中研究代码并记录相关细节。那么在后续阶段中,编译器可以利用这些记下的知识来提高转换的质量。这种策略要求第一趟获得的知识记录在IR中,后续各趟可以查找并利用这些知识。
最后,两阶段结构可以简化编译器重定目标的过程。我们可以轻易地想象到为单个前端构建多个后端,这样即可产生输入同一语言但输出针对不同目标机器的编译器。类似地,我们可以想象针对不同语言的前端生成同样的IR并使用共同的后端。这两种场景,都假定一种IR可以服务于几种源和目标的组合,实际上,特定于语言和特定于机器的细节通常都会进入到IR。
重定目标
改变编译器使之针对新处理器生成代码的任务,通常称为将该编译器重定目标。
引入IR使得可以向编译增加更多阶段。编译器编写者可以在前端和后端之间插入第三个阶段。这个中间部分,也称为优化器,以IR程序作为其输入,产生一个语义上等价的IR程序作为其输出。通过使用IR作为接口,编译器编写者插入第三个阶段时,可以将对前端和后端的破坏降到最低。这就形成了下述的编译器结构,称为三阶段编译器。
优化器
编译器的中间部分称为优化器,负责分析并转换IR,以改进IR。
优化器是一个IR到IR的转换器,,试图在某些方面改进IR程序。(请注意,依据我们在1.1节中的定义,这些转换器本身就是编译器。)优化器可以对IR处理一遍或多遍,分析IR并重写IR。优化器重写IR可以使后端生成一个可能更快速或更小的目标程序。优化器还可能有其他目标,诸如产生更少缺页异常或耗能较少的程序。
概念上,三阶段结构表示了经典的优化编译器。实际上,每个阶段内部都划分为若干趟。前端由两趟或三趟组成,处理识别有效源语言程序的各种细节,并产生该程序的初始IR形式。中间部分包含执行不同优化的各趟处理。这些趟的数目和目的因编译器而异。后端由若干趟处理组成,每一趟都将输入的IR程序进一步处理,使之更接近目标机的指令集。编译器的三个阶段和其中的各趟处理共享了同一个基础设施,这些结构如图1-1所示。
将编译器在概念上划分为前端、中间部分(优化器)以及后端在实践中是很有用的做法。这些阶段解决的问题各有不同。前端的工作涉及理解源程序并将其分析结果以IR形式记录下来;优化器部分专注于改进IR形式;后端必须将转换过的IR程序映射到目标机的有限资源上,从而能够有效利用那些资源。
在这三个阶段中,优化器的描述最为模糊不清。优化这个术语,暗含编译器需要找到某个问题的最优解的意思。优化过程中发生的问题是如此之错综复杂,因而这些问题实际上是得不到最优解的。需要进一步澄清的是,编译后代码的实际性能取决于优化器和后端两个阶段中应用的所有技术之间的相互影响。因而,即使单个的某项技术可以被证明是最优的,但它与其他技术的交互可能产生次优的结果。因此,相对于未优化的代码版本而言,良好的优化编译器可以改进代码的质量。但优化编译器通常无法产生最优代码。
中间部分可以是单块式的一趟处理,其中应用一个或多个优化技术来改进代码,也可以从结构上设计为若干趟规模较小的处理过程,其中每趟都读写IR。单体式结构可能更为高效;多趟结构有助于降低实现的复杂度,同时在调试编译器时也相对简单。此外还提高了灵活性,可以在不同情况下采用不同的优化技术组合。这两种方法之间的选择,取决于构建编译器时和编译器实际运行时的约束条件。
点击复制链接 与好友分享!回本站首页 您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力 上一篇:1.1 简介 下一篇:1.3 转换概述 相关文章1.2 多核的未来:异构平台
1.2 多核处理器的缘起
译者简介
译者序
译者序
译者序
译者序
译者序
译者序
译者序
图文推荐本文关键词:编译器设计,由笔耕文化传播整理发布。
本文编号:53562
本文链接:https://www.wllwen.com/wenshubaike/mishujinen/53562.html