コールグラフ

コールグラフ (マルチグラフとも呼ばれる) とは、コンピュータプログラムのサブルーチン同士の呼び出し関係を表現した有向グラフである。具体的には、各ノードが手続きを表現し、各エッジ(f,g)は手続きfが手続きgを呼び出すことを示す。従って、循環したグラフは再帰的な関数呼び出しを示す。
コールグラフはプログラムの初歩的な解析の結果であり、プログラムを人間が可読なものにするため、あるいはたとえば手続き間の変数の追跡を行う解析といった発展的な解析のための基礎として用いることができる。コールグラフの簡単な利用方法は、一度も呼び出されない関数を見つけることである。
コールグラフは 動的でも静的でもありうる。動的なコールグラフはプログラムの実行結果の記録、たとえばプロファイラの出力である。従って、動的なコールグラフは正確であるが、プログラムの一度の実行結果を記述できるのみである。正確な静的コールグラフは非決定論的であり、静的なコールグラフ抽出の
アルゴリズムは一般的に過剰な見積もりに基づいている。つまり、実際に生じる各呼び出し関係もグラフ内に表現されるが、プログラムの実際の動作では一度も生じないいくつかの呼び出し関係も表現される。
コールグラフは正確さによって異なる形で表現することができる。より正確なコールグラフは長い計算時間と大きなメモリ消費量を代償として、たとえばプロファイラの出力結果などの形式により、実際のプログラムの振る舞いより正確に見積もることができるよう表現することができる。最も正確なコールグラフは「コンテキストを理解した」コールグラフ、すなわち各手続きについて手続きが呼び出されるコールスタックごとに別々のノードを持つようにしたものである。完全に「コンテキストを理解した」コールグラフは生成に膨大なメモリを消費するが計算は簡単に行うことができる。大規模なプログラムでは計算時間がかかりすぎるため、完全に「コンテキストを理解した」コールグラフを静的に求めることはできない。最も正確さが低いコールグラフは「コンテキストを理解しない」ものであり、各手続きについてノードを一つしか持たない。
動的なディスパッチを備えるJavaやC++などの言語では、静的なコールグラフを正確に求めるためにはエイリアス解析の結果を必要とする。逆に言えば、正確なエイリアスを求めるためにはコールグラフが必要である。静的な解析システムは二つを同時に求めることで、この相互に相手を必要とする問題(無限後退)を解決する。
コールグラフという用語はコンパイラやバイナリ変換のコミュニティでよく用いられる。

**コールグラフを生成するソフトウェア**

**自由ソフトウェアのコールグラフ生成ソフトウェア**
  codeviz : 静的なコールグラフ生成プログラム（対象プログラムは実行しない）。gccに対するパッチとして実装されており、Cおよび C++に対応している。
 egypt : 短いPerlスクリプトで、gccとGraphvizを用いてCプログラムの静的なコールグラフを生成する。
 gprof : GNU Binutilsの一部である。
 pycallgraph : Graphvizを用いてPythonプログラムのコールグラフを生成する。
  doxygen : Graphvizを用いて静的な呼び出し、継承の図を生成する。

**商用のコールグラフ生成ソフトウェア**
  aiCall : 無料の評価版が存在する。

**その他、関連するツール**
 Graphviz : テキストにより表現されたグラフ（コールグラフを含む）を図に変換する。GProfとともに用いる必要がある。UNIX哲学に基づき、gprof単体では図の描画を行わない。

**コールグラフの例**
例として、GProfが自分自身を解析した結果のコールグラフを示す。
index    called     name                              
index    called     name
72384/72384       sym_id_parse 54             
1508/1508        cg_dfn 15
3   72384             match 3                     
13   1508             pre_visit 13
----------------------                                
4/9052        cg_tally 32                 
1508/1508        cg_assemble 38
3016/9052        hist_print 49               
14   1508             propagate_time 14
6032/9052        propagate_flags 52          
4    9052             sym_lookup 4                
2             cg_dfn 15
----------------------                                
1507/1507        cg_assemble 38
5766/5766        core_create_function_syms 41|15   1507+2           cg_dfn 15
5    5766             core_sym_class 5            
1509/1509        is_numbered 9
----------------------                                
1508/1508        is_busy 11
24/1537        parse_spec 19               
1508/1508        pre_visit 13
1513/1537        core_create_function_syms 41|       1508/1508        post_visit 12
6    1537             sym_init 6                  
2             cg_dfn 15
----------------------                                
1511/1511        core_create_function_syms 41|       1505/1505        hist_print 49
7    1511             get_src_info 7              
16   1505             print_line 16
----------------------                                
2/9           print_name_only 25
2/1510        arc_add 31                  
1508/1510        cg_assemble 38              
1430/1430        core_create_function_syms 41
8    1510             arc_lookup 8                
17   1430             source_file_lookup_path 17
----------------------                                
1509/1509        cg_dfn 15                   
24/24          sym_id_parse 54
9    1509             is_numbered 9               
18     24             parse_id 18
----------------------                                
24/24          parse_spec 19
1508/1508        propagate_flags 52          
10   1508             inherit_flags 10            
24/24          parse_id 18
----------------------                                
19     24             parse_spec 19
1508/1508        cg_dfn 15                   
24/1537        sym_init 6
11   1508             is_busy 11                  
----------------------                                
24/24          main 1210
1508/1508        cg_dfn 15                   
20     24             sym_id_add 20
12   1508             post_visit 12               

**注釈**

**参考文献**
Ryder, B.G., "Constructing the Call Graph of a Program," Software Engineering, IEEE Transactions on , vol.SE-5, no.3pp. 216– 226, May 1979 
*Grove, D., DeFouw, G., Dean, J., and Chambers, C. 1997. Call graph construction in object-oriented languages. SIGPLAN Not. 32, 10 (Oct. 1997), 108-124. 
*Callahan, D.; Carle, A.; Hall, M.W.; Kennedy, K., "Constructing the procedure call multigraph," Software Engineering, IEEE Transactions on , vol.16, no.4pp.483–487, Apr 1990