1

我一直在构建自己的编译器,其中很大一部分显然是寄存器分配器,它尽可能有效地将临时变量与机器寄存器匹配。在诸如 x86 之类的架构上,寄存器并不多,因此存在大量溢出,其中变量必须存储在内存(堆栈)中。还有一些变量存储在内存中,因为它们太大而无法放入寄存器中。

实际上再次调用寄存器分配器以有效地分配内存中的变量,以便尽可能多地共享空间。真正的问题是没有办法限制寄存器分配器将两个变量放在内存中彼此相邻(因为我可以给它更大的变量作为一些较小的变量)并允许分配器移动较小的变量这样更大的变量可以适应,我想知道是否有任何算法可以处理这个问题,否则我必须将内存分成不同的区域,每个区域都保存不同大小的变量。

下面是一个例子来证明这一点:

void f(){
    int32_t a, b;
    //something happens to a and b...
    int64_t c;
    //something happens to c...
}

出于示例的目的,这里有一些假设......变量没有被优化掉,一旦定义了 c 并且所有变量都分配到堆栈内存,a 和 b 就不再有用了。显然,我希望“c”使用与刚刚使用的“a”和“b”相同的内存,因此只分配 8 个字节,但是我的编译器的当前版本将分配完整的 16 个字节。

我的问题是,如何有效地在不同大小的内存中分配变量?

4

1 回答 1

1

显然,寄存器分配器不足以分配堆栈空间,因为合并相邻的寄存器没有意义——至少在 x86 上是这样。

为什么不扩展它来做到这一点呢?或者,更好的是——将其划分或子类以直接处理寄存器和堆栈分配。

至于堆栈分配器,在两个变量由于非重叠范围而可以共享相同分配的(罕见)情况下,最小化使用的堆栈通常既不节省执行时间,也不特别节省空间。在范围转换时分配和取消分配额外堆栈空间的操作不太值得。即使在最关键的实时处理中,人们通常对鲁棒性和速度更感兴趣,而不是削减几个字节的堆栈空间。

于 2010-02-09T19:43:22.720 回答