1 背景介绍
在上一篇博文 LLVM 里的寄存器分配 - 准备工作(一) 里,我主要整理了 LLVM 在做寄存器分配前所做的准备工作,介绍了 LLVM 是在怎样的 MIR 上做的寄存器分配。接下来,就需要讲讲 LLVM 是如何做寄存器分配了。虽然我学习的第一个寄存器分配算法是图着色算法,但由于目前的 LLVM 版本里使用的寄存器分配器均是线性扫描算法的变种(事实上 LLVM3.0 版本以前的寄存器分配器默认使用的就是线性扫描算法),因此本文主要介绍线性扫描算法的理论知识以及相关术语,图着色算法的具体过程可以参考文档 Global Register Allocation。
2 为什么不使用图着色算法?
在开始研究 LLVM 里的寄存器分配算法之前,我一直以为 LLVM 使用的是图着色算法,后来了解多一点才发现 LLVM 至始至终就没有考虑过图着色。这是为什么呢?这个问题其实在 LLVM3.0 的发布会议上,这一版本寄存器分配器的开发者 Olesen 在他的 报告 里提到过,如下所示:
除此之外,在实际的编译工作中,人们发现了另外一个问题。由于在目前所有的硬件架构中,寄存器的数目都是有限的,故对于大型程序来说,寄存器不够用可以说是必然存在的情况。换句话说,大型程序一定会产生大量溢出。问题就出现在这里,因为图着色算法把重点放在解决“如何把所有的程序变量尽可能地分配到寄存器中”,如果程序一定会大量产生溢出,那么,关注“如何高效地溢出”比关注“如何尽量减少溢出”更有