1
0
通常希望堆栈深度在跳跃和循环上保持不变。 这意味着对于每个节点,每个传入边缘都应该具有相同的堆栈深度。这大大简化了遍历cfg,因为后缘不能再更改已计算指令的堆栈深度。 这也是限制堆栈深度的要求。如果不强制执行,代码中的循环将增加。 您应该考虑的另一件事是使所有操作码的堆栈效果具有确定性。非确定性操作码的一个例子是:如果topofstack==0,则弹出。 编辑: 如果您确实有一组确定的操作码和堆栈深度不变,那么就不需要访问程序的每个可能路径。通过cfg进行一次fs/bfs就足以确定最大的堆栈深度。这可以在线性时间内完成(取决于指令的数量),但不能更快。
评估当前基本块点的传出边缘是否仍需要评估的基本块不应与性能相关。即使在最坏的情况下,每个指令都是
|
2
2
考虑到您的语言似乎没有任何用户输入,所有程序都将以相同的方式一直计算。因此,可以在执行期间执行程序并跟踪最大堆栈大小。可能不是你想要的。 至于您的路径论证:请注意,跳跃允许循环,因此,在没有进一步分析的情况下,循环可能意味着不终止和堆栈溢出(即每个循环执行后堆栈大小增加)。[如果存在循环,n个节点仍然意味着无限多的路径] 您可能能够执行某种形式的 abstract interpretation 。 关于来自ivlad的评论:简单地计算push是错误的,因为存在可能的循环。 我不确定if语句的语义是什么,所以这也很有用:假设if语句的标签只能是一个前向标签(也就是说,您永远不能在代码中跳回来)。在这种情况下,你的路径计数论点又回到了现实中。实际上,生成的CFG将是一棵树(如果不复制代码,则为DAG)。在这种情况下,您可以做一个近似计数,通过自下而上计算推送的数量,然后在if语句的情况下为两个分支取最大推送的数量。它仍然不是最佳的正确结果,但是比简单的push语句计数产生更好的近似值。 |
danial · 如何在多个字符串的每个位置找到最频繁的字符 2 年前 |
Manny · 如何比较Perl中的字符串? 2 年前 |
Diret · 获取范围内每个数字的子倍数的算法 2 年前 |
Saif · 排序时python如何决定何时调用比较器? 2 年前 |