想象一下,我有一种基于堆栈的玩具语言,它带有 Push、Pop、Jump 和 If 操作。
我有一个程序,它的输入是玩具语言。例如我得到序列
Push 1
Push 1
Pop
Pop
在这种情况下,最大堆栈将为 2。更复杂的示例将使用分支。
Push 1
Push true
If .success
Pop
Jump .continue
.success:
Push 1
Push 1
Pop
Pop
Pop
.continue:
在这种情况下,最大堆栈将为 3。但是,如本例所示,通过从上到下遍历是不可能获得最大堆栈的,因为它实际上会导致堆栈下溢错误。
CFG 可以帮助您构建图表并遍历您拥有的基本块的每条可能路径。然而,由于路径的数量对于 n 个顶点可以快速增长,因此您得到 (n-1)!可能的路径。
我目前的方法是尽可能简化图表并减少可能的路径。这行得通,但我认为它很难看。有没有更好(阅读:更快)的方法来解决这个问题?如果算法产生的堆栈深度不是最优的,我很好。如果正确的堆栈大小是 m,那么我唯一的限制是结果 n 是 n >= m。是否有可用的贪心算法可以在这里产生良好的结果?
更新:我知道循环和所有控制流合并具有相同堆栈深度的不变量。我想我写下一个简单的玩具般的语言来说明这个问题。基本上我有一个确定性的基于堆栈的语言(JVM 字节码),所以每个操作都有一个已知的堆栈增量。
请注意,对于这个问题,我确实有一个可行的解决方案,可以产生良好的结果(简化的 cfg),但我正在寻找一种更好/更快的方法。