叶调用优化与收缩包装
1. 叶调用优化适用于被调者是不调用任何过程的过程之场景,这种过程叫叶过程
2. 有几种可能的优化
a)如果过程的实现使用display数组来寻址非局部变量,那么叶过程可避免在起始代码序列中更新display数组
b)如果叶过程内不使用由被调者保存的寄存器(寄存器分配器应设法优先使用由调用者保存的寄存器),那么可避免起始代码序列中保存代码和收尾代码序列中恢复代码。很小的叶过程很可能不使用到被调者保存的寄存器,只使用部分调用者保存的寄存器的叶过程,那么调用者也可以避免一部分寄存器保存与恢复代码
c)如果调用者有很多次调用叶过程,而且两者代码同时可见,那么叶过程不必自己分配栈帧,由调用者一次性分配好
3. 收缩包装是叶调用优化的一种推广,目的是尽可能去掉过程起始代码序列和收尾代码序列中实际没用的寄存器保存恢复代码。可以先用数据流分析来计算每个基本块的保存寄存器集合(基本块入口可预见但其前驱不可预见且入口不可达的那些寄存器)与恢复寄存器集合(基本块出口可达但其后继不可达且出口不可预见的那些寄存器),再在保存寄存器集合非空的基本块入口处插入save指令(插入点已是最早的合适的位置),恢复寄存器集合非空的基本块出口处插入restore指令(插入点已是最晚的合适的位置)
尾调用优化与尾递归删除
1. 尾调用优化的条件是两个(不同)过程编译时同时可见,比如处于同一编译单元,或调用者有足够多的、使得优化可能发生的关于被调用者的信息
2. 尾调用优化的实现,因为被调者返回后代码序列到调用者收尾代码序列之间不存在有用计算,所以原来标准链接处理要保存的那些寄存器不可能活跃,首先要裁剪调用前代码序列即不保存由调用者保存的寄存器和不压栈返回地址,以及裁剪被调过程的起始代码序列即不保存由被调者保存的寄存器和不分配新栈帧(借用调用者的栈帧,若被调者的栈帧比调用者的大,则需按两者之差扩展栈帧),然后转移到被调者裁剪过的起始代码序列,最后修改被调过程的收尾代码序列:正确释放栈帧,比如用帧指针赋给栈指针,使之直接返回到调用者的调用者(比如o调用p,p调用q,q是尾调用,那么优化后q实际返回到o)。综上可得,尾调用优化减免了压栈返回地址与保存寄存器的开销
3. 尾递归删除是尾调用优化的一种特例,由于调用者和被调者是同一过程,因此不存在扩展栈帧和额外释放栈帧,只须改变参数及跳转到过程入口处即可
posted on 2023-09-06 23:23
春秋十二月 阅读(53)
评论(0) 编辑 收藏 引用 所属分类:
Compiler