(57)【要約】【課題】プログラムの実行時における動的な指標を使用することなく、並列計算機によって効率的に並列処理可能なプログラムへ修正するための、修正箇所をプログラマへ提示することができる。【解決手段】本発明の情報処理装置１０は、プログラムのソースコード１００から、１つ以上の入力データノードと１つの出力データノードとを有する依存グラフを作成する手段２と、依存グラフの１つ以上の入力データノードから、１つの出力データノードまでのパスごとにパス長を算出する手段４と、算出手段によって算出されたパス長の分散を算出する手段４とを備えることを特徴とする。【選択図】  図１
2009163662.tif 000002
【特許請求の範囲】
【請求項１】
プログラムのソースコードを記憶する記憶手段と、
前記記憶手段から前記ソースコードを読み出す読出手段と、
前記ソースコードから、前記ソースコードに含まれる複数の要素のそれぞれをノードとし、ノード間を枝で接続することによって依存関係を示す依存グラフを作成する作成手段と、
前記依存グラフの一部であって、データ入力を意味する要素のノードである入力データノードと、データ出力を意味する要素のノードである出力データノードとを含む部分依存グラフを、前記依存グラフから抽出する抽出手段と、
前記部分依存グラフについて、前記入力データノードから前記出力データノードまでのパスごとにパス長を算出する第１の算出手段と、
前記部分依存グラフに含まれるパスのパス長のちらばり度を算出する第２の算出手段とを備えることを特徴とする情報処理装置。
【請求項２】
前記部分依存グラフは、前記依存グラフに含まれる出力データノードと、その出力データノードとの依存関係を有するノードとを含むことを特徴とする請求項１に記載の情報処理装置。
【請求項３】
前記依存グラフに複数の出力データノードが含まれる場合、前記抽出手段は、前記依存グラフに含まれる出力データノードの数だけ前記部分依存グラフを抽出し、
前記複数の部分依存グラフのそれぞれは、前記依存グラフに含まれる出力データノードのそれぞれと、その出力データノードとの依存関係を持つノードとを含むことを特徴とする請求項２に記載の情報処理装置。
【請求項４】
前記作成した依存グラフに含まれる入力データノードと出力データノードとを指定する指定手段をさらに備え、
前記部分依存グラフは、前記指定手段によって指定された入力データノードを起点とし、前記指定手段によって指定された前記出力データノードを終点とするパスが経由するノードを含むことを特徴とする請求項１に記載の情報処理装置。
【請求項５】
前記指定手段によって複数の出力データノードが指定された場合、前記抽出手段は、前記指定手段によって指定された出力データノードの数だけ前記部分依存グラフを抽出し、
前記複数の部分依存グラフのそれぞれは、当該指定された出力データノードのそれぞれを終点とし、前記指定手段によって指定された入力データノードを起点とするパスが経由するノードを含むことを特徴とする請求項４に記載の情報処理装置。
【請求項６】
前記ちらばり度が大きい順に、前記抽出された部分依存グラフの順序付けする順序付手段と、
前記抽出された依存グラフの順序付け結果に応じて、部分依存グラフと、その部分依存グラフのちらばり度とを関連付けて出力する出力手段をさらに備えることを特徴とする請求項１乃至請求項５のいずれか１項に記載の情報処理装置。
【請求項７】
前記ちらばり度が大きい順に、前記抽出された部分依存グラフの順序付けする順序付手段と、
前記抽出された依存グラフの順序付け結果に応じて、部分依存グラフを識別する情報と、その部分依存グラフのちらばり度とを関連付けて出力する出力手段をさらに備えることを特徴とする請求項１乃至請求項５のいずれか１項に記載の情報処理装置。
【請求項８】
前記出力手段が、前記ちらばり度が最大である部分依存グラフについての情報を出力することを特徴とする請求項６または請求項７に記載の情報処理装置。
【請求項９】
前記プログラムのソースコードを、依存性抽出可能となるように変換する変換手段をさらに有することを特徴とする請求項１乃至請求項８のいずれか１項に記載の情報処理装置。
【請求項１０】
プログラムのソースコードを記憶する記憶手段と、
前記記憶手段から前記ソースコードを読み出す読出手段と、
前記読み出したソースコードから、前記ソースコードに含まれる複数の要素のそれぞれをノードとし、ノード間を枝で接続することによって依存関係を示す依存グラフを作成する作成手段と、
前記作成した依存グラフについて、データ入力を意味する要素のノードである入力データノードからデータ出力を意味する要素のノードである出力データノードまでのパスごとにパス長を算出する第１の算出手段と、
前記作成した依存グラフについて、前記依存グラフに含まれるパスのパス長の分散を算出する第２の算出手段とを備えることを特徴とする情報処理装置。
【請求項１１】
プログラムのソースコードを記憶手段へ記憶し、
前記記憶手段から前記ソースコードを読み出し、
前記ソースコードから、前記ソースコードに含まれる複数の要素のそれぞれをノードとし、ノード間を枝で接続することによって依存関係を示す依存グラフを作成し、
前記依存グラフの一部であって、データ入力を意味する要素のノードである入力データノードと、データ出力を意味する要素のノードである出力データノードとを含む部分依存グラフを、前記依存グラフから抽出し、
前記部分依存グラフについて、前記入力データノードから前記出力データノードまでのパスごとにパス長を算出し、
前記部分依存グラフに含まれるパスのパス長のちらばり度を算出することを特徴とする情報処理装置の制御方法。
【請求項１２】
コンピュータに、
プログラムのソースコードを記憶手段へ記憶する機能と、
前記記憶手段から前記ソースコードを読み出す機能と、
前記ソースコードから、前記ソースコードに含まれる複数の要素のそれぞれをノードとし、ノード間を枝で接続することによって依存関係を示す依存グラフを作成する機能と、
前記依存グラフの一部であって、データ入力を意味する要素のノードである入力データノードと、データ出力を意味する要素のノードである出力データノードとを含む部分依存グラフを、前記依存グラフから抽出する機能と、
前記部分依存グラフについて、前記入力データノードから前記出力データノードまでのパスごとにパス長を算出する機能と、
前記部分依存グラフに含まれるパスのパス長のちらばり度を算出する機能ととを実現させることを特徴とする情報処理装置の制御プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置、情報処理装置の制御方法、および情報処理装置の制御プログラムに関するものである。
【背景技術】
【０００２】
近年、複数のプロセッサが並列に演算処理を行う並列計算機は、演算処理能力の高さから、良く用いられている。しかし、この並列計算機によって効率的に並列処理可能なプログラムを、プログラマが記述するのは一般的に困難である。そこで、並列計算機による並列処理を考慮することなく記述されたプログラムを、並列計算機によって効率的に並列処理可能なプログラム（以下、並列度の高いプログラムと呼ぶ。）へ修正することが行われている（例えば、特許文献１。）。
【０００３】
上記特許文献１に開示されている技術では、プログラムを実際の動作環境で実行させて、実行時における動的な指標（トレース結果）に従い、プログラムのボトルネック部分を提示する。プログラマは、提示されたボトルネック部分のプログラムのソースコードを修正することによって、効率的に、並列度の高いプログラムへ改良することができる。
【特許文献１】特開平６−８３６０８号公報
【発明の開示】
【発明が解決しようとする課題】
【０００４】
上記特許文献１に開示されている技術では、プログラムを実際の動作環境で実行させて、実行時における動的な指標（トレース結果）に従い、プログラムのボトルネック部分を提示する。
【０００５】
しかし、プログラムを実際の動作環境で実行させた際の動的な指標に従ってプログラムのボトルネック部分を提示するため、プログラムを実行可能な状態とする必要があり、プログラマの負担が大きいという問題がある。さらに、実際の利用を反映した入力データセットを用意する必要があり、コストが増大するという問題がある。
【０００６】
本発明は、上記問題点を解決するためになされたものであって、プログラムの実行時における動的な指標を使用することなく、並列度の高いプログラムへ修正するための、修正箇所を提示することができる情報処理装置、情報処理装置の制御方法、および情報処理装置の制御プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００７】
上記目的を達成するために、本発明の実施形態に係る情報処理装置は、プログラムのソースコードを記憶する記憶手段と、前記記憶手段から前記ソースコードを読み出す読出手段と、前記ソースコードから、前記ソースコードに含まれる複数の要素のそれぞれをノードとし、ノード間を枝で接続することによって依存関係を示す依存グラフを作成する作成手段と、前記依存グラフの一部であって、データ入力を意味する要素のノードである入力データノードと、データ出力を意味する要素のノードである出力データノードとを含む部分依存グラフを、前記依存グラフから抽出する抽出手段と、前記部分依存グラフについて、前記入力データノードから前記出力データノードまでのパスごとにパス長を算出する第１の算出手段と、前記部分依存グラフに含まれるパスのパス長のちらばり度を算出する第２の算出手段とを備えることを特徴とする。
【発明の効果】
【０００８】
本発明によれば、プログラムの実行時における動的な指標を使用することなく、並列計算機によって効率的に並列処理可能なプログラムへ修正するための、修正箇所をプログラマへ提示することができる。
【発明を実施するための最良の形態】
【０００９】
以下、本発明の実施形態について説明する。
【００１０】
（実施形態）
図１は、本発明の実施形態に係る情報処理装置１０を示すブロック図である。  
本実施形態に係る情報処理装置１０は、依存グラフ作成部２と、抽出部３と、分散算出部４と、順序付部５と、出力部６とを備える。情報処理装置１０の入力は、プログラムのソースコードである。情報処理装置１０の出力は、入力されたプログラムのソースコード１００を並列度の高いプログラムのソースコードへ修正する際に、プログラマが修正することによって潜在的に性能（並列度）向上の余地が大きい領域を示す情報である。
【００１１】
依存グラフ作成部２は、入力されたプログラムのソースコードから、依存グラフを作成する。依存グラフ作成部２は、作成した依存グラフを抽出部３へ出力する。なお、依存グラフとは、プログラムのソースコードに含まれる各要素が、データノードあるいはプロセスノードとされ、データノードとプロセスノードとを交互に接続して作成される有向非循環グラフである。
【００１２】
抽出部３は、入力された依存グラフを、潜在的な性能向上の余地を算出する際の処理単位である部分依存グラフへ抽出する。抽出部３は、部分依存グラフを、分散算出部４へ出力する。
【００１３】
分散算出部４は、入力された部分依存グラフについて、潜在的な性能向上の余地を算出する。分散算出部４は、潜在的な性能向上の余地の算出が終了した後、抽出部３へ新たな部分依存グラフを出力させるための信号を送信する。分散算出部４は、部分依存グラフごとの潜在的な性能向上の余地の算出結果を、順序付部５へ出力する。
【００１４】
順序付部５は、部分依存グラフごとの潜在的な性能向上の余地の算出結果の中で、潜在的な性能向上の余地が大きい順に、部分依存グラフの順序付けを行う。順序付部５は、潜在的な性能向上の余地が大きい順に、各部分依存グラフに対応する領域のプログラムのソースコードを示す情報を、出力部６へ出力する。
【００１５】
出力部６は、ディスプレイ、プリンタなどであり、潜在的な性能向上の余地が大きい順に、各部分依存グラフと対応する領域のプログラムのソースコードを示す情報を表示する。
【００１６】
図２は、情報処理装置１０に入力されるプログラムのソースコード１００の一例を示す図である。  
このプログラムのトップレベルは、“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”（図２に示すソースコードの４行目）である。このプログラムトップレベルは、入力値が“ｉｎｐｕｔ”であり、出力値が“ｏｕｔｐｕｔ”であり、関数が“ａｂｓ”である。
【００１７】
関数“ａｂｓ”の本体は、図２に示すソースコードの１〜３行目である。“｜ａ｜−＞｜ｂ｜”は、関数“ａｂｓ”の入力が“ａ”であり、関数“ａｂｓ”の出力が“ｂ”であることを示す。
【００１８】
“ｉｆ（ａ＞０）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝”は、“ａ”が０より大きければ“ａ”を“ｂ”へ代入し、それ以外では“−ａ”を“ｂ”へ代入することを示す。
【００１９】
情報処理装置１０に入力されるプログラムは、以下の４つの要件、すなわちプログラムのソースコードから依存グラフを作成可能であるための要件（依存性抽出可能要件）を満足するものである。１つ目の要件は、一度変数に代入された値はその後変わることがない性質（静的単一代入の性質）を持つことである。２つ目の要件は、関数を呼び出す際に同一の値が引数として入力されたときには、同一の値を出力すること（関数の呼び出しに副作用がないこと）である。３つ目の要件は、ある変数の値が自分自身の変数の値に依存しないこと（値の依存関係に循環が無いこと）である。４つ目の要件は、関数の再帰呼び出しがないことである。なお、上記４つの要件を満足するプログラムは、有限な有向非巡回グラフとなる依存グラフで記述することができる。
【００２０】
上記４つの要件を満足するプログラム言語の構文の一例を擬似ＢＮＦ機能で示す。
【００２１】
・プログラムトップレベル：＝（代入式｜関数定義）の列
・関数定義：＝関数名＝本体
・本体：＝“｛“入出力リスト  文の列”｝”
・入出力リスト：＝“｜“コンマ区切りの変数名列”｜−＞｜“コンマ区切の変数名列”｜”
・文：＝代入式｜ＩＦ文｜関数定義
・IF文：＝“IF（“式”）ｔｈｅｎ｛“文の列”｝ｅｌｓｅ｛“文の列”｝”
・代入式：＝コンマ区切りの変数名列＝式
・式：＝値｜関数呼びだし｜変数名
・関数呼び出し：＝関数名“（“コンマ区切りの変数名”）”
値は、数値リテラルあるいは真偽値リテラルである。変数名および関数名は、任意の識別子とする。例えば、加算“＋”や減算“―”、比較“＞”などの二項演算子は、２つの入力を持つ関数呼び出しである。
【００２２】
ここでは、プログラムに含まれる要素は、式とＩＦ文である。
【００２３】
情報装置に入力されるプログラムのソースコード１００が、上記４つの要件を満足する言語モデルで記述されていない場合であっても、プログラムの特定の領域が局所的に上記４つの要件を満足していれば、当該プログラムの特定の領域のみを、情報処理装置１０に入力することによって、潜在的な並列度が算出できる。例えば、プログラミング言語Ｃで作成されたプログラムは、一般に、静的単一代入の性質を持たないが、静的単一代入の最適化（ＳＳＡ（ｓｔａｔｉｃ  ｓｉｎｇｌｅ  ａｓｓｉｇｎｍｅｎｔ）最適化）手法によって、静的単一代入の性質を満足するプログラムのソースコード１００を作成することができる。
【００２４】
図３は、依存グラフ作成部２が、図２に示されるプログラムのソースコード１００をから、作成した依存グラフ２００、２１０の一例を示す図である。
【００２５】
依存グラフとは、データとプロセスとをノードとして、データノードとプロセスノードとを交互に接続して作成される有向非循環グラフである。依存グラフは、プログラムのソースコード１００に指定される処理が、どのようなデータおよびプロセスから構成されているかを示すものである。プログラムソースコードに含まれる要素のそれぞれが、データノード、あるいはプロセスノードとされる。なお、プログラム全体を表現する依存グラフは、１つのプログラムトップレベルを表現した依存グラフと、１つ以上の関数などの依存グラフとの集合から構成される。
【００２６】
まず、依存グラフを構成するデータノード、プロセスノード、およびエッジ（枝）について説明する。  
図３では、データノードおよびプロセスノードはエッジ（図中では矢印で示される）により接続される。エッジによって接続されるノードであって、エッジの根元側のノードを親ノードと呼び、エッジの先端側のノードを子ノードと呼ぶ。
【００２７】
プロセスノードは、ある処理を持つ。プロセスノードは、１つ以上の親プロセスノードと、１つ以上の子プロセスノードとを持つ。プロセスノードの親データノードは、プロセスを実行するのに必要なデータを示す。プロセスノードの子データノードは、プロセスの実行結果を示す。
【００２８】
例えば、プロセスノードは、加算プロセスノードや、減算プロセスノード、代入プロセスノード、ＩＦプロセスノードであっても良く、再帰的に依存グラフで定義されていても良い。
【００２９】
例えば、加算プロセスノードは、２つの親データノードをもち、１つの子データノードを持つ。加算プロセスノードは、２つの親データノードが持つ値を加算し、その加算結果を子データノードへ与える。
【００３０】
代入プロセスノードは、１つの親データノードを持ち、１つの子データノードを持つ。代入プロセスノードは、親データノードが持つ値を、子データノードへ与える。
【００３１】
ＩＦプロセスノードは、条件分岐を示し、３つの親データノードを持ち、１つの子データノードを持つ。ＩＦプロセスノードの３つの親データノードは、それぞれ、条件を示す条件データノード、条件が真のときの値を示す真データノード、条件が偽のときの値を示す偽データノードである。ＩＦプロセスノードは、条件が真のときに真データノードの値を子データノードへ与え、条件が偽のときに偽データノードの値を子データノードへ与える。
【００３２】
再帰的に依存グラフで定義された再帰的プロセスノードは、親データノードの値を、再帰的に定義された依存グラフの入力データノードとする。再帰的に依存グラフで定義された再帰的プロセスノードは、再帰的に定義された依存グラフの出力データノードの値を、子データノードへ与える。
【００３３】
データノードは、ある値を持つ。データノードは、親プロセスノードを持たないか、１つの親プロセスノードを持つ。データノードは、子プロセスノードを持たないか、１つ以上の子プロセスノードを持つ。親プロセスノードを持たないデータノードを入力データノードと呼び、子プロセスノードを持たないデータノードを出力データノードと呼ぶ。
【００３４】
データノードの親プロセスノードは、データノードが持つ値が決定されるために必要なプロセスを示す。データノードの子プロセスノードは、データノードが持つ値を使用して行われるプロセスを示す。
【００３５】
依存グラフに含まれる入力データノードのすべてに値が与えられれば、依存グラフによって示される処理はすべて実行可能となる。なお、依存グラフが有向非巡回グラフであるため、一度データノードに与えられた値は変化しない。
【００３６】
次に、図３に示す依存グラフ２００、２１０について説明する。図３は、図２に示すプログラムのソースコード１００のプログラムトップレベルの依存グラフ２００と、トップレベルに含まれる関数“ａｂｓ”の依存グラフ２１０を示す。
【００３７】
プログラムトップレベルの依存グラフ２１０は、入力データノード“ｉｎｐｕｔ”２１１と、プロセスノード“ａｂｓ”２１２と、出力データノード“ｏｕｔｐｕｔ”２１３からなる。プロセスノード“ａｂｓ”２１２は、同じく図３に示される関数“ａｂｓ”の依存グラフ２１０によって定義される。
【００３８】
関数“ａｂｓ”の依存グラフ２１０は、入力データノード“０”２１１、２１３と、入力データノード“ａ”２１２と、減算プロセスノード２１４と、代入プロセスノード２１５と、比較プロセスノード２１６と、条件データノード２１９と、真データノード２１８と、偽データノード２１７と、ＩＦプロセスノード２２０からなる。
【００３９】
減算プロセスノード２１４は、入力データノード“０”２１１の値“０”から、入力データノード“ａ”２１２の値“ａ”を減算し、減算結果“−ａ”を偽データノード２１７へ与える。
【００４０】
代入プロセスノード２１５は、入力データノード“ａ”２１２の値“ａ”を真データノード２１８へ与える。
【００４１】
比較プロセスノード２１６は、入力データノード“ａ”２１２の値“ａ”と、入力データノード“０”２１３の値“０”を比較し、“ａ＞０”であれば“真”を、“ａ≦０”であれば“偽”を、条件データノード２１９へ与える。
【００４２】
ＩＦプロセスノード２２０は、比較プロセスノード２１６から“真”が与えられれば、真データノード２１８の持つ値“ａ”を、出力データノード“ｂ”２２１へ与える。一方、ＩＦプロセスノード２２０は、比較プロセスノード２１６から“偽”が与えられれば、偽データノード２１７の持つ値“−ａ”を、出力データノード“ｂ”２２１へ与える。
【００４３】
図４は、依存グラフ作成部２がプログラムのソースコード１００から依存グラフ２００、２１０を作成する際の動作を示すフローチャートである。  
まず、依存グラフ作成部２は、図２に示すプログラムのソースコード１００の構文解析を行い、構文木３００を作成する（ステップＳ１０１）。
【００４４】
次に、依存グラフ作成部２は、作成した構文木３００をもとに、関数表４００を作成する（ステップＳ１０２）。
【００４５】
次に、依存グラフ作成部２は、作成した関数表４００をもとに、依存グラフ２００、２１０を作成する（ステップＳ１０３）。
【００４６】
図５は、依存グラフ作成部２が、図２に示すプログラムのソースコード１００をもとに作成する構文木３００の一例である。なお、本実施形態では、プログラムのソースコードをもとに構文木を作成する方法については、特に限定するものではない。
【００４７】
プログラムトップレベル３０１は、代入式３０２と関数定義３０３から構成される。プログラムトップレベル３０１を構成する代入式３０２は、右辺の関数呼び出し３０４の戻り値を、左辺“ｏｕｔｐｕｔ”へ代入する。プログラムトップレベル３０１を構成する代入式３０２の右辺である関数呼び出し３０４は、“ｉｎｐｕｔ”を引数として、関数“ａｂｓ”を呼び出す。
【００４８】
プログラムトップレベル３０１を構成する関数定義３０３は、関数名“ａｂｓ”の関数を、関数本体３０５によって定義される。関数本体３０５は、入力“ａ”と、出力“ｂ”と、ＩＦ文３０６とから構成される。
【００４９】
関数本体３０５を構成するＩＦ文３０６は、条件式である関数呼び出し３０７と、真（ｔｈｅｎ節）の文である代入式３０８と、偽（ｅｌｓｅ節）の文である代入式３０９とから構成される。
【００５０】
ＩＦ文３０６の条件式である関数呼び出し３０７は、“ａ”を引数１とし、“０”を引数２とする関数“＞”である。なお、関数“＞”は、引数１“ａ”よりも引数２“０”が大きい場合に“真”を出力し、引数１“ａ”が引数２“０”以下である場合に“偽”を出力する。
【００５１】
真（ｔｈｅｎ節）の文である代入式３０８は、右辺“ａ”を左辺“ｂ”へ代入する。
【００５２】
偽（ｅｌｓｅ節）の文である代入式３０９は、右辺の関数呼び出し３１０の戻り値を、左辺“ｂ”へ代入する。偽（ｅｌｓｅ節）の文である代入式３０８の右辺である関数呼び出し３１０は、“０”を引数１とし、“ａ”を引数２とする関数“−”である。なお、関数“−”は、引数１“０”から引数２“ａ”を減算して、その減算結果を出力する関数である。
【００５３】
図６は、依存グラフ作成部２が、図５に示す構文木をもとに作成する関数表の一例である。なお、本実施形態では、構文木をもとに関数表を作成する方法については、特に限定するものではない。
【００５４】
図７は、依存グラフ作成部２が、構文木をもとに関数表を作成する際の動作を示すフローチャートである。図７（ａ）は、構文木３００をもとに関数表４００を作成する際の、依存グラフ作成部２の初期動作を示すフローチャートである。
【００５５】
まず、依存グラフ作成部２は、関数名と関数の内容とを対応させて記憶するための領域、即ち空の関数表を作成する（ステップＳ２０１）。
【００５６】
次に、依存グラフ作成部２は、プログラムトップレベル３０１を、関数表へ登録処理中の関数（以下、カレント関数と呼ぶ）とする（ステップＳ２０２）。
【００５７】
次に、依存グラフ作成部２は、カレント関数を関数表へ登録するためのルーチン（以下、登録ルーチン）を呼び出す（ステップＳ２０３）。なお、登録ルーチンの処理が終了すると、依存グラフ作成部２による関数表作成処理は終了する。
【００５８】
図７（ｂ）は、依存グラフ作成部２が登録ルーチンを呼び出し実行する際の動作を示すフローチャートである。
【００５９】
ここで、ステップＳ２０３において、プログラムトップレベル３０１をカレント関数として登録ルーチンを呼び出した際の依存グラフ作成部２の動作を説明する。
【００６０】
まず、依存グラフ作成部２は、カレント関数の関数名と関数の中身とを、関数表に登録する（第１登録ルーチンのステップＳ３０１）。カレント関数の関数名はプログラムトップレベル３０１であり、カレント関数の中身はプログラムトップレベル３０１を構成する代入式３０８、およびその代入式３０８より下の階層にある変数“ｏｕｔｐｕｔ”、関数呼び出し３１０、関数名“ａｂｓ”、引数１“ｉｎｐｕｔ”である。依存グラフ作成部２は、空の関数表に、関数名“プログラムトップレベル３０１”および関数の中身“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”を登録する（図６に示す関数表の１行目）。
【００６１】
次に、依存グラフ作成部２は、カレント関数に関数定義３０３が含まれるか否かを判定する（第１登録ルーチンのステップＳ３０２）。
【００６２】
カレント関数に関数定義３０３が含まれない場合は、依存グラフ作成部２は、呼び出し元へ戻る（第１登録ルーチンのステップＳ３０７）。
【００６３】
一方、カレント関数に関数定義３０３が含まれる場合は、依存グラフ作成部２は、カレント関数に含まれる関数定義３０３を取得する（第１登録ルーチンのステップＳ３０３）。即ち、依存グラフ作成部２は、プログラムトップレベル３０１に含まれる関数定義３０３（関数名“ａｂｓ”）を取得する。なお、カレント関数に複数の関数定義３０３が含まれる場合は、すべての関数定義３０３を取得する。
【００６４】
次に、依存グラフ作成部２は、取得した関数定義３０３のうちの１つをカレント関数とする（第１登録ルーチンのステップＳ３０４）。即ち、依存グラフ作成部２は、関数定義３０３（関数名“ａｂｓ”）をカレント関数とする。
【００６５】
次に、依存グラフ作成部２は、第２登録ルーチンを呼び出す（第１登録ルーチンのステップＳ３０５）。即ち、依存グラフ作成部２は、関数定義３０３（関数名“ａｂｓ”）をカレント関数として、登録ルーチンを呼び出す。
【００６６】
次に、依存グラフ作成部２は、カレント関数を関数表に登録する（第２登録ルーチンのステップＳ３０１）。カレント関数の関数名は“ａｂｓ”であり、カレント関数の中身は関数名“ａｂｓ”の関数本体３０５、およびその関数本体３０５より下の階層にある入力“ａ”、出力“ｂ”、ＩＦ文３０６などである。依存グラフ作成部２は、関数表に、関数名“ａｂｓ”および関数の中身“｛｜ａ｜→｜ｂ｜ｉｆ（ａ＞0）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝｝”を追加登録する（図６に示す関数表の２行目）。
【００６７】
次に、依存グラフ作成部２は、カレント関数“ａｂｓ”に関数定義３０３が含まれるか判定する（第２登録ルーチンのステップＳ３０２）。カレント関数“ａｂｓ”には関数定義３０３は含まれないため、依存グラフ作成部２は、呼び出し元（第１登録ルーチンのステップＳ３０５）へ戻る（第２登録ルーチンのステップ３０７）。
【００６８】
次に、依存グラフ作成部２は、第１登録ルーチンのステップＳ３０３で取得した関数定義３０３をすべて関数表へ登録したかを判定する（第１登録ルーチンのステップ３０６）。
【００６９】
取得した関数定義３０３をすべて関数表へ登録したと判定された場合は、依存グラフ作成部２は、呼び出し元へ戻る。依存グラフ作成部２は、プログラムトップレベル３０１に含まれる関数定義３０３（関数名“ａｂｓ”のみ）を関数表へ登録したので、呼び出し元（ステップＳ２０３）へ戻る（第１登録ルーチンのステップＳ３０７）。
【００７０】
一方、取得した関数定義３０３をすべて関数表へ登録していないと判定された場合は、依存グラフ作成部２は、ステップＳ３０３〜Ｓ３０５の処理を繰り返し行う。
【００７１】
以上のように処理行い、第１登録ルーチンの呼び出し元（ステップ２０３）へ戻れば、依存グラフ作成部２は、動作を終了する。
【００７２】
図８、９、１０は、依存グラフ作成部２が、関数表をもとに依存グラフを作成する際の動作を示すフローチャートである。なお、図３は、図６に示す関数表４００をもとに作成された依存グラフ２００、２１０の一例である。なお、本実施形態では、関数表をもとに依存グラフを作成する方法については、特に限定するものではない。
【００７３】
図８（ａ）は、関数表をもとに依存グラフを作成する際の、依存グラフ作成部２の初期動作を示すフローチャートである。  
まず、依存グラフ作成部２は、関数表４００から関数を１つ取得する（ステップＳ４０１）。即ち、依存グラフ作成部２は、図６の関数名“トップレベル”と関数の内容“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”とを取得する。
【００７４】
次に、依存グラフ作成部２は、取得した関数についての依存グラフを作成するための領域（以下では、グラフ領域と呼ぶ）を作成する（ステップＳ４０２）。
【００７５】
次に、依存グラフ作成部２は、関数の入出力リストに対応する入力データノードおよび出力データノードを作成する（ステップＳ４０３）。プログラムトップレベルの入力は“ｉｎｐｕｔ”、出力は“ｏｕｔｐｕｔ”である。依存グラフ作成部２は、グラフ領域に、入力データノード“ｉｎｐｕｔ”および出力データノード“ｏｕｔｐｕｔ”を作成する。
【００７６】
次に、依存グラフ作成部２は、関数に含まれる代入式およびＩＦ文の集合を取得する（ステップＳ４０４）。即ち、依存グラフ作成部２は、プログラムトップレベルに含まれる代入式 “ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”を取得する。
【００７７】
次に、依存グラフ作成部２は、取得した文集合からの依存グラフを作成するためのルーチン（以下、第１作成ルーチンと呼ぶ）を呼び出す（ステップＳ４０５）。即ち、依存グラフ作成部２は、代入式 “ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”からなる文集合に関しての依存グラフ２００を作成する。
【００７８】
図８（ｂ）は、依存グラフ作成部２が生成ルーチンを呼び出し実行する際の動作を示すフローチャートである。  
まず、依存グラフ作成部２は、文集合から文を１つ取り出す（第１作成ルーチンのステップＳ５０１）。即ち、依存グラフ作成部２は、代入式 “ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”からなる文集合から、代入式“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”を取り出す。
【００７９】
次に、依存グラフ作成部２は、取り出した文が代入式かＩＦ文かを判定する（第１作成ルーチンのステップＳ５０２）。
【００８０】
取り出した文が代入式の場合（第１作成ルーチンのステップＳ５０２の“代入式）、依存グラフ作成部２は、代入式の依存グラフを作成するためのルーチン（代入式ルーチン）を呼び出し、依存グラフを作成する（第１作成ルーチンのステップＳ５０３）。なお、代入式ルーチンを呼び出し実行する際の、依存グラフ作成部２の動作については後述する。
【００８１】
取り出した文がＩＦ文の場合（第１作成ルーチンのステップＳ５０２の“ＩＦ文”）、依存グラフ作成部２は、ＩＦ文の依存グラフを作成するためのルーチン（ＩＦ文ルーチン）を呼び出し、依存グラフを作成する（第１作成ルーチンのステップＳ５０４）。なお、ＩＦ文ルーチンを呼び出し実行する際の、依存グラフ作成部２の動作については後述する。
【００８２】
代入式ルーチンを呼び出し実行することによって、代入式 “ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”の依存グラフ２００を作成したあと、依存グラフ作成部２は、文集合に含まれるすべての文の依存グラフを作成したか否かを判定する（第１作成ルーチンのステップＳ５０５）。
【００８３】
文集合に含まれるすべての文の依存グラフを作成していないと判定された場合（第１作成ルーチンのステップＳ５０５の“いいえ”）、依存グラフ作成部２は、文集合に含まれる文であって、まだ依存グラフを作成していない文に対して、ステップＳ５０１〜Ｓ５０４の処理を行い、依存グラフを作成する。
【００８４】
一方、文集合に含まれるすべての文の依存グラフを作成したと判定された場合（第１作成ルーチンのステップＳ５０５の“はい”）、依存グラフ作成部２は、呼び出し元（ステップＳ４０５）に戻る。
【００８５】
次に、依存グラフ作成部２は、関数表４００に登録されたすべての関数を処理したか否かを判定する（ステップＳ４０６）。
【００８６】
関数表４００に登録されたすべての関数を処理したと判定された場合（ステップＳ４０６の“はい”）、依存グラフ作成部２は、依存グラフ作成の処理に関する動作を終了する。
【００８７】
一方、関数表４００に登録されたすべての関数を処理していないと判定された場合（ステップＳ４０６の“いいえ”）、依存グラフ作成部２は、関数表４００に登録された残りの関数についても、ステップＳ４０１〜Ｓ４０５の処理を行い、依存グラフを作成する。
【００８８】
ここで、依存グラフ作成部２は、関数表４００に登録された関数“プログラムトップレベル”と“ａｂｓ”のうち、関数“プログラムトップレベル”についてしか処理を行っていないので、すべての関数を処理していないと判定する。
【００８９】
次に、依存グラフ作成部２は、関数“ａｂｓ”に関して、ステップＳ４０１〜Ｓ４０３の処理を行う。
【００９０】
次に、依存グラフ作成部２は、ステップＳ４０４において、関数“ａｂｓ”に含まれる文の集合、即ち、ＩＦ文“ｉｆ（ａ＞0）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝”を取得する。
【００９１】
次に、依存グラフ作成部２は、ＩＦ文“ｉｆ（ａ＞0）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝”からなる文集合の依存グラフを作成するためのルーチン（以下、第２作成ルーチンと呼ぶ）を呼び出し、実行する。
【００９２】
依存グラフ作成部２は、第２作成ルーチンのステップＳ５０１〜Ｓ５０５において、ＩＦ文“ｉｆ（ａ＞0）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝”の依存グラフを作成するためのルーチン（ＩＦ文ルーチン）を呼び出し、依存グラフを作成する。
【００９３】
このようにして、依存グラフ作成部２は、関数“プログラムトップレベル３０１”と“ａｂｓ”の依存グラフ２１０を作成し、動作を終了する。
【００９４】
図９は、依存グラフ作成部２が代入文ルーチンを呼び出し実行する際の動作を示すフローチャートである。なお、以下では、関数“プログラムトップレベル３０１”に含まれる代入式“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”の依存グラフを作成する例を用いて、依存グラフ作成部２の動作を説明する。なお、この代入式では、右辺が代入元であり、左辺が代入先であるものとする。
【００９５】
まず、依存グラフ作成部２は、代入式の左辺に対応するデータノードが作成済みか否かを判定する（ステップＳ６０１）。即ち、依存グラフ作成部２は、代入式の左辺“ｏｕｔｐｕｔ”に対応するデータノードを既に図８のステップＳ４０３で作成しているため、代入式の左辺に対応するデータノードが作成済みと判定する（ステップＳ６０１の“はい”）。
【００９６】
一方、代入式の左辺に対応するデータノードがまだ作成されていないと判定された場合（ステップＳ６０１の“いいえ”）、依存グラフ作成部２は、代入式の左辺に含まれる変数に対応するデータノードを作成する（ステップＳ６０２）。なお、代入式の左辺に含まれる変数が複数あった場合には、依存グラフ作成部２は、それぞれの変数に対してデータノードを作成する。
【００９７】
次に、依存グラフ作成部２は、代入式の右辺が、値、変数名、あるいは、関数呼び出しのいずれであるかを判定する（ステップＳ６０３）。即ち、依存グラフは、代入式の右辺“ａｂｓ（ｉｎｐｕｔ）”が関数呼び出しであると判定する。
【００９８】
代入式の右辺“ａｂｓ（ｉｎｐｕｔ）”が関数呼び出しである場合（ステップＳ６０３の“関数呼び出し”）、依存グラフ作成部２は、関数の引数に対応するデータノードを作成済みか否かを判定する（ステップＳ６０９）。即ち、依存グラフ作成部２は、関数の引数“ｉｎｐｕｔ”に対応するデータノードを既に図８のステップＳ４０３で作成しているため、関数の引数に対応するデータノードが作成済みと判定する（ステップＳ６０９の“はい”）。
【００９９】
一方、関数の引数に対応するデータノードがまだ作成されていないと判定された場合（ステップＳ６０９の“いいえ”）、依存グラフ作成部２は、関数の引数に含まれる変数に対応するデータノードを作成する（ステップＳ６１０）。なお、関数の引数に含まれる変数が複数あった場合には、依存グラフ作成部２は、それぞれの変数に対してデータノードを作成する。
【０１００】
次に、依存グラフ作成部２は、関数プロセスノードを作成する（ステップＳ６１１）。即ち、依存グラフ作成部２は、関数“ａｂｓ”に対応するプロセスノードを作成する。
【０１０１】
次に、依存グラフ作成部２は、関数の引数に対応するデータノードと、関数に対応するプロセスノードと、代入式の左辺に対応するデータノードとを接続する（ステップＳ６１２）。即ち、依存グラフ作成部２は、関数の引数に対応するデータノード“ｉｎｐｕｔ”を根元側とし、関数“ａｂｓ”に対応するプロセスノードを先端側とするエッジにより、データノード“ｉｎｐｕｔ”と関数プロセスノード“ａｂｓ”を接続する。さらに、依存グラフ作成部２は、関数プロセスノード“ａｂｓ”を根元側とし、代入式の右辺に対応するデータノード“ｏｕｔｐｕｔ”を先端側とするエッジにより、関数プロセスノード“ａｂｓ”とデータノード“ｏｕｔｐｕｔ”とを接続する。
【０１０２】
このように、依存グラフ作成部２は、代入式“ｏｕｔｐｕｔ＝ａｂｓ（ｉｎｐｕｔ）”の依存グラフを作成し、代入式ルーチンの呼び出し元（第１作成ルーチンのＳ５０４）へ戻る。
【０１０３】
以下では、図９のステップＳ６０３で、代入式の右辺が値あるいは変数名と判定された場合の依存グラフ作成部２の動作について説明する。
【０１０４】
代入式の右辺が値である場合（ステップＳ６０３の“値”）、依存グラフ作成部２は、代入式の左辺に対応するデータノードへ、代入式の右辺の値を代入する（ステップＳ６０１）。そして、依存グラフ作成部２は、代入式ルーチンの呼び出し元へ戻る。
【０１０５】
代入式の右辺が変数名である場合（ステップＳ６０３の“変数名”）、依存グラフ作成部２は、代入式の右辺に含まれる変数名に対応するデータノードが作成済みかを判定する（ステップＳ６０５）。
【０１０６】
代入式の右辺に含まれる変数名に対応するデータノードがまだ作成されていないと判定された場合のみ（ステップＳ６０５の“いいえ”）、依存グラフ作成部２は、代入式の右辺に含まれる変数名に対応するデータノードを作成する（ステップＳ６０６）。
【０１０７】
次に、依存グラフ作成部２は、代入プロセスノード２１５を作成する（ステップＳ６０７）。
【０１０８】
次に、依存グラフ作成部２は、代入式の右辺に対応するデータノードと、代入プロセスノード２１５と、代入式の左辺に対応するデータノードとを接続する（ステップＳ６０８）。即ち、依存グラフ作成部２は、代入式の右辺に対応するデータノードを根元側とし、代入プロセスノード２１５を先端側とするエッジにより、代入式の右辺に対応するデータノードと代入プロセスノード２１５とを接続する。さらに、依存グラフ作成部２は、代入プロセスノード２１５を根元側とし、代入式の右辺に対応するデータノードを先端側とするエッジにより、代入プロセスノード２１５と代入式の右辺に対応するデータノードとを接続する。
【０１０９】
このように、依存グラフ作成部２は、代入式の依存グラフを作成し、代入式ルーチンの呼び出し元へ戻る。
【０１１０】
図１０は、依存グラフ作成部２がＩＦ文ルーチンを呼び出し実行する際の動作を示すフローチャートである。なお、以下では、関数“ａｂｓ”に含まれるＩＦ文“ｉｆ（ａ＞0）ｔｈｅｎ｛ｂ＝ａ｝ｅｌｓｅ｛ｂ＝−ａ｝”の依存グラフ２１０を作成する例を用いて、依存グラフ作成部２の動作を説明する。
【０１１１】
まず、依存グラフ作成部２は、ＩＦプロセスノード２２０を作成する（ステップＳ７０１）。
【０１１２】
次に、依存グラフ作成部２は、ＩＦ文の条件に含まれる文集合を取得する（ステップＳ７０２）。即ち、依存グラフ作成部２は、ＩＦ文の条件“ａ＞０”から構成される文集合を取得する。
【０１１３】
次に、依存グラフ作成部２は、取得した文集合（ＩＦ文の条件“ａ＞０”）の依存グラフを作成するための作成ルーチンを呼び出し実行する（ステップＳ７０３）。なお、ＩＦ文の条件“ａ＞０”は、“ａ”が０より大きいときに真を、“ａ”が０未満のときに偽を、条件データノード２１９へ代入する代入式とみなされる。
【０１１４】
次に、依存グラフ作成部２は、ＩＦ文のｔｈｅｎ側、即ち、条件が真であったときに実行される処理を記述する文集合を取得する（ステップＳ７０４）。即ち、依存グラフ作成部２は、代入式“ｂ＝ａ”から構成される文集合を取得する。
【０１１５】
次に、依存グラフ作成部２は、取得した文集合（代入式“ｂ＝ａ”）の依存グラフを作成するための作成ルーチンを呼び出し実行する（ステップＳ７０５）。なお、ＩＦ文のｔｈｅｎ側の処理“ｂ＝ａ”は、入力データノード“ａ”を、真データノード２１８へ入力する代入文と見なされる。
【０１１６】
次に、依存グラフ作成部２は、ＩＦ文のｅｌｓｅ側、即ち、条件が偽であったときに実行される処理を記述する文集合を取得する（ステップＳ７０６）。即ち、依存グラフ作成部２は、代入式“ｂ＝−ａ”から構成される文集合を取得する。
【０１１７】
次に、依存グラフ作成部２は、取得した文集合（代入式“ｂ＝−ａ”）の依存グラフを作成するための作成ルーチンを呼び出し実行する（ステップＳ７０７）。なお、ＩＦ文のｅｌｓｅ側の処理“ｂ＝−ａ”は、入力データノード“０”の値“０”から入力データノード“ａ”の値“ａ”を減算した結果を、偽データノード２１７へ入力する代入文と見なされる。
【０１１８】
次に、依存グラフ作成部２は、条件データノート、真データノード２１８、および偽データノード２１７と、ＩＦプロセスノード２２０とを接続する（ステップＳ７０８）。即ち、依存グラフ作成部２は、条件データノート２１９を根元側としＩＦプロセスノード２２０を先端側とするエッジによって、条件データノード２１９とＩＦプロセスノード２２０とを接続する。依存グラフ作成部２は、真データノード２１８ を根元側としＩＦプロセスノード２２０を先端側とするエッジによって、真データノード２１８とＩＦプロセスノード２２０とを接続する。依存グラフ作成部２は、偽データノード２１７を根元側としＩＦプロセスノード２２０を先端側とするエッジによって、偽データノード２１７とＩＦプロセスノード２２０とを接続する。
【０１１９】
次に、依存グラフ作成部２は、ＩＦプロセスノード２２０と出力データノードとを接続する（ステップＳ７０９）。ＩＦプロセスノード２２０を根元側とし、出力データノード“ｂ”２２１を先端側とするエッジによって、ＩＦプロセスノード２２０と出力データノード“ｂ”２２１とを接続する。
【０１２０】
このように、依存グラフ作成部２は、ＩＦ文の依存グラフを作成し、ＩＦ文ルーチンの呼び出し元（第２作成ルーチンのステップＳ５０３）へ戻る。
【０１２１】
以上、図８、９、１０を用いて説明したように、依存グラフ作成部２は、図６に示す関数表をもとに、図３に示す依存グラフを作成する。
【０１２２】
抽出部３は、依存グラフ作成部２が作成した依存グラフ（図３）から、潜在的な性能向上の余地を算出する際の処理単位である部分依存グラフを抽出する。即ち、抽出部３は、依存グラフに含まれる出力データノードごとに、出力データノードと依存関係を持つノードを抽出して、１つ以上の入力データノードと１つの出力データノードとを有する依存グラフへ抽出する。なお、抽出部３は、出力データノードごとに、出力データノードからエッジを逆向きにたどって到達可能なノードのみを抽出することによって、出力データノードと依存関係を持つノードを抽出する。
【０１２３】
抽出部３は、プログラムトップレベルの依存グラフ２００、および関数“ａｂｓ”の依存グラフ２１０を抽出算出部へ出力する。
【０１２４】
図１１は、分散算出部４が、入力された依存グラフに含まれる複数のパスごとにパス長を算出し、そのパス長の分散を算出する際の動作を示すフローチャートである。以下では、一例として、図３に示す関数“ａｂｓ”の依存グラフ２１０が分散算出部４に入力されたものとして説明する。なお、本実施形態では、依存グラフから、依存グラフに含まれるパスのパス長の分散を算出する方法については、特に限定するものではない。
【０１２５】
まず、分散算出部４は、入力された依存グラフの各パスのパス長を記憶する記憶領域である集合Ｓを“空”に初期化する（ステップＳ８０１）。
【０１２６】
次に、分散算出部４は、依存グラフの入力データノードの集合と、出力データノードとを取得する（ステップＳ８０２）。即ち、分散算出部４は、図３に示す関数“ａｂｓ”の依存グラフの入力データノード“０”２１１、入力データノード“ａ”２１２、および入力データノード“０”２１３と、出力データノード“ｂ”２２１とを取得する。
【０１２７】
次に、分散算出部４は、入力データノードを１つ選択する（ステップＳ８０３）。例えば、分散算出部４は、入力データノード“ａ”２１２を選択する。
【０１２８】
次に、分散算出部４は、選択した入力データノードを始点、出力データノードを終点とするパスのパス長の集合Ｐを求める（ステップＳ８０４）。即ち、分散算出部４は、入力データノード“ａ”２１２を始点、出力データノード“ｂ”２２１を終点とするパスのパス長の集合を求める。
【０１２９】
入力データノード“ａ”２１２を始点、出力データノード“ｂ”２２１を終点とするパスは３つあって、1番目のパスは「入力データノード“ａ”２１２→減算プロセスノード２１４→偽プロセスノード２１７→ＩＦプロセスノード２２０→出力データノード“ｂ”２２１」であり、２番目のパスは「入力データノード“ａ”２１２→代入プロセスノード２１５→真プロセスノード２１８→ＩＦプロセスノード２２０→出力データノード“ｂ”２２１」であり、３番目のパスは「入力データノード“ａ”２１２→比較プロセスノード２１６→条件プロセスノード２１９→ＩＦプロセスノード２２０→出力データノード“ｂ”２２１」である。
【０１３０】
各パスのパス長をパスが経由するエッジの数とすれば、１番目のパスのパス長は“４”であり、２番目のパスのパス長は“４”であり、３番目のパスのパス長は“４”である。ここで、パス長の集合Ｐは、｛“４”、“４”、“４”｝となる。
【０１３１】
次に、分散算出部４は、求めたパス長の集合Ｐを、“空”に初期化したパス長の集合Ｓへ追加する（ステップＳ８０５）。ここで、パス長の集合Ｓは、｛“４”、“４”、“４”｝となる。
【０１３２】
次に、分散算出部４は、ステップＳ８０３で取得した入力データノードのうち、ステップＳ８０４〜Ｓ８０５からなる処理を行っていない入力データノードが存在するか否かを判定する（ステップＳ８０６）。即ち、分散算出部４は、ステップＳ８０３で取得した入力データノード“ａ”２１２、入力データノード“０”２１１、および入力データノード“０”２１３のうち、入力データノード“０”２１１、２１３については、まだステップＳ８０４〜Ｓ８０５からなる処理を行っていないと判定する。
【０１３３】
未処理の入力データノードが存在すると判定された場合（ステップＳ８０６の“はい”）、分散算出部４は、未処理の入力データノードを選択して、ステップＳ８０４〜Ｓ８０５からなる処理を行う。即ち、分散算出部４は、入力データノード“０”２１１を選択し（ステップＳ８０３）、入力データノード“０”２１１を始点、出力データノード“ｂ”２２１を終点とするパスのパス長の集合Ｐをもとめ（ステップＳ８０４）、集合Ｓに追加する（ステップＳ８０５）。なお、分散算出部４がいずれの入力データノード“０”を選択したとしても、パス長の集合Ｐは｛“４”｝となる。そのため、分散算出部４がステップＳ８０３で取得した入力データノードのすべてに対して、ステップＳ８０４〜Ｓ８０５からなる処理を行った場合は、集合Ｓは｛“４”、“４”、“４”、“４”、“４”｝となる。
【０１３４】
一方、未処理の入力データノードが存在しないと判定された場合（ステップＳ８０６の“いいえ”）、分散算出部４は、パス長の集合Ｓの分散を算出する（ステップＳ８０７）。即ち、分散算出部４は、パス長の集合Ｓ｛“４”、“４”、“４”、“４”、“４”｝の分散“０”を求める。なお、パス長の集合Ｓの分散は、各パス長から集合Ｓに含まれるパス長の平均値を減算したものを二乗した結果の平均値である。
【０１３５】
図１２は、入力データノードを始点とし、出力データノードを終点とするパスのパス長の集合Ｐを求める際（図１１のステップＳ８０４）の分散算出部４の動作を示すフローチャートである。なお、本実施形態では、パスのパス長の集合Ｐをもとめる方法については、特に限定するものではない。
【０１３６】
まず、分散算出部４は、始点データノードと終点データノードとが同一か否かを判定する（ステップＳ９０１）。
【０１３７】
始点データノードと終点データノードとが同一と判定された場合（ステップＳ９０１の“はい”）、分散算出部４は、パス長の集合として“０”を１つ含む集合｛“０”｝を返す（ステップＳ９０２）。
【０１３８】
一方、始点データノードと終点データノードとが同一でないと判定された場合（ステップＳ９０１の“いいえ”）、分散算出部４は、始点データノードの子プロセスノードを取得する（ステップＳ９０３）。
【０１３９】
次に、分散算出部４は、子プロセスノードの子データノード（以下では、孫ノードと呼ぶ）を取得する（ステップＳ９０４）。
【０１４０】
次に、分散算出部４は、孫ノードのうちの１つを始点とし、終点データノードを終点とする依存グラフに含まれるパスのパス長の集合を求める（ステップＳ９０５）。即ち、分散算出部４は、孫ノードのうちの１つを始点とし、終点データノードを終点として、ステップＳ９０１〜Ｓ９０６の処理（パス長算出ルーチン）の再帰呼び出しを行う。
【０１４１】
次に、分散算出部４は、パス長の集合に含まれるすべてのパス長に“２”を加え、その集合を返す（ステップＳ９０６）。
【０１４２】
このようにして、分散算出部４は、入力データノードを始点とし、出力データノードを終点とするパスのパス長の集合Ｐを求める。
【０１４３】
以上、図１１、１２を用いて説明したように、分散算出部４は、依存グラフごとに、依存グラフに含まれる複数のパスのパス長の分散を算出する。依存グラフごとに求められたパス長の分散は、依存グラフごとの、プログラマが修正することによって潜在的に性能（並列度）向上の余地の大きさを示す。パス長の分散が大きい依存グラフは、並列度を高くすることによって性能を向上させるためにプログラムの修正が推奨される箇所としてプログラマへ提示される。分散算出部４は、抽出部３から入力された依存グラフごとに、そのパス長の分散を算出し、その結果を順序付部５へ出力する。
【０１４４】
順序付部５は、依存グラフごとのパス長の分散が入力されると、パス長の分散が大きい順に依存グラフの順序付けを行い、潜在的な性能向上の余地が大きい順序として、出力部６へ出力する。出力部６は、順序付部５から入力された依存グラフに対応する領域ごとに、潜在的な性能向上の余地が大きさを、ユーザに見える形で表示する。
【０１４５】
出力部６には、パス長の分散が最大である依存グラフに対応する領域のみが提示されてもよく、依存グラフに対応する領域と潜在的な性能向上の余地の大きさを示す指標（その依存グラフのパス長の分散）とをあわせて提示してもよく、潜在的な性能向上の余地が大きい（パス長の分散の大きい）依存グラフそのものをグラフ形式で提示しても良い。このとき出力部６は、潜在的な性能向上の余地が大きい依存グラフに対応する領域のプログラムのソースコードを合わせて提示しても良い。
【０１４６】
このように、本実施形態に係る情報処理装置１０によれば、プログラムのソースコードから依存グラフを作成し、作成した依存グラフに含まれるパスのパス長の分散を潜在的に性能（並列度）向上の余地の大きさを示す指標とし、パス長の分散が大きい依存グラフに対応する領域を表示することで、プログラムの実行時における動的な指標を使用することなく、並列計算機によって効率的に並列処理可能なプログラムへ修正するための、修正箇所をプログラマへ提示することができる。
【０１４７】
なお、上記のように、本実施形態では、プログラマが修正することによって潜在的に性能（並列度）向上の余地の大きさを示す指標として、依存グラフごとのパス長の分散を用いたが、依存グラフに含まれるパスごとにパス長がどれほど異なっているか（ちらばり度）を示す指標であればよく、例えば、パス長の分散のほか、パス長の標準偏差などで有っても良い。
【０１４８】
また、上記実施形態では、抽出部３は、依存グラフに含まれる各出力データノードと依存関係を持つノードを抽出することによって、複数の部分依存グラフを抽出するものとした。
【０１４９】
しかし、抽出部３は、ユーザが指定する潜在的な性能向上の余地を算出する際の処理単位に応じて、依存グラフから部分依存グラフを抽出することができる。
【０１５０】
即ち、ユーザによって依存グラフに含まれる１つの入力データノードおよび１つの出力データノードが指定された場合に、抽出部３は、その１つの入力データノードと起点とし、その１つの出力データノードを終点とするパスが経由するノードを抽出する。このようにして、抽出部３は、１つの部分依存グラフを抽出する。
【０１５１】
ユーザによって、依存グラフに含まれる複数の入力データノードおよび１つの出力データノードが指定された場合に、抽出部３は、それら複数の入力データノードを起点とし、その１つの出力データノードを終点とするパスが経由するノードを抽出する。このようにして、抽出部３は、１つの部分依存グラフを抽出する。
【０１５２】
ユーザによって、依存グラフに含まれる複数の入力データノードおよび複数の出力データノードが指定された場合に、抽出部３は、出力データノードごとに、複数の入力データノードを起点とし、各出力データノードを終点とするパスが経由するノードを抽出する。このようにして、抽出部３は、ユーザによって指定された出力データノードの数の部分依存グラフを抽出する。
【０１５３】
このようにすることで、ユーザによって直接指定された領域を、潜在的な性能向上の余地を算出する際の処理単位とすることができ、ユーザの望む処理単位ごとに潜在的な性能向上の余地をユーザへ提示することができる。
【０１５４】
また、この情報処理装置１０は、例えば、汎用のコンピュータ装置を基本ハードウェアとして用いることでも実現することが可能である。すなわち、依存グラフ作成部２、抽出部３、分散算出部４、および順序付部５は、上記のコンピュータ装置に搭載されたプロセッサにプログラムを実行させることにより実現することができる。このとき、情報処理装置１０は、上記のプログラムをコンピュータ装置にあらかじめインストールすることで実現してもよいし、ＣＤ−ＲＯＭなどの記憶媒体に記憶して、あるいはネットワークを介して上記のプログラムを配布して、このプログラムをコンピュータ装置に適宜インストールすることで実現してもよい。
【０１５５】
なお、本発明は上記実施形態そのままに限定されるものではなく、実施段階ではその要旨を逸脱しない範囲で構成要素を変形して具体化できる。また、上記実施形態に開示されている複数の構成要素の適宜な組み合わせにより、種々の発明を形成できる。例えば、実施形態に示される全構成要素から幾つかの構成要素を削除してもよい。
【図面の簡単な説明】
【０１５６】
【図１】本発明の実施形態に係る情報処理装置１０の構成を示すブロック図。
【図２】プログラムのソースコード１００の一例を示す図。
【図３】依存グラフの一例を示す図。
【図４】本発明の実施形態に係る依存グラフ作成部２の動作を示すフローチャート。
【図５】構文木の一例を示す図。
【図６】関数表の一例を示す図。
【図７】本発明の実施形態に係る依存グラフ作成部２の動作を示すフローチャート。
【図８】本発明の実施形態に係る依存グラフ作成部２の動作を示すフローチャート。
【図９】本発明の実施形態に係る依存グラフ作成部２の動作を示すフローチャート。
【図１０】本発明の実施形態に係る依存グラフ作成部２の動作を示すフローチャート。
【図１１】本発明の実施形態に係る分散算出部４の動作を示すフローチャート。
【図１２】本発明の実施形態に係る分散算出部４の動作を示すフローチャート。
【符号の説明】
【０１５７】
１・・・記憶部
２・・・依存グラフ作成部
３・・・抽出部
４・・・分散算出部
５・・・順序付部
６・・・出力部
１０・・・情報処理装置
１００・・・プログラムのソースコード
２００・・・プログラムトップレベルの依存グラフ
２０１・・・入力データノード“ｉｎｐｕｔ”
２０２・・・プロセスノード
２０３・・・出力データノード“ｏｕｔｐｕｔ”
２１０・・・関数“ａｂｓ”の依存グラフ
２１１・・・入力データノード“０”
２１２・・・入力データノード“ａ”
２１３・・・入力データノード“０”
２１４・・・減算プロセスノード
２１５・・・代入プロセスノード
２１６・・・比較プロセスノード
２１７・・・偽プロセスノード
２１８・・・真プロセスノード
２１９・・・条件プロセスノード
２２０・・・ＩＦプロセスノード
２２１・・・出力データノード“ｂ”
３００・・・構文木
３０１・・・プログラムトップレベル
３０２、３０８、３０９・・・代入式
３０３・・・関数定義
３０４、３０７、３１０・・・関数呼び出し
３０５・・・関数本体
３０６・・・ＩＦ文
４００・・・関数表
【図１】
2009163662.tif 000003
【図２】
2009163662.tif 000004
【図３】
2009163662.tif 000005
【図４】
2009163662.tif 000006
【図５】
2009163662.tif 000007
【図６】
2009163662.tif 000008
【図７】
2009163662.tif 000009
【図８】
2009163662.tif 000010
【図９】
2009163662.tif 000011
【図１０】
2009163662.tif 000012
【図１１】
2009163662.tif 000013
【図１２】
2009163662.tif 000014