1.编译器简介
编译器:以某种语言编写的程序作为输入,产生一个等价的程序作为输出。
如果当作一个黑盒子,编译器可看作这样:
解释器:将一种可执行规格作为输入,产生的输出是执行该规格的结果。
如果当作一个黑盒子,解释器可看作这样:
编译器和解释器
同:1)分析输入程序,并判定是否有效
2)建立内部模型,表示输入程序的结构和语义
3)确定执行期间在何处存储值
异:编译器:输出转换后可以执行的目标程序来产生结果
解释器:解释代码来产生结果
编译器的两个原则:(1)正确性:保持被编译程序的语义
(2)实用:对输入程序的改进可觉察
2.编译器结构
典型编译器的结构:
IR(中间表示):编译器各个独立阶段之间所传递程序的版本
前端:理解源程序并将其分析结果以IR形式记录下来
优化器:改进IR形式
后端:将转换过的IR程序映射到目标机的有限资源上,从而有效利用那些资源
3.前端
前端根据语法和语义,判断输入代码是否良构。若代码有效,前端会以编译器的IR格式来建立该代码的一个表示;否则会向用户回报诊断错误信息。
前端有两趟独立的处理,词法分析器和语法分析器,来判断输入代码。
1)词法分析器:以字符流为输入,并将其转换为已归类单词的流【形如(p,s):p是单词的词类,s是单词拼写】。
2)语法分析器:判断输入流是否是源语言的一个句子。
3)IR(中间表示):编译器可以使用各种不同种类的IR
4.优化器
优化器分析代码的IR形式,以发现有关上下文的事实,并利用此项上下文相关知识重写代码,使之能够以更有效的方式来算同样的答案。
1)分析:判断编译器可以在何处安全应用优化技术且有利可图
数据流分析和相关性分析。
2)转换:使用分析的结果来将代码重写为一种更高效的形式。
5.后端
1)指令选择:将每个IR操作在各自的上下文中映射为一个或多个目标机操作。
+指令选择器隐式依赖于寄存器分配器,以便将这些符号寄存器名(虚拟寄存器),映射到目标机的实际寄存器。
+指令选择器可以利用目标机提供特殊操作。目的:减少寄存器的使用或加快运行等
2)寄存器分配:在代码的每一个点上,寄存器分配器都必须决定哪些值驻留在目标寄存器中。它接下来重写代码以反映其决策。
3)指令调度:指令调度器重排代码中的各个操作。它试图最小化等待操作数所浪费的周期数。
+不同操作执行时间可能不同。许多处理器有一个特性,可以在长延迟操作执行期间发起新的操作。只要新操作完成之前不引用长延迟操作的结果,执行都可以正常地进行
4)代码生成的各组件间的交互