(57)【要約】【課題】複数の関数コールが含まれるプログラムコードに対し、プログラムコードの構造を変換することでデータ転送量を削減し、処理の高速化を実現する。また、同プログラムコードに対し、タスク並列可能なタスク並列コードに変換することで、マルチコア上で動作可能なコードとし、処理の高速化を実現する。【解決手段】Ｃ言語などで記述されたコードであるオリジナルコードに対し、コード構造変換部によりコードの構造を変換して最適通信量コードを生成するプログラムコード構造変換装置であって、コード構造変換部は、複数の関数コールを有するオリジナルコードを入力し、１階層のフラットなコードであるフラット・コードに変換するインライン展開手段と、フラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成する通信量最適化手段とを有する。更に、最適通信量コードに対し、タスク並列可能なタスク並列コードに変換するタスク分割部を有する。【選択図】図１７
2012014526.tif 000002
【特許請求の範囲】
【請求項１】
高級言語で記述されたプログラムコードであるオリジナルコードに対し、プログラムコード構造変換部でコードの構造を変換してフラット・コードを生成するプログラムコードの構造変換装置であって、
前記プログラムコード構造変換部は、複数の関数コールを有する前記オリジナルコードを入力し、１階層のフラットなコードであるフラット・コードに変換するインライン展開手段を有し、
該インライン展開手段は、
前記オリジナルコードから、関数定義を抽出する手段と、
抽出した前記関数に対して関数の戻り値を変換する手段と、
抽出した前記関数に対して関数の仮引数の変換を行う手段と、
前記関数を関数コールする上位関数に対して関数コール個所を抽出する手段と、
前記関数コール個所に等価変換を施しながら該関数コール箇所に関数を展開し、フラット・コードを生成する手段とを有する
ことを特徴とするプログラムコードの構造変換装置。
【請求項２】
請求項１に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所に、インライン展開が不可能な関数が存在する場合に、該関数の位置を、該関数の意味が実質的に変わらない箇所に移動し、
該関数の戻り値を、新たに定義した仮変数に代入し、
該関数が記述された位置では、前記仮変数を利用し、前記関数コールを使用しない関数へ置換して前記関数コール箇所をインライン展開し、前記１階層のフラットなコードを生成する
ことを特徴とするプログラムコードの構造変換装置。
【請求項３】
請求項１に記載のプログラムコードの構造変換装置であって、
前記プログラムコード構造変換部は、通信量最適化部を備えており、
該通信量最適化部は、
前記インライン展開されたフラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成する
ことを特徴とするプログラムコードの構造変換装置。
【請求項４】
請求項１に記載のプログラムコードの構造変換装置であって、
前記関数展開したフラット・コードに対し、静的単一代入形式のフラット・コードに変換する手段を有する
ことを特徴とするプログラムコードの構造変換装置。
【請求項５】
請求項２に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所にｉｆ文のブロックが存在し、該ｉｆ文の条件式に前記関数コールが使用されている場合に、該条件式を前記ｉｆ文の前に移動して“ｌｏｃａｌ＿ｃｏｎｄ１”に仮代入し、前記ｉｆ文の条件式内では前記仮代入した“ｌｏｃａｌ＿ｃｏｎｄ１”に置換し、前記ｉｆ文内の条件式から前記関数コールを除去する
ことを特徴とするプログラムコードの構造変換装置。
【請求項６】
請求項２に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所にｗｈｉｌｅ文のブロックが存在し、該ｗｈｉｌｅ文の条件式に前記関数コールが使用されている場合に、該条件式を前記ｗｈｉｌｅ文の後に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入し、該仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”を前記ｉｆ文の新たな条件式とし、
該新たな条件式が成り立たない場合は、ｂｒｅａｋ文で前記ｗｈｉｌｅ文から抜け出す記述に置換えることより、前記ｗｈｉｌｅ文の条件式を前記関数コールを使用しないコードへ置換し、前記ｉｆ文内の条件式から前記関数コールを除去する
ことを特徴とするプログラムコードの構造変換装置。
【請求項７】
請求項２に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所にｄｏ−ｗｈｉｌｅ文のブロックが存在し、該ｄｏ−ｗｈｉｌｅ文の条件式に前記関数コールが使用されている場合に、該条件式を前記ｄｏ−ｗｈｉｌｅ文内の文の後に移動し、“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入して置換し、前記ｉｆ文内の条件式から前記関数コールを除去する
ことを特徴とするプログラムコードの構造変換装置。
【請求項８】
請求項２に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所にｆｏｒ文のブロックが存在し、該ｆｏｒ文のフィールドの引数に前記関数コールが使用されている場合に、該引数のフィールドを前記ｆｏｒ文の前に移動して“ｌｏｃａｌ＿ｃｏｎｄ１”に仮代入し、前記ｆｏｒ文の引数のフィールド内では、前記仮代入した“ｌｏｃａｌ＿ｃｏｎｄ１”に置換し、該ｆｏｒ文内のフィールドから前記関数コールを除去する
ことを特徴とするプログラムコードの構造変換装置。
【請求項９】
請求項２に記載のプログラムコードの構造変換装置であって、
前記フラット・コードを生成する手段は、
前記抽出された関数コール箇所にｓｗｉｔｃｈ文のブロックが存在し、該ｓｗｉｔｃｈ文のフィールドに引数に前記関数コールが使用されている場合に、該条件式を前記ｓｗｉｔｃｈ文の前に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入し、前記ｓｗｉｔｃｈ文の条件式内は、前記仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”に置換し、該ｓｗｉｔｃｈ文内の条件式から前記関数コールを除去する
ことを特徴とするプログラムコードの構造変換装置。
【請求項１０】
請求項３に記載のプログラムコードの構造変換装置であって、
前記通信量最適化部は、
前記フラット・コードからループ文を抽出し、抽出したループ文内のブロック内に、演算結果が配列変数に対する格納かを判断する手段と、
前記配列変数を生成する演算過程において、演算に必要な入力ノードに関しても、配列を使用するかを判断する手段と、
ループ内に対し、大局的番号付けと、ループアンロールと、複数のループを融合する手段と、
前記配列変数を演算する上で必要となる入力ノードに対し、小容量の配列名、若しくは単一の変数名に変数名をリネーミングする手段と、
リード参照が存在しない変数の宣言文と変数代入文を削除する手段とを有する
ことを特徴とするプログラムコードの構造変換装置。
【請求項１１】
高級言語で記述され複数の関数コールを有するプログラムコードであるオリジナルコードに対し、インライン展開を行って１階層のフラットなコードであるフラット・コードを生成するプログラムコード構造変換部と、
前記インライン展開されたフラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成する通信量最適化部と、
前記最適通信量コードに対し、タスク並列可能なタスク並列コードに変換するタスク分割部とを備えており、
前記タスク分割部は、前記最適通信量コードに対し、変数定義表のグループ情報で定義されたグループ指定において、同一グループ名の場合、各グローバル変数のリード／ライト参照を、１つのブロック内に収めるグループ化を行う手段と、入力のグローバル変数に対して、前記１つのブロック内のみで使用される変数をローカル変数としてブロック内に変数定義し、関数化する手段とを有する
ことを特徴とするプログラムコード構造変換装置。
【請求項１２】
請求項１１に記載のプログラムコードの構造変換装置であって、
前記プログラムコード構造変換部は、インライン展開手段と通信量最適化部とを有し、
前記インライン展開手段は、
前記オリジナルコードから関数定義を抽出する手段と、
抽出した前記関数に対して関数の戻り値を変換する手段と、
抽出した前記関数に対して関数の仮引数の変換を行う手段と、
前記関数を関数コールする上位関数に対して関数コール個所を抽出する手段と、
前記関数コール個所に等価変換を施しながら該関数コール箇所に関数を展開し、フラット・コードを生成する手段と、
複数の関数コールを有する前記オリジナルコードを入力し、１階層のフラットなコードであるフラット・コードに変換し、
前記通信量最適化部は、
前記フラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成し、
前記タスク分割部は、
前記最適通信量コードと、
該最適通信量コード内で使用される変数一覧に対し、その変数をグローバル変数に変換するかローカル変数に変換するかを指定する変数スコープ情報と、
どの変数を１つのタスク内に包括するかを指定するグループ情報で構成される変数定義表とを入力とする
ことを特徴とするプログラムコード構造変換装置。
【請求項１３】
請求項１２に記載のコード構造変換装置であって、
前記タスク分割部は、
前記変数定義表に示された前記変数スコープ情報を元に、各変数をグローバル変数、若しくはローカル変数に再定義する変数定義変換手段と、
関数の上部、若しくはコードの途中のポイントである新規検索対象個所から、初めてグローバル変数に対する代入が初めて発生する個所を探索するグローバル変数抽出手段と、
該抽出したグローバル変数に対する代入に対して、該グローバル変数の代入に必要となる入力ノードが、グローバル変数のみになるまで逆探索し、必要となる文を抽出し、抽出個所を一か所にまとめる変換を行う入力ノード逆探索手段並びにコード並べ替え手段と、
前記一か所にまとめた抽出個所の前後を中括弧“｛｝”で括り、中括弧“｛｝”で使用されるローカル変数の変数定義を中括弧“｛｝”内に複製するブロック化手段と、
前記グローバル変数抽出手段、前記入力ノード逆探索手段、前記コード並べ替え手段、及び前記ブロック化手段の一連のシーケンスを、ライト参照の存在する全グローバル変数に対して実行する手段とを有する
ことを特徴とするプログラムコード構造変換装置。
【請求項１４】
請求項１３に記載のコード構造変換装置であって、
前記タスク分割部は、
前記変数定義表に定義されたグループ情報を元に、複数の中括弧“｛｝”で括ったブロックに対し、データ依存解析により、複数のブロックを１つのブロックにマージ可能か不可能かを判断するグループ化判断手段と、
実際に複数のブロックを１つのブロックにマージするグループ化手段と、
該ブロック化した個所を抽出しブロック内の機能を関数化し、関数コールに置換する関数化手段とを有する
ことを特徴とするコード構造変換装置。
【請求項１５】
請求項１４に記載のコード構造変換装置であって、
生成された前記フラット・コードで記述された関数コールの羅列に対し、これらの関数をマルチタスクで動作可能とするために、前記各関数コール間にタスク分割の指示文を挿入する通信関数挿入手段を有することを特徴とする構造変換装置。
【請求項１６】
請求項１に記載のプログラムコードの構造変換装置であって、
該コード構造変換装置は、ネットワークを接続可能なポートを有するＰＣ本体と、表示装置と、メディアドライブと、記憶装置とを備えた情報処理装置により構成され、
前記プログラムコード構造変換部は、コード構造変換プログラム実行形式で構成されることを特徴とする情報処理装置。
【請求項１７】
高級言語で記述されたプログラムコードであるオリジナルコードに対し、該プログラムコードの構造を変換してフラット・コードを生成するコード構造変換プログラムであって、
コンピュータに、
複数の関数コールを有する前記オリジナルコードから、関数定義を抽出するステップ、
抽出した前記関数に対して関数の戻り値を変換するステップ、
抽出した前記関数に対して関数の仮引数の変換を行うステップ、
前記関数を関数コールする上位関数に対して関数コール個所を抽出するステップ、
前記関数コール個所に等価変換を施しながら該関数コール箇所に関数を展開し、フラット・コードを生成するステップ、及び
前記フラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成するステップ
を実行させるためのプログラム。
【請求項１８】
請求項１７に記載のコード構造変換プログラムであって、
前記コンピュータに、
前記関数コール個所に等価変換を施しながら該関数コール箇所に関数を展開し、フラット・コードを生成するステップにおいて、
前記抽出された関数コール箇所に、インライン展開が不可能な関数が存在する場合に、該関数の位置を、該関数の意味が実質的に変わらない箇所に移動するステップ、
該関数の戻り値を、新たに定義した仮変数に代入するステップ、及び
該関数が記述された位置では、前記仮変数を利用し、前記関数コールを使用しない関数へ置換して前記関数コール箇所をインライン展開し、前記１階層のフラットなコードを生成するステップ
を実行させるためのプログラム。
【請求項１９】
請求項１７に記載のコード構造変換プログラムであって、
前記コンピュータに、
前記最適通信量コードに対し、変数定義表のグループ情報で定義されたグループ指定において、同一グループ名の場合、各グローバル変数のリード／ライト参照を、１つのブロック内に収めるグループ化を行うステップ、及び
入力のグローバル変数に対して、前記１つのブロック内のみで使用される変数をローカル変数としてブロック内に変数定義し、関数化するステップ
を実行させるためのプログラム。
【請求項２０】
請求項１６に記載のコード構造変換プログラムであって、
前記コンピュータに、
前記最適通信量コードと、該最適通信量コード内で使用される変数一覧に対し、その変数をグローバル変数に変換するかローカル変数に変換するかを指定する変数スコープ情報と、どの変数を１つのタスク内に包括するかを指定するグループ情報で構成される変数定義表とを入力とするステップ、
前記変数定義表に示された前記変数スコープ情報を元に、各変数をグローバル変数、若しくはローカル変数に再定義する変数定義変換ステップ、
関数の上部、若しくはコードの途中のポイントである新規検索対象個所から、初めてグローバル変数に対する代入が初めて発生する個所を探索するグローバル変数抽出ステップ、
該抽出したグローバル変数に対する代入に対して、該グローバル変数の代入に必要となる入力ノードが、該グローバル変数のみになるまで逆探索し、必要となる文を抽出し、抽出個所を一か所にまとめる変換を行う入力ノード逆探索ステップ並びにコード並べ替えステップ、
前記一か所にまとめた抽出個所の前後を中括弧“｛｝”で括り、中括弧“｛｝”で使用されるローカル変数の変数定義を中括弧“｛｝”内に複製するブロック化ステップ、及び
前記グローバル変数抽出ステップ、前記入力ノード逆探索ステップ、前記コード並べ替えステップ、及び前記ブロック化ステップの一連のシーケンスを、ライト参照の存在する全グローバル変数に対して実行するステップ
を実行させるためのプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラムコードの構造変換装置、並びにコード構造変換プログラムに係る。特に、Ｃ言語などの高級言語で記述されたプログラムコードを入力とするコンパイラが生成する中間コードを生成する中間コード生成プログラム、及び、コンパイラ処理の前処理として、Ｃ言語で記述されたコードの構造を変換してコード自身生成するコード構造変換プログラム、並びに、前記中間コード生成プログラム、若しくは、コード構造変換プログラムが動作するコード構造変換装置に関する。また、本発明は、プログラムコードの構造変換方法にも関係する。
【背景技術】
【０００２】
近年、Ｃ言語などの高級言語で記述されたソフトウェアのコード規模は飛躍的に増加し、このソフトウェアを実行するＣＰＵコアには、より高い性能が求められている。また、ソフトウェアをＣＰＵで実行可能なオブジェクト形式に変換するコンパイラの最適化性能が向上し、同一のソフトウェアでも、コンパイルの最適化方式により高速に処理を実現可能な状況となっている。
コンパイラの基本的動作は、コード上で定義された各変数に関してデータ依存性を解析し、ＣＰＵコアで実行する際の性能劣化要因を、データ依存性が破壊されない範囲にて、コードの並べ替えを行い、性能向上を行うものである。
【０００３】
例えば、特許文献１に開示されるコンパイル方式では、ループ内の不変式をループ外に移動する手段により実行すべき演算数を削減することで、性能向上を実現している。また、特許文献２に開示されるコンパイル方式では、ループ回数が異なる複数のループに対し、ループの融合を行うことにより、演算数を削減し、性能向上を実現する。
【０００４】
また、主として半導体により構成するＣＰＵコアは、ムーアの法則に従い、年々、動作周波数向上による高速化が進んできた。一方、半導体の微細化に伴う消費電力の増加に従い、動作周波数の向上のみの性能向上には限界が表れ始め、近年では、複数のコアによる並列処理可能なマルチコア環境へと移行している。従来は、大規模なソフトウェアの処理性能向上には、動作周波数向上の恩恵により実現出来ていたが、マルチコア化が進む現在では、１つのコードを、並列所化可能な処理単位で分割し、マルチコアで並列に処理することで、性能向上を行っている。なお、本発明では、この並列処理可能な処理単位をタスクと定義し、このような並列化をタスク並列と定義する。近年では、タスク分割を実現可能なオープンソースの標準規格や並列化コンパイラなどの技術が発展段階にある。
【０００５】
例えば、特許文献３に開示されるコンパイル方式では、マルチコア間のデータキャッシュに格納されるデータの配置を最適化することにより、キャッシュ競合により発生する性能低下を抑止することができる。
【０００６】
また近年の潮流として、ソフトウェアのコード規模の増加に対して、オープンソースや標準ライブラリなどで定義された関数ライブラリや変数の構造体などを利用してソフトウェアの開発を行う傾向にある。これらのオープンソースでは、数行〜数百行のコード規模を１つの関数ライブラリとし、関数ライブラリとのデータの受け渡しを容易とするため、標準的な構造体で変数群をまとめることにより、ソフトウェア開発者は、少ないコード記述量で、大規模かつ複雑な機能のコーディングを可能とし、コーディング期間の短縮と、可読性の高いコードを得ることが可能である。
【０００７】
例えば、簡単なオープンソースの例として、ＡＮＳＩ規格で定義されている＜ｍａｔｈ．ｈ＞では、指数関数“ｅｘｐ（）”やサイン関数“ｓｉｎ（）”などが定義される。＜ｍａｔｈ．ｈ＞が定義される前のコーディングでは、これら複雑な指数関数やサイン関数の機能に対し、サブルーチン等を利用してコーディングする必要があり、コーディング量が大きく、またコードの可読性も低かった。しかしながら、＜ｍａｔｈ．ｈ＞のような標準ライブラリを利用することで、これら２つの問題を解決できる。
【０００８】
また、近年ではより複雑な機能を関数として定義したオープンソースによる標準ライブラリもあり、例えば、非特許文献１で開示されるＯｐｅｎＣＶ（Ｏｐｅｎ  Ｓｏｕｒｃｅ  Ｃｏｍｐｕｔｅｒ  Ｖｉｓｉｏｎ）等である。ＯｐｅｎＣＶでは、画像処理やパターン認識などの複雑な処理がライブラリ化され、ソフトウェア開発者にとって、よりコーディング量の少ないコード記述が実現出来る。
【０００９】
図２９、図３０を用いて、ＯｐｅｎＣＶを利用して記述するコード例について説明する。  
図２９はＯｐｅｎＣＶ標準ライブラリを使用して記述したコード例を示すための図である。本説明では、映像処理を例にして説明する。  
１行目の３０は、ＩｐｌＩｍａｇｅ構造体で定義された配列変数の定義であり、４つの変数ｓｒｃ＿ｉｍｇ、ｄｓｔ０、ｄｓｔ１、ｄｓｔ２からなる。本構造体では、主として画像の縦と横のサイズ及び、これらの画像サイズにて画像自身を表現する２次元配列らが定義される。本定義によれば、４つの画像が定義される。
【００１０】
４行目の３１はガウシアン平滑化処理を実行する関数コールを示し、５行目の３２はメディアン平滑化処理を実行する関数コールを示し、６行目の３３はエッジ保持平滑化処理を実行する関数コールを示す。これら３つの関数コールで使用する“ｃｖＳｍｏｏｔｈ関数”は、関数の引数を変更するのみで、異なる平滑化処理を実現する関数であり、ＯｐｅｎＣＶ規格にて定義された関数である。これら３つの関数を逐次的に接続したコード構造となる。
【００１１】
図３０は、図２９で示したＯｐｅｎＣＶ標準ライブラリを使用して記述したコード例の動作概要を示した図である。  
入力画像ｓｒｃ＿ｉｍｇに対し、ガウシアン平滑化関数３１によりガウシアン平滑化を行い、中間結果ｄｓｔ０を得る。次に、中間結果ｄｓｔ０に対し、メディアン平滑化関数３２によりメディアン平滑化を行い、中間結果ｄｓｔ１を得る。最後に、中間結果ｄｓｔ１に対し、エッジ保持平滑化関数３３によりヘッジ保持平滑化を行い、中間結果ｄｓｔ２を得る。この様に、各関数コール３１、３２，３３が逐次的に処理され、各関数単位で中間結果を生成し、次段処理に演算結果を受け渡す構造となる。
【００１２】
各平滑化処理は、主として、２次元の畳み込み演算処理で構成する。出力値は入力画像の各データ要素に対し、２次元畳み込み演算を実施し、各データ要素の周囲のデータ要素を含むデータ要素に対し、特定の係数（重み）を掛けてシグマ加算を行い、平均値を出力する処理である。本例では、対象データの周囲一データを含む、合計９データに対して重み係数を掛け合わせ、９で割った平均値を得る演算である。
【００１３】
図２９、図３０で示すように、本来、非常に複雑で大規模な処理を、オープンソースを利用することにより、コード量を大幅に削減可能で、可読性が高いコードを得ることが出来る。
【先行技術文献】
【特許文献】
【００１４】
【特許文献１】特開２０００−１８７５９６号公報
【特許文献２】特開２００９−２１１４５８号公報
【特許文献３】特開２０００−１１２９０１号公報
【非特許文献】
【００１５】
【非特許文献１】ｈｔｔｐ：／／ｏｐｅｎｃｖ．ｗｉｌｌｏｗｇａｒａｇｅ．ｃｏｍ
【発明の概要】
【発明が解決しようとする課題】
【００１６】
このように、オープンソースで記述したコードは、コード量が少ないと共に、可読性の高いコードとすることができる。これは、４つの変数であるｓｒｃ＿ｉｍｇ，ｄｓｔ０、ｄｓｔ１、ｄｓｔ２と平滑化関数ｃｖＳｍｏｏｔｈ自身に非常に大きな情報量が隠蔽されているためである。ここで、このオープンソースで記述されたコードに対し、コンパイラによりオブジェクトコードに変換し、実際にＣＰＵコアで実行する場合について説明する。
【００１７】
このようなオープンソースで記述されたコードは、大規模関数に対する関数コールの羅列で構成される。先に示したｏｐｅｎＣＶのコード例でも、少ないコード量で、大規模の機能を実現出来る。一方、先のコード例では、関数間が大容量のデータ配列で接続される。例えば、ＨＤ解像度の１バイトのＲＧＢフォーマット画像の場合、４つの変数であるｓｒｃ＿ｉｍｇ，ｄｓｔ０、ｄｓｔ１、ｄｓｔ２の各サイズは、横画素数×縦画素数×ＲＧＢ３色分のデータ配列が必要であり、１，９２０×１，０８０×３＝６，２６６，８８０バイトのデータ配列容量が必要となる。４変数では、更に４倍され、２５，０６７，５２０バイト、すなわち、約２５Ｍバイトのデータ配列容量が必要となる。本データ容量は、ＣＰＵコアが有するキャッシュメモリ容量に対して十分に大きいため、キャッシュメモリからの追い出しが頻発し、ＤＤＲ−ＳＤＲＡＭ等で構成する主記憶メモリへの書き込み、並びに、読出しの回数が大きくなる。このようなキャッシュメモリと主記憶間のデータ入れ替え処理は、性能低下要因の一員である。
【００１８】
更に、オープンソースで記述されたプログラムは大規模なアプリケーションとなる。近年、大規模アプリケーションは、マルチコアでの実行が主流になりつつある。マルチコアによる並列タスク化では、まずプログラムコードに対し、データ依存性の破壊されない単位にて処理を分割するタスク並列化（マルチタスク化）が必要となる。しかしながら、オープンソースで記述されたプログラムは解析が困難であり、マルチタスク化を容易に実行出来ない。
【００１９】
本発明の目的の１つは、Ｃ言語などの高級言語で記述され複数の関数コールを有するオリジナルコードに対し、そのプログラムコードの構造を変換することで、データ転送量を削減し、処理の高速化を実現することのできるコード構造変換装置、並びにコード構造変換プログラムを提供することにある。
【００２０】
本発明の他の目的は、複数の関数コールを有した階層構造を有する大規模なプログラムに対し、データ通信量を最適化し、キャッシュミスによる性能劣化を抑止することのできるコード構造変換装置、並びにコード構造変換プログラムを提供することにある。
【００２１】
また、本発明の他の目的は、上述の大規模プログラムに対し、自動でマルチタスク化を施し、マルチコア環境で実行可能なプログラムを提供することにある。
【課題を解決するための手段】
【００２２】
本発明の代表的なもの一例を示すと、次の通りである。本発明は、高級言語で記述されたプログラムコードであるオリジナルコードに対し、プログラムコード構造変換部でコードの構造を変換してフラット・コードを生成するプログラムコードの構造変換装置であって、前記プログラムコード構造変換部は、複数の関数コールを有する前記オリジナルコードを入力し、１階層のフラットなコードであるフラット・コードに変換するインライン展開手段を有し、該インライン展開手段は、前記オリジナルコードから関数定義を抽出する手段と、抽出した前記関数に対して関数の戻り値を変換する手段と、抽出した前記関数に対して関数の仮引数の変換を行う手段と、前記関数を関数コールする上位関数に対して関数コール個所を抽出する手段と、前記関数コール個所に等価変換を施しながら該関数コール箇所に関数を展開し、フラット・コードを生成する手段とを有することを特徴とする。
【発明の効果】
【００２３】
本発明によれば、高級言語で記述されたオリジナルコードに対し、コードの構造を変換して、１階層のフラットなコードであるフラット・コードに変換することにより、データ転送量を削減し、処理の高速化を実現できる。
【図面の簡単な説明】
【００２４】
【図１Ａ】本発明の第１の実施形態になるコード構造変換装置の構成を示す図である。
【図１Ｂ】図１Ａのコード構造変換装置において、コード構造変換プログラムにより実現されるインライン展開部の機能を示したブロック図である。
【図１Ｃ】図１Ａのコード構造変換装置の変形例を示す図である。
【図２】図１Ａのインライン展開部の処理フローであるインライン展開フローを示すフローチャート図である。
【図３】図２におけるＳＳＡ形式変換ステップ１２２の処理概要を示す図である。
【図４】図２における戻り値変換ステップ１１２の変換内容を示す図である。
【図５】図２における仮引数変換ステップ１１３の変換内容を示す図である。
【図６】図２における関数コールの等価変換ステップ１１７の、詳細フローを説明するための図である。
【図７】図６におけるｉｆ文の変換ステップ１１７１の、変換内容を説明するための図である。
【図８】図６におけるｗｈｉｌｅ文の変換ステップ１１７３の、変換内容を説明するための図である。
【図９】図６におけるｄｏ−ｗｈｉｌｅ文の変換ステップ１１７５の、変換内容を説明するための図である。
【図１０】図６におけるｆｏｒ文の変換ステップ１１７７の、変換内容を説明するための図である。
【図１１】図６におけるｓｗｉｔｃｈ文の変換ステップ１１７９の、変換内容を説明するための図である。
【図１２】図６における関数引数の変換ステップ１１８１の、変換内容を説明するための図である。
【図１３】図１Ｃにおける通信量最適化部１３０の通信最適化フローを説明するためのフローチャート図である。
【図１４】図１３において、フラット・コード１７０に対し、大局的番号付けステップ１３４により生成する大局的番号付け結果１３６の例を示す図である。
【図１５】図１３において、大局的番号付け結果１３６に対し、ループアンロール・ステップ１３７とループ融合ステップ１３９を実施した場合の変換例を示す図である。
【図１６】図１３において、ループ融合結果１４０に対し、変数リネーミング・ステップ１４１とデッドコード削除ステップ１４３を実施した場合の変換例を示す図である。
【図１７】本発明の第２の実施形態になる、コード構造変換装置の構成を示す図である。
【図１８】図１７の変数定義表１８０のフォーマットを示す図である。
【図１９】図１７におけるタスク分割部１５０の処理フローを示すフローチャート図である。
【図２０】図１９の変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローで生成するブロック１９１の概念図と、図１９の関数化ステップ１５９で生成した関数１９２の概念図を示した図である。
【図２１】図１９の処理フローのうち、全グローバル変数をグルーピングしない例のグループ変数定義表１８０である。
【図２２】図１９の変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローで生成するコードの例を示した図である。
【図２３】図１９の変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローで生成するコードの他の例を示した図である。
【図２４】図１９の処理フローのうち、グローバル変数の一部をグルーピングした例のグループ変数定義表１８０である。
【図２５】Ｇ７ノード変換２０６から、グローバル変数Ｇ３とＧ５をグループ化した場合の変換例を示す図である。
【図２６】図１９の処理フローのうち、グローバル変数の一部をグルーピングした他の例のグループ変数定義表１８０である。
【図２７】Ｇ７ノード変換２０６から、グローバル変数Ｇ３、Ｇ５、Ｇ６をグループ化した場合の変換例を示す図である。
【図２８】本発明の第３の実施形態になる、コード構造変換装置を採用したＰＣの構成を示す図である。
【図２９】一般に知られているＯｐｅｎＣＶ標準ライブラリを使用して記述したコード例を示す図である。
【図３０】図２９で示したＯｐｅｎＣＶ標準ライブラリを使用して記述したコード例の、動作概要を示した図である。
【発明を実施するための形態】
【００２５】
本発明の第１の様態によれば、本発明のコード構造変換装置は、Ｃ言語などの高級言語で記述されたコードであるオリジナルコードに対し、コードの構造を変換してフラット・コードを生成する手段を有するコード構造変換部を有し、コード構造変換部は、複数の関数コールを有するオリジナルコードを入力し、１階層のフラットなコードであるフラット・コードに変換するインライン展開部を有することを特徴とする。
【００２６】
インライン展開部によるインライン展開は、オリジナルコードから関数定義を抽出する手段と、抽出した関数に対し、関数の戻り値を変換する手段と、同じく抽出した関数に対して関数の仮引数の変換を行う手段とを有し、更に、各関数を関数コールする上位関数に対して、関数コール個所を抽出する手段と、関数コールの等価変換を施しながら、関数コール個所に関数を展開し、フラット・コードを生成する手段を有する。本発明によれば、高級言語で記述されたオリジナルコードに対し、コードの構造を変換して、１階層のフラットなコードであるフラット・コードに変換することにより、データ転送量を削減し、処理の高速化を実現できる。
【００２７】
本発明の第２の様態によれば、コード構造変換部は、さらに、フラット・コードに対し、静的単一代入形式（Ｓｔａｔｉｃ  Ｓｉｎｇｌｅ  Ａｓｓｉｇｎｍｅｎｔ  Ｆｏｒｍａｔ：ＳＳＡ）のフラット・コードに変換する手段を有することを特徴とする。
【００２８】
本発明の第３の様態によれば、コード構造変換部は、さらに、フラット・コードに対し、変数のデータ通信量を最適化し、最適通信量コードを生成する通信量最適化部を有することを特徴とする。通信量最適化部は、フラット・コードに対し、ループ文を抽出し、抽出したループ文内のブロック内に、演算結果が配列変数に対する格納かを判断する手段を有し、更に、その配列変数を生成する演算過程において、演算に必要な入力ノードに関しても、配列を使用するかを判断する手段を有し、ループ内に対し、大局的番号付けと、ループアンロールと、複数のループを融合する手段とを有し、配列変数を演算する上で必要となる入力ノードに対し、小容量の配列名、若しくは単一の変数名に変数名をリネーミングする手段を有し、更に、リード参照が存在しない変数の宣言文と変数代入文を削除する手段を有することを特徴とする。
【００２９】
これにより、オリジナルコードに対し、コードの構造を変換して最適通信量コードを生成し、最適通信量コードにて実行することにより、データ転送を最適化することができる。そのため、キャッシュミスの頻度を削減し、オリジナルコードの処理速度を向上出来る。同時に、インライン展開された最適通信量コードでは、ブランチ数が削減され、処理即速度を向上できる。
【００３０】
また、本発明の第４の様態によれば、本発明のコード構造変換装置は、さらに、先に説明したコード構造変換部が生成する最適通信量コードに対し、タスク並列可能なタスク並列コードに変換するタスク分割部を有する。最適通信量コードに対し、タスク分割を施すことにより、マルチタスク型のタスク並列コードに変換可能となる。マルチコア環境で実行可能なプログラムを提供することにより、処理速度をさらに向上できる。
【００３１】
タスク分割部の入力は２種存在し、１つ目は最適通信量コードであり、２つ目は最適通信量コード内で使用される変数一覧に対し、その変数をグローバル変数に変換するかローカル変数に変換するかを指定する変数スコープ情報と、どの変数を１つのタスク内に包括するかを指定するグループ情報で構成される変数定義表と入力とする。
【００３２】
タスク分割部は、変数定義表に示された変数スコープ情報を元に、各変数をグローバル変数、若しくはローカル変数に再定義する変数定義変換手段と、関数の上部、若しくはコードの途中のポイントである新規検索対象個所から、初めてグローバル変数に対する代入が初めて発生する個所を探索するグローバル変数抽出手段と、抽出したグローバル変数に対する代入に対して、本グローバル変数の代入に必要となる入力ノードが、グローバル変数のみになるまで逆探索し、必要となる文を抽出し、抽出個所を一か所にまとめる変換を行う入力ノード逆探索手段並びにコード並べ替え手段と、一か所にまとめた抽出個所の前後を中括弧“｛｝”で括り、中括弧“｛｝”で使用されるローカル変数の変数定義を中括弧“｛｝”内に複製するブロック化手段と、これらグローバル変数抽出手段、入力ノード逆探索手段、コード並べ替え手段、ブロック化手段の一連のシーケンスを、ライト参照の存在する全グローバル変数に対して実行する手段を有することを特徴とする。
【００３３】
また、タスク分割部は、変数定義表に定義されたグループ情報を元に、複数の中括弧“｛｝”で括ったブロックに対し、データ依存解析により、複数のブロックを１つのブロックにマージ可能か不可能かを判断するグループ化判断手段と、実際に複数のブロックを１つのブロックにマージするグループ化手段と、ブロック化した個所を抽出しブロック内の機能を関数化し、関数コールに置換する関数化手段とを有することを特徴とする。
【００３４】
また、生成されたコードで記述された関数コールの羅列に対し、これらの関数をマルチタスクで動作可能とするために、関数コール間にタスク分割の指示文を挿入する通信関数挿入手段を有することを特徴とする。
【００３５】
また、本発明の第５の様態によれば、本発明のコード構造変換装置は、ＣＰＵ、表示装置、ハードディスクドライブなどを有するパーソナルコンピュータやワークステーション等の情報処理装置で構成し、コード構造変換部、並びにタスク分割部は、コード構造変換プログラム実行形式で構成することを特徴とする。
【００３６】
また、本コード構造変換プログラム実行形式は、外部メディアからの複製や、インタネットからのダウンロードにより、パーソナルコンピュータやワークステーション等の情報処理装置に複製可能な実行形式であることを特徴とする。
【実施例１】
【００３７】
以下、本発明のコード構造変換装置並びにコード構造変換プログラムの各実施形態について説明する。まず、本発明の基本的な構成と動作を解説し、その後に、具体的な発明の内容を実施例の図面を参照して詳細に説明する。なお、プログラミング言語は、Ｃ言語、ＦＯＲＴＲＡＮ言語、Ｊａｖａ（登録商標）言語など様々な言語で表現可能であるが、本実施形態では、発明の機能を説明するために、使用するコードはＣ言語によるコードを例として説明する。本発明では、Ｃ言語を例に説明するが、機能や手段に関して言語に依存しないため、本発明は言語に関して限定を持たない。
【００３８】
図１Ａは、本発明の第１の実施形態におけるコード構造変換装置の構成を示す図、図１Ｂは、コード構造変換プログラムにより実現されるインライン展開部の機能を示したブロック図、図１Ｃは、図１Ａのコード構造変換装置の変形例を示す図である。
【００３９】
第１の実施形態におけるコード構造変換装置（以下、第１のコード構造変換装置）１は、大きく３つの処理部を有する。１つ目はＣ言語などで記述されたコードの構造を変換するコード構造変換部２、２つ目は、Ｃ言語などで記述されたコードであるオリジナルコード１００、並びに、コード構造変換部２によりコード構造が変換されたフラット・コード１７０を格納するデータ蓄積部４、３つ目はコード構造変換部２とデータ蓄積部４の間にて、データの転送処理を行う第１の入出力制御部３からなる。
【００４０】
オリジナルコード１００は、複数の関数コールが記述された上位関数を有する階層構造を持つ、一般的なコードである。例えば、図２９に示したような、ＯｐｅｎＣＶ標準ライブラリを使用して記述された階層構造を有するコードである。
【００４１】
コード構造変換部２は、内部に２つの処理部で構成し、第１の入出力制御部３を経由して第１のデータ蓄積部４のデータベース４１０に格納されたオリジナルコード１００を入力し、複数の関数コールを有するオリジナルコード１００に対し、１階層のフラットなコードであるフラット・コード１７０に変換しデータベース４７０に蓄積するインライン展開部１１０で構成される。
【００４２】
インライン展開部１１０は、図１Ｂの機能ブロック図に示したように、関数の型や引数等の関数の仕様である関数宣言等の関数定義を抽出する関数定義の抽出手段１１１、抽出した関数に対する戻り値の変換手段１１２、抽出した関数に対する仮引数の変換手段１１３、及び、関数コール箇所の抽出手段１１４、抽出された関数コールに関する、関数コールの等価変換手段１１５、及び、関数埋め込み、フラット・コードの生成手段１１６で構成されている。
【００４３】
インライン展開部１１０は、インライン展開の前処理として、オリジナルコード１００に対し、関数定義を抽出する機能と、関数定義を抽出した関数に対して関数の戻り値を変換する機能と、同じく抽出した関数に対して関数の仮引数の変換を行う機能とを有する。更に、インライン展開処理として、各関数を関数コールする上位関数に対して、関数コール個所を抽出する機能と、関数コールの等価変換を施しながら、関数コール個所に関数を展開し、フラット・コードを生成する機能とを有する。関数コール箇所の抽出手段１１４で抽出された関数コール箇所には、インライン展開が可能なコードと不可能なコードが存在する。不可能な場合とは、文の引数定義の個所に、複数の文を記述出来ない場合である。このような、インライン展開が不可能なコードに対しては、関数コールの等価変換手段１１５により、入力コードの変換、すなわち、関数コールの等価変換がなされる。この変換は、次の（１）〜（４）の手順により実行される。
【００４４】
（１）インライン展開が不可能な関数に対し、
（２）上記関数の位置を、その関数の意味が実質的に変わらない箇所に移動し、
（３）上記関数の戻り値を、新たに定義した仮変数（ｌｏｃａｌ＿ｃｏｎｄ）に代入し、
（４）元々、上記関数が記述された位置では、上記仮変数を利用する。
【００４５】
これにより、関数コール箇所にインライン展開が不可能なコードが存在する場合に、関数コールを使用しないコードへ置換する。これにより、全ての関数コール箇所をインライン展開し、同機能の文を出力することができる。
【００４６】
インライン展開部１１０を構成する各手段の機能は、コンピュータ上で所定のプログラムを実行することで、実現できる。これらの機能については、プログラムのインライン展開フローにより、最適化方法の説明と共に記述する。これらのプログラムや、プログラムの実行に必要な各種のデータは、データ蓄積部４に保持されている。
【００４７】
なお、コード構造変換部２は、図１Ｃに変形例として示したように、フラット・コード１７０を入力とし、フラット・コード１７０の内部で定義される変数のデータ通信量を最適化し、最適通信量コード１６０を生成しデータベース４６０に蓄積する通信量最適化部１３０を備えても良い。以下の実施例では、コード構造変換部２が通信量最適化部１３０を備えた例について説明する。なお、以下の各実施例において、コード構造変換部２として図１Ａ相当の構成を採用しても良いことは言うまでも無い
入出力制御部３は、スレーブ的な動作をする制御部であり、コード構造変換部２と第１のデータ蓄積部４との間に配置され、コード構造変換部２がリクエストマスタとしてアクセスし、第１の入出力制御部３が調停を行い、第１のデータ蓄積部４をアクセスする構造である。第１のデータ蓄積部４は、オリジナルコード１００のデータを蓄積する装置である。
【００４８】
図２は、インライン展開部１１０のインライン展開フローをより詳細に説明するための、フローチャート図である。
【００４９】
インライン展開部１１０は、まず、第１の入出力制御部３経由で入力（ステップ１１０）されたオリジナルコード１００に対し、関数抽出ステップ１１１にて、関数宣言を抽出し、戻り値変換ステップ１１２にて関数の戻り値変換を行い、仮引数変換ステップ１１３にて、仮引数の変換を行う。これらの２つの戻り値変換ステップ１１２と仮引数変換ステップ１１３は各関数に対して実施するため、関数判断ステップ１１４にて、最後の関数に対して先の戻り値変換ステップ１１２と仮引数変換ステップ１１３を実施したか確認し、最後の関数の場合は次段フロー（ステップ１１６）に遷移し、最後の関数でない場合は、対象関数更新ステップ１１５にて、変換対象とする関数を更新し、関数抽出ステップ１１１に戻る。
【００５０】
次に、各関数を関数コールする上位関数に対して変換を施すため、関数コール抽出ステップ１１６にて関数を抽出し、関数コールの等価変換ステップ１１７にて上位関数に対し等価の変換を行い、関数埋め込みステップ１１８にて、先の仮引数変換ステップ１１３にて得られ、等価変換した各関数を上位階層関数に展開する。本処理も関数抽出処理と同様に、関数コール判断ステップ１１９にて、最後の関数コールに対して先の関数コールの等価変換ステップ１１７と関数埋め込みステップ１１８を実施したか確認し、最後の関数コールの場合は処理を終了して、生成されたフラット・コード１７０をデータベース４６０に記録する（ステップ１２１）。関数コール判断ステップ１１９にて、最後の関数コールでない場合は、対象関数更新ステップ１２０にて、変換対象とする関数コール個所を更新し、関数コール抽出ステップ１１６に戻る。
【００５１】
関数埋め込みステップ１１８では、上位階層から見て、一貫性のある変数名に変換しながら、仮引数変換ステップ１１３にて得られた変換した各関数を上位階層関数に展開する。本変換は、従来のコンパイラが有するインライン展開手段と同等である。
【００５２】
これら一連のシーケンスを全関数に対して階層的に実施することで、全関数がインライン展開された１階層のコードを生成する。
【００５３】
次に、ＳＳＡ形式変換ステップ１２２にて、生成した１階層のコードを、静的単一代入形式（Ｓｔａｔｉｃ  Ｓｉｎｇｌｅ  Ａｓｓｉｇｎｍｅｎｔ  Ｆｏｒｍａｔ：ＳＳＡ）に変換する。ＳＳＡ形式とは、各変数が一回のみ代入される形式を意味する。例えば、Ｃ言語の文法では、１つの変数に対して、複数回の代入を行うことができる。
【００５４】
図３を用いて、ＳＳＡ形式変換ステップ１２２の処理概要を示す。図３の入力に示された３行目と４行目にて、同一の＜変数名＞に対して、２回（複数回）代入が行われるコードである。この２回の代入の間に、同一の＜変数名＞に対して、リード参照は存在しない。従って、出力の２行目のように＜変数名＿ｔｍｐ０＞を追加定義し、４行目に示すように、２回目の代入に関して、＜変数名＞の代わりに＜変数名＿ｔｍｐ０＞に値を代入し、６行目が示すように、リード参照の参照データを＜変数名＞の代わりに＜変数名＿ｔｍｐ０＞を参照するように変換する。本ＳＳＡ形式変換ステップ１２２により、１階層のコード内に定義された全変数は、全て一回のみの代入となるように変換される。１階層のコードに対するＳＳＡ形式変換手段によれば、プログラム全体に対して従来のデータ依存解析を実施することで、容易に各変数のスコープ期間を判断することが出来る。
【００５５】
次に、１階層のＳＳＡ形式のコードに対し、文単位並べ替えステップ１２３により、データの依存性が破壊されない範囲で、文単位にて並べ替えを行う。これは、先のＳＳＡ形式変換ステップ１２２により、スコープ期間の判定が容易となり、従来のコンパイラの最適化手段を用いることで実現できる。このようにして、フラット・コード１７０の内部で定義される変数のデータ通信量を最適化し、最適通信量コード１６０を生成してデータベース４６０に蓄積する。
【００５６】
結果、これら一連のシーケンスを全関数に対して階層的に実施することで、全関数がインライン展開された１階層のコードであるフラット・コード１７０、もしくは、最適通信量コード１６０を生成する。
【００５７】
なお、これらのフローでは、従来のコンパイル技術で利用するコードのデータ依存解析などを用いることにより容易に変換可能な個所に関しては、説明を省略する。
【００５８】
図４は、戻り値変換ステップ１１２の変換内容を説明するための図である。本戻り値変換ステップ１１２は、１つの関数を入力とし、変換した１つの関数を出力する。
【００５９】
図４の左列である入力は入力関数であり、図４の右列は、戻り値変換ステップ１１２の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００６０】
入力関数は、１行目に示す＜関数型＞、＜関数名＞、＜仮引数＞、及び、１行目の中括弧“｛”から１３行目の中括弧“｝”の間で括られた関数本体で表現することができる。ここで、戻り値とは、５行目や８行目で定義された“ｒｅｔｕｒｎ”文で定義することが出来る。“ｒｅｔｕｒｎ”文の右に示した値＜ｖａｌｕｅ１＞と＜ｖａｌｕｅ２＞が関数の戻り値であり、その変数型は＜関数型＞と同一である。また、“ｒｅｔｕｒｎ”文は、“ｒｅｔｕｒｎ”文が実行された時点で、後述された処理を終了し、関数コールされた上位関数に戻る“ｂｒｅａｋ文”のような振舞いを行う。これらの処理を模擬する為に、戻り値変換ステップ１１２では、２、５，６，８，９，１１，１２行目のような変換を行う。
【００６１】
まず、２行目のように、関数の戻り値を変数として定義するため、＜関数型＞と同様の変数型にて、“ｒｅｔ＿ｔｍｐ”変数と、“ｒｅｔ＿ｖａｌｕｅ”変数を定義する。次に、“ｒｅｔｕｒｎ”文が記述された５行目、並びに８行目は、それぞれ、５，６行目と８，９行目のように、“ｒｅｔ＿ｔｍｐ”変数に戻り値を仮代入し、ＧＯＴＯ文を付加する。ＧＯＴＯ文のジャンプ先である“ＦＵＮＣ＿ＥＮＤ”は、関数本体の最後の位置である１１行目とし、ジャンプ先の１２行名では仮代入りした戻り値を“ｒｅｔ＿ｖａｕｅ”変数に再度代入する。この変換により、“ｒｅｔｕｒｎ”文の“ｂｒｅａｋ”を伴う機能を模擬した戻り値変換を行う。
【００６２】
これらの変換では、“ｒｅｔｕｒｎ”文の抽出と関数本体の最後の中括弧“｝“を構文解釈により抽出し、変換を実施する。
【００６３】
図５は、仮引数変換ステップ１１３の変換内容を説明するための図である。仮引数変換ステップ１１３は、１つの関数を入力とし、変換した１つの関数を出力する。
【００６４】
図５の左列である入力は入力関数であり、図５の右列は、仮引数変換ステップ１１３の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力関数に対し、変換が実施された行に対して付すものである。
【００６５】
入力関数は、１行目に示す＜関数型＞、＜関数名＞、＜値仮引数＞、及び、１行目の中括弧“｛”から６行目の中括弧“｝”の間で括られた関数本体で表現することができる。ここで、＜値仮引数＞とは関数のＣａｌｌ  ｂｙ  Ｖａｌｕｅ形式の引数であり、４行目と５行目で定義されたリード参照、並びにライト参照にて、＜値仮引数＞で定義された変数が使用される。仮引数引き渡しによる関数コールの場合、変数の有効期間であるスコープ期間は、関数内部を実行している時のみとなり、関数の実行が終了した時点で、データを破棄しても構わない。そこで、出力の２行目、のように、関数内でスコープを有する“Ｌｏｃａｌ＿＿＜値仮引数名＞”を仮引数と同じ型で定義し、３行目にて、＜値仮引数名＞を“Ｌｏｃａｌ＿＿＜値仮引数名＞”に代入する。さらに４行目、５行目のように、元来、＜値仮引数＞がリード参照、又は、ライト参照で仕様されたコードに対しては、“Ｌｏｃａｌ＿＿＜値仮引数名＞”に置換える。本変換に従えば、関数内のみでスコープ期間が有効な仮変数として動作できる。
【００６６】
これらの変換では、＜値仮引数＞の宣言と、利用個所のみを構文解析により抽出し、変換を実施する。
【００６７】
なお、＜値仮引数＞の参照がリード参照のみの場合、変数のスコープ期間を無視することが可能であるため、“Ｌｏｃａｌ＿＿＜値仮引数名＞”に置換する必要はないが、本発明では、リード参照時の変換方式に関して、限定を持たない。
【００６８】
図６は、図２に示したインライン展開フローにおける、関数コールの等価変換ステップ１１７の詳細フローを説明する図である。
【００６９】
図２に示したインライン展開フローの関数コール抽出ステップ１１６にて抽出された関数コール箇所には、インライン展開が可能なコードと不可能なコードが存在する。不可能な場合とは、文の引数定義の個所に、複数の文を記述出来ない場合である。簡単な例として、ｉｆ文を例に説明する。ｉｆ文の文法は、以下のようになる。
【００７０】
文法：ｉｆ（＜条件式＞）｛＜実行文＞｝
ここで、＜条件式＞個所には、１つの条件式のみを記述することができる。例えば、以下のｉｆ文使用例を想定する。
【００７１】
例：ｉｆ（ｓｕｂ＿ｆｕｎｃ（ａ）＝＝０）｛＜実行文＞｝
ここで、＜条件式＞で使用されるｓｕｂ＿ｆｕｎｃ（）関数は、内部で複数の文や変数の宣言、“ｒｅｔｕｒｎ文”などで構成される。この様な複雑な文で構成されるサブ関数を、そのままｉｆ文内の＜条件式＞個所に展開することは出来ない。従って、事前に入力コードを変換することで、インライン展開が可能となる。
【００７２】
この様な事前のインライン展開を可能とする変換を含む、関数コールの等価変換ステップ１１７の詳細を、図６に示す。
【００７３】
入力コードに記述された関数コール個所に関し、ｉｆ文判定ステップ１１７０では、ｉｆ文内の条件式であると判定した場合はｉｆ変換ステップ１１７１にてｉｆ文の変換を行い、ｗｈｉｌｅ文判定ステップ１１７２では、関数コール個所がｗｈｉｌｅ文内の条件式であると判定した場合はｗｈｉｌｅ文変換ステップ１１７３にてｗｈｉｌｅ文の変換を行う。ステップｄｏ−ｗｈｉｌｅ文判定１１７４では、関数コール個所がｄｏ−ｗｈｉｌｅ文内の条件式であると判定した場合はｄｏ−ｗｈｉｌｅ変換ステップ１１７５にてｄｏ−ｗｈｉｌｅ文の変換を行い、ｆｏｒ文判定ステップ１１７６では、関数コール個所がｆｏｒ文内の条件式であると判定した場合はｆｏｒ変換ステップ１１７７にてｆｏｒ文の変換を行う。ｗｉｔｃｈ文判定ステップ１１７８では、関数コール個所がｓｗｉｔｃｈ文内の条件式であると判定した場合はｓｗｉｔｃｈ変換ステップ１１７９にてｓｗｉｔｃｈ文の変換を行い、関数引数ステップ１１８０では、関数コール個所が関数の引数であると判定した場合は関数引数変換ステップ１１８１にて関数引数の変換を行う。これらの変換は、関数コールが記述された上位関数に対して行うものである。
【００７４】
なお、これらの関数コールが記述された個所を抽出する構文解釈手段は、従来のコンパイラで使用された手段と同等である。
【００７５】
図７は、ｉｆ変換ステップ１１７１の変換内容を説明するための図である。ｉｆ変換ステップ１１７１は、ｉｆ文ブロックを入力とし、変換した同機能の文を出力する。
【００７６】
図７の左列である入力は入力コードであり、図７の右列は、ｉｆ変換ステップ１１７１の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００７７】
入力の３行目に示すｉｆ文の＜条件式＞には関数コールが使用されている。この条件式を出力の２行目に示すように、ｉｆ文前に移動して“ｌｏｃａｌ＿ｃｏｎｄ１”に仮代入し、ｉｆ文の条件式内では、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ１”に置換する。本変換により、ｉｆ文内の条件式から関数コールを除去できる。
【００７８】
なお、入力の４行目に示すように、従属してｅｌｓｅ  ｉｆ文が存在する場合は、同様に、出力の４，５，６行目に示すように、ｅｌｓｅ文と中括弧“｛｝”で括ったブロックに分割し、ブロック内で、関数コールを“ｌｏｃａｌ＿ｃｏｎｄ２”に再代入して置換する。この様に、ｉｆ文並びにｅｌｓｅｉｆ文は、階層的に関数コールをｉｆ文の＜条件式＞から除去する。
【００７９】
図８は、ｗｈｉｌｅ変換ステップ１１７３の変換内容を説明するための図である。ｗｈｉｌｅ文変換ステップ１１７３は、ｗｈｉｌｅ文ブロックを入力とし、変換した同機能の文を出力する。
【００８０】
図８の左列である入力は入力コードであり、図８の右列は、ｗｈｉｌｅ変換ステップ１１７３の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００８１】
入力の２行目に示すｗｈｉｌｅ文の＜条件式＞には関数コールが使用されている。この条件式を出力の３行目に示すように、ｗｈｉｌｅ文後に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入し、ｗｈｉｌｅ文の条件式内には、無限ループを示す“ｗｈｉｌｅ（１）”に置換する。本変換により、ｗｈｉｌｅ文内の条件式から関数コールを除去できる。更に出力の４行目に示すように、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”をｉｆ文の条件とし、この条件式が成り立つ場合、入力の＜文＞を実行し、条件式が成り立たない場合、出力の５行目のように、ｂｒｅａｋ文でｗｈｉｌｅ文から抜け出す記述に置換える。本変換により、ｗｈｉｌｅ文の条件式に関数コールを使用しないコードへの置換ができる。
【００８２】
図９は、ｄｏ−ｗｈｉｌｅ変換ステップ１１７５の変換内容を説明するための図である。ｄｏ−ｗｈｉｌｅ変換ステップ１１７５は、ｄｏ−ｗｈｉｌｅ文ブロックを入力とし、変換した同機能の文を出力する。
【００８３】
図９の左列である入力は入力コードであり、図９の右列は、ｄｏ−ｗｈｉｌｅ変換ステップ１１７５の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００８４】
入力の５行目に示すｄｏ−ｗｈｉｌｅ文の＜条件式＞には関数コールが使用されている。この条件式を出力の４行目に示すように、ｄｏ−ｗｈｉｌｅ文内の＜文＞の後に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入して置換する。また、５行目のｄｏ−ｗｈｉｌｅ文の条件式に、仮代入した本変換により、ｗｈｉｌｅ文内の条件式から関数コールを除去できる。更に出力の４行目に示すように、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”を使用するように置換する。本変換により、ｄｏ−ｗｈｉｌｅ文の条件式に関数コールを使用しないコードへの置換ができる。
【００８５】
図１０は、ｆｏｒ変換ステップ１１７７の変換内容を説明するための図である。ｆｏｒ変換ステップ１１７７は、ｆｏｒ文ブロックを入力とし、変換した同機能の文を出力する。
【００８６】
図１０の左列である入力は入力コードであり、図１０の右列は、ｆｏｒ変換ステップ１１７７の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００８７】
なお、ｆｏｒ文の引数は、以下のように、＜初期値＞フィールド、＜条件式＞フィールド、＜更新文＞フィールドに分かれているため、それぞれ変換を行う。
【００８８】
ｆｏｒ文の文法：ｆｏｒ（＜初期値＞、＜条件式＞、＜更新文＞）｛ブロック｝
入力の３行目に示すｆｏｒ文の＜初期値＞フィールドに関数コールが使用されている。この＜初期値＞を出力の２行目に示すように、ｆｏｒ文前に移動して“ｌｏｃａｌ＿ｃｏｎｄ１”に仮代入し、ｆｏｒ文の＜初期値＞フィールド内では、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ１”に置換する。本変換により、ｆｏｒ文内の＜初期値＞フィールドから関数コールを除去できる。
【００８９】
次に、＜条件式＞の変換方法について示す。入力の９行目に示すｆｏｒ文の＜条件式＞フィールドに関数コールが使用されている。この場合、ｆｏｒ文によるループ機能をｗｈｉｌｅ文に置換することで、＜条件式＞をｆｏｒ文の引数で使用しない形式に変換する。まず、出力の９行目に示すように、ｆｏｒ文をｗｈｉｌｅ（１）文の無限ループに置換える。次に、出力の１０行目のように、＜条件式＞をｗｈｉｌｅ文内に移動して“ｌｏｃａｌ＿ｃｏｎｄ２”に仮代入し、１１行目のｉｆ文の条件とする。条件が成り立つ場合、入力の１１行目に記したｆｏｒ文内ブロックである＜文２＞を処理し、ｉｆ文の条件が成り立たない場合、ｗｈｉｌｅ文からｂｒｅａｋする。また、この＜条件式＞の変化の場合、入力９行目の＜更新文＞をｗｈｉｌｅ文の最後の１３行目に移動する。本変換により、ｆｏｒ文の＜条件式＞に使用された関数コールを除去できる。
【００９０】
次に、＜更新文＞の変換方法について示す。入力の１７行目に示すｆｏｒ文の＜更新文＞フィールドに関数コールが使用されている。この場合、出力の１７行目のように、＜更新文＞フィールドには何も記述しない。＜更新文＞フィールドは、出力の２１行目の様に、ｆｏｒ文の最後の個所に移動する。なお、ｆｏｒ文の＜更新文＞を伴う変更において、ｆｏｒ文のブロック内で入力の１９行目に示すようなＣｏｎｔｉｎｕｅ文が使用されている場合は、出力の１９行目に示すようにＧＯＴＯ文で、ｗｈｉｌｅ文の最後（２１行目）にブランチする記述を付加する。従って、出力の２１行目には、ラベルの付加が必要となる。
【００９１】
ｆｏｒ文の変換に際しては、＜初期値＞フィールド、＜条件式＞フィールド、＜更新文＞フィールドの各引数に関数コールが使用される場合がある。この場合、まず＜初期値＞フィールドの変換を行い、次に＜更新文＞フィールドの変換を行い、最後に＜条件式＞フィールドの変換を行うシーケンスにより、全組合せの変換を可能とする。
【００９２】
図１１は、ｓｗｉｔｃｈ変換ステップ１１７９の変換内容を説明するための図である。ｓｗｉｔｃｈ変換ステップ１１７９は、ｓｗｉｔｃｈ文ブロックを入力とし、変換した同機能の文を出力する。
【００９３】
図１１の左列である入力は入力コードであり、図１１の右列は、ｓｗｉｔｃｈ変換ステップ１１７９の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００９４】
入力の３行目に示すｓｗｉｔｃｈ文の＜条件式＞には関数コールが使用されている。この条件式を出力の２行目に示すように、ｓｗｉｔｃｈ文前に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入し、ｓｗｉｔｃｈ文の条件式内は、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”に置換する。本変換により、ｓｗｉｔｃｈ文内の条件式から関数コールを除去できる。
【００９５】
図１２は、関数引数変換ステップ１１８１の変換内容を説明するための図である。関数引数変換ステップ１１８１は、関数文ブロックを入力とし、変換した同機能の文を出力する。
【００９６】
図１２の左列である入力は入力コードであり、図１２の右列は、関数引数変換ステップ１１８１の処理を実施した変換結果を示す。また、最左列の番号はコードの行番号を示し、中央部の矢印（⇒）は、入力コードに対し、変換が実施された行に対して付すものである。
【００９７】
入力の３行目に示す関数の＜引数＞には関数コールが使用されている。この関数コールによる＜引数＞を出力の２行目に示すように、関数コール前に移動して“ｌｏｃａｌ＿ｃｏｎｄ”に仮代入し、関数の＜引数＞は、仮代入した“ｌｏｃａｌ＿ｃｏｎｄ”に置換する。本変換により、関数の＜引数＞から関数コールを除去できる。
【００９８】
なお、図６から図１１にて説明した各変換方式に関し、追加した変数に関しては、変数宣言文の追加も必要となるため、変換フローの適材適所にて追加する。
【００９９】
また、本説明では全ての関数コールに対して、インライン展開するフローを説明したが、インライン展開を抑止する手段を有しても構わない。従来、インライン展開を可能とするコンパイラでは、関数単位、若しくは、関数コール単位でインライン展開を可能とする技術がある。関数単位では、関数に対して、コンパイル方法を指示するプラグマを指定する。また、関数コール単位では、インライン展開すべき関数コールに対して、同様にコンパイル方法を指示するプラグマを指定する。本発明に於いても、関数単位、若しくは関数コール単位でインライン展開指示を可能とする手段を有する。
【０１００】
以上の通り、本実施形態におけるインライン展開部は、オリジナルコードから関数コール個所を抽出し、この関数コールの等価変換を施しながら、関数コール個所に関数を展開し、フラット・コードを生成する。これにより、高級言語で記述され複数の関数コールが含まれるオリジナルコードに対し、コードの構造を変換して、１階層のフラットなコードであるフラット・コードに変換することにより、データ転送量を削減し、処理の高速化を実現することができる。
【０１０１】
次に、図１３は、図２のステップ１２２〜１２４に示した、本実施形態における通信量最適化部１３０（図１Ｃ参照）の通信最適化フロー、すなわち、フラット・コード１７０の内部で定義される変数のデータ通信量を最適化し、最適通信量コード１６０を生成する処理の詳細を説明するフローチャート図である。通信量最適化部１３０では、インライン展開部１１０によって生成したフラット・コード１７０を入力とし、データ依存解析により、データ配列に関し、最適通信量コード１６０を生成し、その通信量を削減する。
【０１０２】
まず、ループ文抽出ステップ１３１にて、入力されたフラット・コード１７０に対し、評価ポイントから文字列検索によりループ文が存在するかを判断し、ループ文が存在しない場合、処理を終了し、ループアンロール・ステップ１３６に遷移し、ループ文が存在する場合、ループ文特徴抽出ステップ１３２に遷移する。ここで、ループ文とは、ｆｏｒ文、ｗｈｉｌｅ文、ｄｏ−ｗｈｉｌｅ文で記述されたコードを意味する。また評価ポイントとは、１回目の処理の場合は、フラット・コード１７０の先頭であり、その評価ポイントから、最初に定義されるループ文を抽出する。
【０１０３】
ループ文特徴抽出ステップ１３２は、その抽出したループ文内のブロックにて、演算結果が配列変数に格納する変数であるか、単一変数に対して格納する変数であるかを抽出し、更に、その配列変数を生成する演算過程において、演算に必要な入力ノードに関しても、配列を使用するかを判断する、配列ループ文判断ステップ１３３にて、先のループ文が配列変数を生成し、更に入力も配列変数を利用する場合、大局的番号付けステップ１３４に遷移し、先のループ文が単一変数を生成する場合、現ループ解析終了ステップ１３５に遷移する。現ループ解析終了ステップ１３５では、先に評価対象としたループ文の評価を終了し、次のループ文を検索するために、評価ポイントを先の評価ポイントで示したループ文の次の行に移動する。
【０１０４】
大局的番号付けステップ１３４は、出力の配列変数のデータ１要素を演算するのに必要な入力変数に対して、ループ文内部のみで有効な変数名にリネーミングして、大局的番号付け結果１３６を順次追加しながら生成する手段を有し、リネーミングが終了した時点で、現ループ解析終了ステップ１３６に遷移する。
【０１０５】
これら、ループ文抽出ステップ１３１と配列ループ文判断ステップ１３２と現ループ解析終了ステップ１３５にて、評価ポイントを変更しながら大局的番号付けを行うことで、フラット・コード１７０全体に対して大局的番号付けを行い、最終的に大局的番号付け結果１３６を得る。
【０１０６】
ループアンロール・ステップ１３７では、大局的番号付け結果１３６に対し、ループ融合可能な複数のループ間で必要な配列変数を解析し、演算に必要な配列となるまで、ループをアンロールし、ループアンロール結果１３８を得る。これらの処理の詳細については、後に述べる。
【０１０７】
次に、ループ融合ステップ１３９では、ループ融合可能な複数のループを融合し、ループ融合結果１４０を得る。次に変数リネーミング・ステップ１４１にて、リード参照される変数について、その変数が代入される代入式で置換し、変数リネーミング結果１４２を得る。最後に、デッドコード削除ステップ１４３にて、リード参照のない変数を削除し、最適通信量コード１６０を生成し、データベース４６０に記録する（ステップ１４４）。
【０１０８】
図１４、図１５、図１６を用いて、通信量最適化部１３０の通信最適化フローの例について説明する。
【０１０９】
図１４は、入力であるフラット・コード１７０に対し、大局的番号付けステップ１３４により生成する大局的番号付け結果１３６の例を示す図である。
【０１１０】
フラット・コード１７０には、１行目から８行目までの第１のループと、９行目から１４行目までの第２のループが含まれるコード例として説明する。なお図中の矢印（⇒）は変更があった個所を示している。
【０１１１】
大局的番号付けステップ１３４では、第１のループ、及び第２のループに対し、その内部の演算の入力と出力が共に配列変数の場合に処理される。入力の４行目に示されたｂ［ｉ］はａ［ｉ］とａ［ｉ＋１］を入力として演算されるため、大局的番号付け結果１３６の２行目と３行目のように、ｔｍｐ０［０］［０］とｔｍｐ０［０］［１］に仮代入する。また４行目の実際の演算に関しては、ａ［ｉ］とａ［ｉ＋１］の代わりにｔｍｐ０［０］［０］とｔｍｐ０［０］［１］を使用する形式に変換する。同様に、入力の１２行目に示されたｃ［ｉ］はｂ［ｉ］とｂ［ｉ＋１］を入力として演算されるため、大局的番号付け結果１３６の１０行目と１１行目のように、ｔｍｐ１［０］とｔｍｐ１［１］に仮代入する。また１２行目の実際の演算に関しては、ｂ［ｉ］とｂ［ｉ＋１］の代わりにｔｍｐ１［０］とｔｍｐ１［１］を使用する形式に変換する。なお本説明では、ｔｍｐ０が２次元配列、ｔｍｐ１が１次元配列として説明するが、これは、説明を容易にするための例であり、実際には、全ての変数がユニークな変数名であればよい。
【０１１２】
このように、大局的番号付けステップ１３４では、出力する配列変数の演算式に対し、外部からの入力配列を使用せず、ループ文内部のローカルな変数のみをリード参照する形式に変換するものである。
【０１１３】
図１５は、大局的番号付け結果１３６に対し、ループアンロール・ステップ１３７でループアンロール結果１３８を得て、これにさらにループ融合ステップ１３９を実施し変換する例を示す図である。
【０１１４】
大局的番号付け結果１３６に対し、ループアンロール・ステップ１３７では、第２のループの出力結果であるｃ［ｉ］を演算する上で必要な入力配列ｂ［ｉ］を解析する。ここでは、１つのｃ［ｉ］を得るためには、２つのｂ［ｉ］とｂ［ｉ＋１］が必要であると判断し、これら２つのデータ配列を生成する第１のループに対し、５、６，７行目のようにループアンロールを施し、ｂ［ｉ＋１］が得られるように置換し、ループアンロール結果１３８を得る。
【０１１５】
次に、ループアンロール結果１３８に対し、ループ融合ステップ１３９では、同一のループ構造であると判断し、８行目と９行目に示された、第２のループ文の定義を削除し、ループ文の統合を行い、ループ融合結果１４０を得る。なお、この様なループ融合手段に関しては、先の特許文献２などに開示される技術である。
【０１１６】
図１６は、ループ融合結果１４０に対し、変数リネーミング・ステップ１４１とデッドコード削除ステップ１４３を実施した場合の変換例を示す図である。
【０１１７】
ループ融合結果１４０に対し、変数リネーミング・ステップ１４１では、１０行目、１１行目、１２行目にて使用していた配列ｂ［ｉ］とｂ［ｉ＋１］に対し、４行目と７行目で定義された配列ｂ［ｉ］とｂ［ｉ＋１］の代入式で置き換えを行う。具体的には、ｂ［ｉ］は４行目で示された（ｔｍｐ０［０］［０］＋ｔｍｐ０［０］［１］）で置き換えを行い、ｂ［ｉ＋１］は７行目で示された（ｔｍｐ０［１］［０］＋ｔｍｐ０［１］［１］）で置き換えを行うものであり、本ステップにより、変数リネーミング結果１４２を得る。
【０１１８】
次に、変数リネーミング結果１４２に対し、デッドコード削除ステップ１４３では、ループ内でリード参照のない代入式を削除する。具体的には、４行目、７行目、１０行目、１１行目の代入式を削除し、最適通信量コード１６０を生成する。
【０１１９】
これら一連の変換フローにより、第１のループと第２のループは融合されると共に、中間結果であったｂ［ｉ］配列が削除され、代わりにｔｍｐ０［２］［２］という、小容量のデータ配列に置換出来る。従来のコンパイラでは、変数定義された変数に関しては、静的に変数をメモリ上に配置する。従って、容量の大きな配列ｂ［］を小容量の配列ｔｍｐ０［２］［２］に置換することにより、メモリ配置すべき変数の容量を削減する。例えば、ＨＤ解像度の配列処理の場合、配列ｂの容量はｂ［１９２０］［１０８０］という大容量の配列を有するが、本変換手段に従えば、配列容量を２４８，４００の１（（２×２）／（１，９２０×１，０８０））に削減することが出来る。
【０１２０】
このように、通信量最適化部１３０では、配列に関し、ループ融合を行うことで、大幅なデータ量削減を行うと共に、大容量データのキャッシュ・スラッシングを回避可能なデータ配列容量に抑えることで、通信量を削減できる。
【０１２１】
結果、最適通信量コード１６０は、フラットかつ通信量を削減したコードとなる。本コードを一般的なコンパイラでオブジェクト形式に変換し、一般的なシングルコアで実行することで、処理速度の速い実行を可能とする。
【０１２２】
本実施形態によれば、複数の関数コールを有した階層構造を有する大規模なプログラムに対し、フラットかつ通信量を削減した最適通信量コードを生成することにより、処理の高速化を実現すると共に、キャッシュミスによる性能劣化を抑止することができる。
【実施例２】
【０１２３】
以下、本発明の第２の実施形態について図面を参照して詳細に説明する。まず、本発明における第２のコード構造変換装置５の基本構成について説明する。
【０１２４】
図１７は、本発明の第２の実施形態における第２のコード構造変換装置５の構成を示す図である。
【０１２５】
第２のコード構造変換装置５は、主に５つの実行部で構成する。第２のコード構造変換装置５は、第１の実施形態で説明したコード構造変換部２と同一構成のコード構造変換部２と、第１の実施形態で説明した最適通信量コード１６０を入力とし、タスク並列可能なタスク並列コード１８１を生成するタスク分割部１５０と、タスク並列コード１８１を元にマルチコア向けのコンパイルを実行し、並列オブジェクト１８２を生成する並列コンパイル処理部１９０と、第１の実施形態で説明したオリジナルコード１００と最適通信量コード１６０に加え、先に示したタスク並列コード１８１、並列オブジェクト１８２、並びに、タスク分割部１５０への入力であり、タスク並列化を実行するための情報である変数定義表１８０を格納する第２のデータ蓄積部７と、コード構造変換部２と第２のデータ蓄積部７との間でオリジナルコード１００と最適通信量コード１６０の通信と、タスク分割部１５０と第２のデータ蓄積部７との間で最適通信量コード１６０、変数定義表１８０、タスク並列コード１８１の通信と、並列コンパイル処理部１９０と第２のデータ蓄積部７との間でスク並列コード１８１と並列オブジェクト１８２の通信を行う第２の入出力制御部６で構成する。なお、第２の入出力制御部６と、第２のデータ蓄積部７は、第１の実施形態で説明した第１の入出力制御部３と、第１のデータ蓄積部４とほぼ同一の機能であり、データ通信、並びに保持するデータ量が異なるのみの違いである。
【０１２６】
図１８は、本発明の第２の実施形態における変数定義表１８０のフォーマットを示す図である。変数定義表１８０では、３つの情報を定義する。
【０１２７】
１つ目の情報である変数名情報１８５は、最適通信量コード１６０に定義された変数の一覧である。最適通信量コード１６０は、インライン展開部１１０によりインライン展開されたフラットなコードであると共に、ＳＳＡ形式変換ステップ１２２により、単一代入形式に変換されたコードである。すなわち、最適通信量コード１６０上で表現されたコードは１階層のコードであるため、最適通信量コード１６０内で定義される変数は、本コード上に定義された全変数が展開されていると共に、１つの関数しか存在しないため、関数内のローカル変数でもグローバル変数でもどちらでもよい。従って、本変数名情報１８５は、最適通信量コード１６０の変数定義文から容易に自動抽出可能である。
【０１２８】
２つ目の情報である変数スコープ情報１８６は、対応する変数名情報１８５に対し、グローバル変数若しくはローカル変数として扱うかを指定するフィールドである。先に述べたように、最適通信量コード１６０は、インライン展開部１１０によりインライン展開されたフラットなコードであるため、各変数の定義は、一律に展開されているため、各変数をグローバル変数とローカル変数のどちらで扱ってもよい。本変数スコープ情報１８６は、タスク分割部１５０のタスク分割処理にて使用する。
【０１２９】
３つ目の情報であるグループ情報１８７は、複数の各変数情報１８５に対し、グルーピングを行うか、行わないかを指定する情報である。本ループ情報１８７を元に、タスク分割部１５０のタスク分割処理にてタスク分割単位を指定する。
【０１３０】
なお、変数スコープ情報１８６としてローカル変数と指定した場合、グループ情報１８７は無視される。また、変数スコープ情報１８６としてグローバル変数と指定した場合、かつグループ情報１８７の定義がない場合、単独の変数で１つのグループとし、自動でユニークなグループ情報１８７を割り振る。すなわち、グローバル変数はグループ外でリード／ライトされる変数であり、ローカル変数は、グループ内のみでリード／ライトされる変数である。タスク分割部１５０では、定義されたグループ指定において同一グループ名の場合、各グローバル変数のリード／ライト参照を、１つのブロック内に収める。そして、入力のグローバル変数に対して、１つのブロック内のみで使用される変数をローカル変数としてブロック内に変数定義し、関数化する。これにより、戻り値並びに仮引数が存在しない構造の関数を生成する。以下、詳細に説明する。
【０１３１】
図１９は、タスク分割部１５０の処理フローを示すフローチャート図である。  
なお、変数定義表１８０は、第２のコード構造変換装置５を利用するユーザが入力する。  
図１９において、タスク分割部１５０の処理の開始後、まず、変数定義変換ステップ１５１では、最適通信量コード１６０に対し、変数定義表１８０で指定した変数がグローバル変数の場合、対象変数をグローバル変数とし、指定した変数がローカル変数の場合、対象変数をローカル変数として、変換を行う。Ｃ言語の文法では、グローバル変数は関数の外部に変数定義があり、ローカル変数は関数の内部に変数定義が存在するため、変数定義変換ステップ１５１にて、異なる変数として変数宣言されている場合、記述箇所に置換を行う。
【０１３２】
次に、グローバル変数抽出ステップ１５２では、一回目のループでは関数の上部から、２回目以降のループでは、新規検索対象を起点とし、構文解析により、初めてライト参照（グローバル変数への代入文）される変数を検索し、グローバル変数が存在する場合、グ入力ノード逆探索ステップ１５３に遷移し、グローバル変数が存在しない場合、グループ化判断ステップ１５７に遷移する。なお、ここで示すグローバル変数とは、先の変数定義変換ステップ１５１にて変換されたグローバル変数である。ここで、抽出したグローバル変数を逆探索対象変数とし、抽出したグローバル変数への代入文を検索起点とする。また、新規検索対象とは、後述するローカル変数名称変更ステップ１５６にて更新する。
【０１３３】
入力ノード逆探索ステップ１５３では対象とするグローバル変数への代入文を起点とし、逆方向（上位方向）にデータ依存性のある変数並びに式を逆探索し、一連の処理に必要となる入力ノードが、グローバル変数となるまで探索を繰り返し、一連の処理に必要とした文を抽出する。ここで、最後に逆探索にて、最後に検出された入力となるグローバル変数が定義された文を、検索終了点とする。次に、入力ノード逆探索ステップ１５３にて抽出した文の一覧に従い、コード並べ替えステップ１５４にて、先の文一覧を１か所にまとめる。具体的には、検索起点から検索終了点までの文を一か所にまとめ、この間の文の記述にて、先の文一覧にて未抽出の文は例外文とし、先にまとめた文の後段に移動させる。
【０１３４】
ここで、ＳＳＡ形式のコードでは、１つの変数に対して、ライト参照は一回しか存在しない。更に本入力ノード逆探索ステップ１５３では、と逆探索対象変数から逆探索を行う。従って、先の未検出の文にて定義された変数への代入文に対し、逆探索対象変数となるグローバル変数とはデータ依存性が存在しないことになり、先に示したように、一か所にまとめた文の後段に本未検出代入文などを移動させても、データ依存性は破壊されない。
【０１３５】
次に、ブロック化ステップ１５５にて、先の一か所にまとめた文の前後に、中括弧“｛｝”で括ることでブロック化し、さらに本ブロック内で代入されるグローバル変数以外の変数を中括弧内のローカル変数とし、変数定義文を中括弧“｛｝”内に移動させ、ローカル変数として定義する。
【０１３６】
次に、ローカル変数名称変更ステップ１５６にて、ブロック化ステップ１５５にてローカル変数として定義したローカル変数が、ブロック化した個所以降にてリード参照されている場合、ブロックの後段にその代入文の複製を生成する。なお、この時、先のローカル変数ではないユニークな名前の変数名として置換する。更に、リード参照されたローカル変数は、先に置換したユニークな名前のローカル変数の代入文として置換する。なお、ＳＳＡ形式では、ライト参照は一回しか存在しないため、リード参照の個所のみ変更すればよい。
【０１３７】
これら、グローバル変数抽出ステップ１５２、入力ノード逆探索ステップ１５３、コード並べ替えステップ１５４、ブロック化ステップ１５５、ローカル変数名称変更ステップ１５６を全グローバル変数のライト参照に対して繰り返し実行するため、抽出したグローバル変数への代入文の次行を新規検索対象とし、グローバル変数抽出ステップ１５２に遷移する。
【０１３８】
上述のグローバル変数抽出ステップ１５２、入力ノード逆探索ステップ１５３、コード並べ替えステップ１５４、ブロック化ステップ１５５、ローカル変数名称変更ステップ１５６を全グローバル変数のライト参照に対して繰り返し実行し、終了した場合には、グループ化判断ステップ１５７に遷移する。グループ化とは、変数定義表１８０のグループ情報１８７で定義されたグループ指定において、同一グループ名の場合、各グローバル変数のライト参照を、１つのブロック内に収めることを示す。グループ化判断ステップ１５７にて、グループ化可能と判断した場合、グループ化ステップ１５８に遷移し、上述のグループ化を行う。グループ化判断ステップ１５７にて、グループ化不可と判断した場合、グループ化解除ステップ１６２に遷移し、グループ化不可のグローバル変数に対しては、グループ情報１８７で指定したグループ化方針に対し、グループ化しないと指定しなおし、グループ化ステップ１５８に遷移する。更に、グループ化解除ステップ１６２では、第２のコード構造変換装置５のユーザインタフェースとして、ユーザにグループ化不可であったと通知する。グループ化判断ステップ１５７、グループ化ステップ１５８、グループ化解除ステップ１６２については後述する。
【０１３９】
次に、関数化ステップ１５９にて、ブロック化した個所全体を関数として再定義する。この中括弧“｛｝”で括ったブロックは、グローバル変数をリード並びにライト参照し、その他の変数は、ローカル変数としてブロック内に変数宣言されているため、関数の引数は存在しない。そこで、ブロック内の文字列を関数のボディ部（本体）とし、変数定義表１８０で指定したグループ情報１８７を関数名とした関数を生成する。同時に、入力されたコードに対し、ブロック化された個所を生成した関数を利用した関数コールに置換える。
【０１４０】
これまで説明したとおり、全グローバル変数に対して、データ依存性の破壊が起こらない限りでブロック化し、関数化することで、各関数は、別タスクとして動作することが可能である。そこで、通信関数挿入ステップ１６１では、各関数コールの間に、タスク分割を行う指定記述を追加する手段を有する。挿入個所は、関数コールの位置であり、従来コンパイラの構文解析技術にて、容易に探索できる。このタスク分割の指定記述は、ＯｐｅｎＣＬ（Ｏｐｅｎ  Ｃｏｍｐｕｔｅｒ  Ｌａｎｇｕａｇｅ）等のマルチコア向け標準ライブラリで規定されており、規格に従ったタスク分割指定を追加する。
【０１４１】
図２０は、図１９で示したタスク分割部１５０の処理フローのうち、変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローで生成したブロック１９１のイメージと、関数化ステップ１５９で生成した関数１９２のイメージを示した図である。
【０１４２】
ブロック１９１は、グローバル変数ａ，ｂ，ｃのみが入出力変数である。ブロック１９１内のみで使用される変数は、ローカル変数としてブロック内に変数定義される。これを関数化ステップ１５９で関数化することで、関数１９２が生成される。関数１９２は、戻り値並びに仮引数が存在しない構造となる。
【０１４３】
次に、図２１、図２２、図２３を用いて、全グローバル変数をグルーピングしない場合のタスク分割部１５０の処理フローのうち、変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローを説明する。
【０１４４】
図２１は、全グローバル変数をグルーピングしない例の変数定義表１８０である。
変数Ｇ１、Ｇ２、Ｇ３、Ｇ４、Ｇ５、Ｇ６、Ｇ７はグローバル変数であり、変数Ｌ１、Ｌ２、Ｌ３、Ｌ４、Ｌ５、Ｌ６はローカル変数である。
【０１４５】
図２２と図２３は、図１９で示したタスク分割部１５０の処理フローのうち、変数定義変換ステップ１５１からローカル変数名称変更ステップ１５６までのフローで生成するコードの例を示した図である。
【０１４６】
図２２と図２３には、縦方向にコードの行番号、横方向に各グローバル変数に対して、ブロック化を行った結果が記してある。
【０１４７】
まず図２２において、入力コード２００は、最適通信量コード１６０を意味する。本入力コード２００では、全変数（５〜１０行目）がローカル変数の場合を起点としている。
【０１４８】
変数定義変換結果２０１は、入力コード２００に対し、変数定義変換ステップ１５１を行った結果である。なお、図中の矢印（⇒）は変換がなされた行に付加している。まず、変数定義変換ステップ１５１では、図２１の変数定義表１８０で定義したグローバル変数Ｇ１、Ｇ２、Ｇ３、Ｇ４、Ｇ５、Ｇ６、Ｇ７（入力コード２００の８〜１０行目）を変数定義変換２０１の１〜２行目のように、関数外に複製し、入力コード２００からは削除する。
【０１４９】
次に、Ｇ３ノード変換２０２に、グローバル変数抽出ステップ１５２にて抽出したグローバル変数Ｇ３に対して、入力ノード逆探索ステップ１５３からローカル変数名称変更ステップ１５６を行った結果を示す。変数定義変換２０１をグローバル変数抽出ステップ１５２にて上から検索した場合、第１のグローバル変数に対する代入は、グローバル変数Ｇ３に対して発生する。従って、まず、グローバル変数Ｇ３（逆探索対象変数）に対して変換を行う。グローバル変数Ｇ３は、１５行目（検索起点）で代入されており、検索起点から逆方向（上方向）に探索する。Ｇ３はＬ１とＬ２を元にライト参照されるため、Ｌ１とＬ２を逆探索した場合、１３行目、並びに１４行目にて、Ｌ１とＬ２のライト参照が存在する。本ライト参照の入力はグローバル変数Ｇ１とＧ２のみであるため、ここで逆探索を終了し、抽出文一覧として保持する。なお、検索終了点は、グローバル変数の最終リード参照位置である１３行目となる。次にコード並べ替えステップ１５４にて、抽出文一覧個所からコード並べ替えを行う。ここでは、例外文が存在しないため、並べ替えは発生しない。
【０１５０】
次に、ブロック化ステップ１５５にて、ブロック個所（１３〜１５行目）を中括弧“｛｝”で括る（１１行目と１６行目）と共に、ブロック内で使用されたローカル変数Ｌ１、Ｌ２をブロック内（１２行目）に複製し、５行目から削除する。次に、ローカル変数名変更ステップ１５６にて、ローカル変数Ｌ１が２８行目でリード参照されていると判断し、１７行目にユニークな名前Ｌ１＿ｔｍｐとして再定義し、２８行目のリード参照個所を、再定義したＬ１＿ｔｍｐで置換する。これら一連の処理シーケンスにより、グローバル変数Ｇ３に対してブロック化する。また、この時点で、新規検索対象を関数コールの次段、すなわち１７行目に移動し、次のグローバル変数に対するライト参照を探索し、処理を繰り返す。
【０１５１】
同様に、図２２のＧ４ノード変換２０３、図２３のＧ５ノード変換２０４、Ｇ６ノード変換２０５、及びＧ７ノード変換２０６を実行する。結果、Ｇ７ノード変換２０６のように、各グローバル変数Ｇ１、Ｇ２、Ｇ３、Ｇ４、Ｇ５、Ｇ６、Ｇ７に対し、ブロック化が終了する。
【０１５２】
次に、図２４と図２５を参照して、図１９のブロック化判断ステップ１５７とブロック化ステップ１５８の動作について説明する。
【０１５３】
図２４は、特定のグローバル変数に対して、同一のグループ名情報１８７を指定することで、グループ化指定した変数定義表１８０を示す図である。図のように、グローバル変数Ｇ３とＧ５をグループ化する。なお本例では、先の図２１、図２２、図２３で説明した、全グローバル変数をグループ化しない状態であるＧ７ノード変換２０６を起点とする。
【０１５４】
図２５は、Ｇ７ノード変換２０６から、グローバル変数Ｇ３とＧ５をグループ化した場合の変換例を示す図である。グローバル変数Ｇ３は、Ｇ７ノード変換２０６の１１〜１６行目のブロックにて代入される。これを非代入ブロックとする。同様に、グローバル変数Ｇ５は、Ｇ７ノード変換２０６の２７〜２９行目のブロックにて代入される。これを代入ブロックとする。グローバル変数Ｇ５の入力ノードは、グローバル変数Ｇ１とＧ２のみである。ここで、グローバル変数Ｇ５の代入ブロック（２７〜２９行目）の上部（逆方向）にある上位ブロック（１８〜２４行目）にて、これらＧ１とＧ２のライト参照は実行されていないため、データ依存性はなく、グローバル変数Ｇ５の代入ブロック（２７〜２９行目）は上位ブロック（１８〜２４行目）の更に上部に移動可能である。このように、代入ブロックを上位ブロックに対して移動可能かを判断するステップがブロック化判断ステップ１５７である。ブロック化判断ステップ１５７では、この移動を繰り返し実行し、非代入ブロックまで到達した時点で、ブロック化可能と判断する。次にブロック化ステップ１５８により、非代入ブロックの後部に代入ブロックをマージして接続する。このブロック化ステップ１５８の結果が、ブロック化結果２０７である。この様な処理シーケンスにより、複数のグローバル変数に対して、共通化、すなわちブロック化する。
【０１５５】
図２６と図２７を参照して、ブロック化判断ステップ１５７にて、ブロック化不可と判断した場合の動作について説明する。
【０１５６】
図２６は、特定のグローバル変数に対して、同一のグループ名情報１８７を指定することで、グループ化指定した変数定義表１８０を示す図である。図２７は、Ｇ７ノード変換２０６から、グローバル変数Ｇ３、Ｇ５、Ｇ６をグループ化した場合の変換例を示す図である。
【０１５７】
図１９のブロック化判断ステップ１５７にて、ブロック化不可と判断した場合、図２６、図２７のように、グローバル変数Ｇ３、Ｇ５、Ｇ６をグループ化する。なお本例では、先に示したように、グローバル変数Ｇ３とＧ５はブロック化出来るため、そのフローが終了した時点である図２５のブロック化結果２０７を起点とする。
【０１５８】
先と同様に、ブロック化判断ステップ１５７にて、代入ブロックを（３０〜３２行目）とし、非代入ブロックを（１１〜１７行目）とする。代入ブロックにはグローバル変数Ｇ４とＧ５のリード参照がある。このグローバル変数Ｇ４へのライト参照が上位ブロック（１８〜２４行目）中に含まれる。従って、代入ブロックを上位ブロックよりも上位に移動すると、データ依存性が破壊されるため、移動することが出来ない。そこで、ブロック化判断ステップ１５７では、この様に、ブロックを移動不可、すなわちブロック化不可と判断した場合は、ブロック化除去ステップ１６２に遷移し、ブロック化除去ステップ１６２は対象グローバル変数のブロック化を抑止するように指示を変更すると共に、第２のコード構造変換装置５のユーザインタフェースとして、ユーザにグループ化不可であったと通知する。
【０１５９】
この様に、第２の実施形態における第２のコード構造変換装置では、入力された最適通信量コード１６０に対し、グローバル変数のみをインタフェースとした、タスク並列可能なタスク並列コード１８１を自動で生成できる。並列コンパイル処理部１９０はタスク並列コード１８１を入力とし、並列オブジェクト１８２を生成する。本並列オブジェクト１８２により、マルチコア環境でのコード実行を可能とし、より低い周波数にて、マルチタスク処理を実現可能で、処理速度を向上できる。
【実施例３】
【０１６０】
以下、本発明の第３の実施形態について図面を参照して詳細に説明する。まず、本発明におけるコード構造変換装置を採用した情報処理装置１０の構成について説明する。
【０１６１】
図２８は、本発明の第３の実施形態における情報処理装置１０の構成を示す図である。情報処理装置１０は、パーソナルコンピュータやワークステーション等（以下、ＰＣと省略する）で構成する。
【０１６２】
ＰＣで構成される情報処理装置１０は、ＰＣでの処理結果やユーザインタフェースなどを表示するＰＣ画面を表示する表示装置１１と、ＣＰＵ１６やハードディスクドライブ１４、ＤＶＤディスクなどのメディアドライブ１３、ネットワークを接続可能なポートを有するＰＣ本体１２で構成する。ハードディスクドライブ１４には、第１の実施形態で説明した第１のデータ蓄積部４、又は、第２の実施形態で説明した第２のデータ蓄積部７が配置される。
【０１６３】
また、第１の実施形態で説明したコード構造変換部２と第１の入力制御部３、若しくは、第２の実施形態で説明したコード構造変換部２と第２の入力制御部６は、コード構造変換プログラム実行形式１５で構成する。すなわち、図１Ａや図１Ｃのコード構造変換部２に相当するコード構造変換プログラム実行形式１５は、Ｃ言語などのプログラミング言語で記述されたコード構造変換プログラムで構成され、コード構造変換プログラムをコンパイラによりＣＰＵ１６で実行可能なオブジェクト形式に変換されたコード構造変換プログラムで構成される。本コード構造変換プログラム実行形式１５は、ＣＰＵ１６上で実行可能である。
【０１６４】
また、本コード構造変換プログラム実行形式１５は、外部メディア１７に格納された第２のコード構造変換プログラム実行形式１８と同一であり、外部メディア１７からハードディスクドライブ１４に対し、第２のコード構造変換プログラム実行形式１８を複製することによっても、ＣＰＵ１６上で実行可能となる。また、コード構造変換プログラム実行形式１５はインタネット回線２１経由で接続されたプログラム提供者１９が有する第３のコード構造変換プログラム実行形式２０と同一であり、ＰＣ本体１２のハードディスクドライブ１４にコード構造変換プログラム実行形式２０としてダウンロードで複製することにより、情報処理装置１０上で、実行可能となる。
【０１６５】
本コード構造変換プログラム実行形式１５、１８、あるいは２０の利用者は、情報処理装置１０上でコード構造変換プログラム実行形式１５を実行し、ハードディスクドライブ１４内の第１のデータ蓄積部４、若しくは第２のデータ蓄積部７の情報を閲覧できる。
【０１６６】
本構成に従えば、コード構造変換プログラム実行形式１５１８、あるいは２０は、情報処理装置１０にて実行可能となる。
【符号の説明】
【０１６７】
１・・・第１のコード構造変換装置、２・・・コード構造変換部、３・・・第１の入出力制御部、４・・・第１のデータ蓄積部、５・・・第２のコード構造変換装置、６・・・第２の入出力制御部、７・・・第２のデータ蓄積部、１０・・・情報処理装置、１１・・・表示装置、１２・・・ＰＣ本体、１３・・・メディアドライブ、１４・・・ハードディスクドライブ、１５・・・第１のコード構造変換プログラム実行形式、１６・・・ＣＰＵ、１７・・・外部メディア、１８・・・第２のコード構造変換プログラム実行形式、１９・・・プログラム提供者、２０・・・第３のコード構造変換プログラム実行形式、２１・・・ネットワーク回線、３１・・・ガウシアン平滑化関数、３２・・・メディアン平滑化関数、３３・・・エッジ保持平滑化関数、１００・・・オリジナルコード、１１０・・・インライン展開部、１１１・・・関数定義の抽出手段、１１２・・・関数の戻り値の変換手段、１１３・・・関数の仮引数の変換手段、１１４・・・関数コール箇所の抽出手段、１１５・・・関数コールの等価変換手段、１１６・・・関数埋め込み、フラット・コードの生成手段、１３０・・・通信量最適化部、１５０・・・タスク分割部、１６０・・・最適通信量コード、１７０・・・フラット・コード、１８０・・・変数定義表、１８１・・・タスク並列コード、１８２・・・並列オブジェクト、１８５・・・変数名情報、１８６・・・変数スコープ情報、１８７・・・グループ名情報、１９０・・・並列コンパイル処理部、４１０・・・データベース、４６０・・・データベース、
Ｓ１１０・・・オリジナルコード入力ステップ、Ｓ１１１・・・関数抽出ステップ、Ｓ１１２・・・戻り値変換ステップ、Ｓ１１３・・・仮引数変換ステップ、Ｓ１１４・・・関数判断ステップ、Ｓ１１５・・・対象関数更新ステップ、Ｓ１１６・・・関数コール抽出ステップ、Ｓ１１７・・・関数コールの等価変換ステップ、Ｓ１１８・・・関数埋め込みステップ、Ｓ１１９・・・関数コール判断ステップ、Ｓ１２０・・・対象関数更新ステップ、Ｓ１２１・・・フラット・コード生成・記録、Ｓ１２２・・・ＳＳＡ形式変換ステップ、Ｓ１２３・・・文単位並べ替えステップ、Ｓ１３１・・・ループ文抽出ステップ、Ｓ１３２・・・ループ文特徴抽出ステップ、Ｓ１３３・・・配列ループ文判断ステップ、Ｓ１３４・・・大局的番号付けステップ、Ｓ１３５・・・現ループ解析終了ステップ、１３６・・・大局的番号付け結果、Ｓ１３７・・・ループアンロール・ステップ、Ｓ１３８・・・ループアンロール結果、Ｓ１３９・・・ループ融合ステップ、Ｓ１４０・・・ループ融合結果、Ｓ１４１・・・変数リネーミング・ステップ、Ｓ１４２・・・変数リネーミング結果、Ｓ１４３・・・デッドコード削除ステップ、Ｓ１５１・・・変数定義変換ステップ、Ｓ１５２・・・グローバル変数抽出ステップ、Ｓ１５３・・・入力ノード逆探索ステップ、Ｓ１５４・・・コード並べ替えステップ、Ｓ１５５・・・ブロック化ステップ、Ｓ１５６・・・ローカル変数名称変更ステップ、Ｓ１５９・・・関数化ステップ、Ｓ１６１・・・通信関数挿入ステップ、Ｓ１６２・・・グループ化除去ステップ、１１７０・・・ｉｆ文判定ステップ、１１７１・・・ｉｆ変換ステップ、１１７２・・・ｗｈｉｌｅ文判定ステップ、１１７３・・・ｗｈｉｌｅ変換ステップ、１１７４・・・ｄｏ−ｗｈｉｌｅ文判定ステップ、１１７５・・・ｄｏ−ｗｈｉｌｅ変換ステップ、１１７６・・・ｆｏｒ文判定ステップ、１１７７・・・ｆｏｒ変換ステップ、１１７８・・・ｓｗｉｔｃｈ文判定ステップ、１１７９・・・ｓｗｉｔｃｈ変換ステップ、１１８０・・・関数引数判定ステップ、１１８１・・・関数引数変換ステップ。
【図１Ａ】
2012014526.tif 000003
【図１Ｂ】
2012014526.tif 000004
【図１Ｃ】
2012014526.tif 000005
【図２】
2012014526.tif 000006
【図３】
2012014526.tif 000007
【図４】
2012014526.tif 000008
【図５】
2012014526.tif 000009
【図６】
2012014526.tif 000010
【図７】
2012014526.tif 000011
【図８】
2012014526.tif 000012
【図９】
2012014526.tif 000013
【図１０】
2012014526.tif 000014
【図１１】
2012014526.tif 000015
【図１２】
2012014526.tif 000016
【図１３】
2012014526.tif 000017
【図１４】
2012014526.tif 000018
【図１５】
2012014526.tif 000019
【図１６】
2012014526.tif 000020
【図１７】
2012014526.tif 000021
【図１８】
2012014526.tif 000022
【図１９】
2012014526.tif 000023
【図２０】
2012014526.tif 000024
【図２１】
2012014526.tif 000025
【図２２】
2012014526.tif 000026
【図２３】
2012014526.tif 000027
【図２４】
2012014526.tif 000028
【図２５】
2012014526.tif 000029
【図２６】
2012014526.tif 000030
【図２７】
2012014526.tif 000031
【図２８】
2012014526.tif 000032
【図２９】
2012014526.tif 000033
【図３０】
2012014526.tif 000034