《Engineering a Complier》学习笔记(七)

代码形式(Code Shape)

 

编译器生成IR后,必须将每个源语言语句映射为目标机指令构成的操作序列。编译器必须在许多备选方法中做出选择,以实现语言中的每个结构。编译器所做的选择影响最终代码的质量。

 

1.分配存储结构

  • 物理寄存器: 目标ISA中一个命名的寄存器
  • 虚拟寄存器: IR使用的一个符号名,以代替物理寄存器名

编译器可能创建额外的静态数据区,以保存常量值、跳转表和调试信息。

逻辑地址空间布局:

 

 

地址空间的不同视图:

 

 

数据区的布局规则:

如果x声明在过程p局部,且值无需跨多次调用  ->  分配到局部储存

如果值跨越对p的多次调用而保持  ->  分配到局部静态存储区中

如果x全局可见  ->  分配到全局存储区

如果x的分配收全局控制  ->   分配到堆

1. 分配偏移量

编译器必须为每个名字分配数据区内部的一个偏移量

x2. 相对偏移量和高速缓存性能

高速缓存在现代计算机系统中的广泛应用,对变量在内存中的布局有微妙的影响。如果代码中使用两个值位置十分接近,则编译器可能想确保二者同时加载到高速缓存中。

对程序中计算的每个值,编译器都必须确定在何处存储该值,是在内存中还是在寄存器中,不管那种情况,都要给出具体的位置。

存储分配为编译器提供了一个关键的机会,编译器可以借此将信息编码到IR中,供后续各趟处理使用。

 

2. 算数运算符

以a-b*c为例,树遍历代码生成器: 

 未完待续

posted @ 2021-01-03 17:21  Asp1rant  阅读(126)  评论(0编辑  收藏  举报