控制程序的流程图

时间:2011-04-07 19:51:39

标签: computer-science compiler-theory control-flow compiler-construction control-flow-graph

我现在正在使用编译器类,我们正处于构建CFG以实现优化的程度。我无法弄清楚的一件事是一个程序有多少CFG?我见过的每个例子似乎都是简单代码段的CGF。所以,如果你有一个程序说三个功能。你是否为每个功能都有一个单独的CFG,或者整个程序有一个大的CFG?

2 个答案:

答案 0 :(得分:3)

每个功能的CFG通过被叫方连接。如果一个函数调用另一个函数,例如:

0  void foo() { /* do stuff */ }
1  void bar() { /* do stuff */ }
2
3  void baz() {
4     foo();  // Callsite for foo. Control transfers to foo, then foo returns here.
5     bar();  // Callsite for bar. Control transfers to bar, then bar returns here.
6  }

然后baz的控件图将包含一个转到foo图表的边。同样地,因为foo最终将返回baz(以及可能从其中调用的任何其他地方),因此foo图的末尾将返回到在foo中致电baz后的声明。在这里,下一个语句是第5行对bar的调用。此时,bar调用点到bar的CFG有一条边,而bar的出口点有一条线。 {1}}回到baz的末尾。

基本上你需要考虑的是“接下来会执行什么代码”。这会告诉您控制图中边缘的位置。函数调用转移控制直到函数返回,这意味着从调用点到函数CFG的边缘再返回。

请注意,并非所有完整程序的CFG都是连接图。如果您正在分析的程序中有unreachable code,那么这将是它自己的完整CFG中未连接的部分。例如如果您在上面的示例中取消了对bar的调用,那么bar会将自己的图表放在一边,而bazfoo将通过边连接

答案 1 :(得分:1)

那么,你可以为每个函数构建一个CFG,然后 - 如果你想做什么,可以将它们组合成一个完整的函数。然而,整个程序CFG可能非常大,因此它们通常不能很好地作为示例。