Practical differences between control flow graph and call (flow?) graph?

Wikipedia defines a call graph as a representation of the calling relationships between subroutines in a program. In a call graph, an edge between two nodes f and g:

      f --> g

represents the fact that subroutine f calls subroutine g. A call graph gives an inter-procedural view of a program.

A control flow graph (CFG) provides finer "details" into the structure of the program as a whole, and of the subroutines in particular. For instance, the CFG of a subroutine f will make explicit all of the paths that are induced by a conditional branch:

                             / branch1 \
    begin --> condition -->             --> codeblock --> g --> end
                             \ branch2 /

This kind of CFG is used to build an intra-procedural view of a subroutine.


Call graphs (CG) and control flow graphs (CFG) consist of nodes and edges. CG is interprocedural, nodes represent subroutines (methods, functions, ...), while edges represent the relationship caller-called between two subroutines (e.g., A->B, "A" is the caller subroutine, while "B" is the called subroutine). CFG is intraprocedural, nodes represent program statements, including called subroutines but also conditionals, while edges represent the flow of the program. When CG and CFG are combined, it is called interprocedural control flow graph (ICFG). CFG generation is more resource-intensive than CG but more detailed.