在编译器后端必须将变量分配给内存或寄存器的代码生成的寄存器分配阶段,溢出寄存器或溢出代码是什么意思?编译器中的寄存器分配
3
A
回答
6
Hardware registers是昂贵的(无论是在芯片面积和解决它们所需的指令位的数量方面),因此通常数量很少。 Spilling发生在给定程序点的live variables(或更准确地说,活动范围的数量)超过可用寄存器的数量时。
考虑下面的示例程序在虚拟机器中执行,该虚拟机器有两个硬件寄存器。假设编译器除寄存器分配外不执行优化。
a := 1 ; liveout: {a}
b := 2 ; liveout: {a,b}
c := 3 ; liveout: {a,b,c}
d := a + b + c
由于a
和b
在d
定义的使用,他们的生活范围跨越的c
定义。但是由于机器只有两个寄存器,所以当定义d
时,不可能将a
,b
和c
保存在寄存器中。至少其中一个必须溢出。
在最简单的溢出形式中,溢出变量的所有定义都被存储替换为stack插槽,并且所有用途都被替换为负载。一些编译器也可以选择执行寄存器到寄存器的溢出,这意味着该值被存储到另一个类的寄存器并从其中载入。例如,在x86-64上,编译器可能会将一个通用寄存器(如rax
)的值溢出到SIMD寄存器(如xmm0
)中。这有利于减少内存流量。
作为溢出的替代方法,编译器可以改为执行活动范围分割。这涉及到将活动范围分成较小的部分 - 只在分割点处插入加载和存储 - 以使着色不可干扰的干扰图形成为可能。正如你可以想象的那样,选择哪个变量溢出对结果代码的性能有着重要的影响。任意溢出在紧密环路中使用或定义的变量可能会造成灾难性后果。因此,一个好的编译器可能会采用某种形式的启发式方法来估算溢出每个变量的成本,然后再进行选择。
相关问题
- 1. 如何在CUDA编译中分配寄存器
- 2. 在CPU寄存器中分配寄存器变量的标准?
- 3. XOR寄存器,寄存器(汇编)
- 4. 图着色寄存器分配器
- 5. Verilog:将寄存器分配给寄存器
- 6. Verilog:将值保存在寄存器中(分配给相同的寄存器)
- 7. 为什么编译器将变量存储在寄存器中?
- 8. 寄存器分配算法的效率
- 9. MIPS编译器中的寄存器 - 使用哪个?
- 10. 编译代码生成 - 条件块内部的寄存器分配
- 11. 分配4位至8位寄存器
- 12. 将值0xB33C分配给寄存器$ t0
- 13. Jamod Modbus从 - 分配寄存器
- 14. GCC避免编译分支链接寄存器(blr)语句
- 15. 编译器中代码生成的参考(中间表示,SSA,指令选择,寄存器分配等)?
- 16. 主要C/C++编译器生成的代码中的寄存器分配规则
- 17. 有关为小型c编译器实现全局寄存器分配器的问题
- 18. Windows配置到寄存器
- 19. 如何强制C++编译器使用寄存器?
- 20. 说服编译器在循环外设置寄存器
- 21. 编译器是否管理CPU寄存器?
- 22. 汇编和寄存器
- 23. 编译器/汇编程序如何理解处理器内核寄存器?
- 24. 大会部分寄存器
- 25. 编译器支持STL容器中的有状态分配器
- 26. 的寄存器
- 27. 解释GDB寄存器(SSE寄存器)
- 28. 汇编器反转XMM寄存器
- 29. 分配数组的编译器行为
- 30. 在verilog中检测未分配的寄存器
令人敬畏的解释,所以编译器也使用启发式来估计寄存器的溢出?令人惊讶的是,你能指出一些有关在那里使用的启发式算法的资源。谢谢,并upvoted。 –
我一直无法找到任何可访问的资源。 [Cooper&Torczon](http://www.amazon.com/Engineering-Compiler-Second-Edition-Cooper/dp/012088478X)表明循环嵌套可以用作估计。基本上,我们假设每个循环执行N次(我们可能选择N = 10)。因此,循环中引用的变量的成本是存储和加载所需的内存操作次数的N倍。类似地,在双重嵌套循环中引用的变量将具有N^2次操作次数的成本。 –