优化c ++编译器如何重用函数的堆栈槽?

Poo*_*ria 2 c++ memory compiler-construction optimization stack

优化c ++编译器如何确定该函数何时不再需要函数的堆栈槽(函数的堆栈帧的一部分),以便它可以重用其内存?.
通过堆栈槽我是指函数堆栈帧的一部分,不一定是函数的整个堆栈帧,并且澄清问题的一个例子是,假设我们有一个函数,在其作用域中定义了六个整数变量,当它的时间在函数中使用第六个变量,第五个变量变得无用,因此编译器可以对第五个和第六个变量使用相同的内存块.
有关此主题的任何信息表示赞赏.

Ira*_*ter 10

编辑:我将这个问题解释为"编译器如何重用堆栈中的特定内存字?" 下面的大多数答案都提出了问题,并且结尾的一个注释回答了问题,"编译器如何重用函数所需的所有堆栈空间?".

大多数编译器不首先分配堆栈槽.相反,对于每个函数体,它们所做的是将变量的每个更新处理,以及对可以看到特定赋值的该变量的所有访问,作为所谓的变量生存期.因此,多次分配的变量将使编译器创建多个生命周期.

(当多个分配可以通过不同的控制路径访问时,会出现这种想法的复杂性;这可以通过对这个称为静态单一赋值的思想进行巧妙的增强来解决,我在此不再讨论).

在代码中的任何一点,都有一组有效的变量生命周期; 当您选择不同的代码点时,您将拥有不同的有效变量生命周期.编译器的实际问题是为每个生命周期分配不同的寄存器或堆栈槽.可以将此视为图形着色问题:每个生命周期都是一个节点,如果两个生命周期可以在代码中的某个点重叠,则从该节点到代表另一个生命周期的另一个节点存在"干扰"弧.您可以为图形着色(或等效地使用数字而不是颜色),这样干扰弧连接的两个节点就不会有相同的颜色(数字); 您可能必须使用任意大数来执行此操作,但对于大多数函数,数字不必非常大.如果你这样做,颜色(数字)将告诉您一个安全的堆栈槽用于特定变量生命周期的指定值.(这个想法通常大致分两个阶段使用:一次分配寄存器,一次为那些不适合寄存器的生命周期分配堆栈槽).

通过确定在图表上用作颜色的最大数字,编译器知道在最坏情况下需要多少个插槽,并且可以在功能进入时保留那么多存储器.

有很多并发症:不同的值占用不同的空间等,但基本的想法就在这里.并非所有编译器都使用图形着色技术,但几乎所有编译器都会弄清楚如何以避免隐含干扰的方式分配堆栈插槽和寄存器.因此,他们知道堆栈槽号和堆栈帧的大小.

编辑...在键入时,似乎问题被解释为"函数的堆栈帧什么时候消失"?答案是,在功能退出时.编译器已经知道它有多大.它不需要在函数执行期间推送或弹出堆栈; 它根据图形着色确定的堆栈槽编号知道放置所有内容的位置.