(57)【要約】【課題】  テンプレートコンパイル方法において、テンプレートから生成される複数の関数定義コードのうち、同一コードとなるものの関数定義コードの共有化を図って、テンプレート機構により増加するコードサイズを縮小する。【解決手段】  同一関数定義生成判定ステップＳ１０５により、関数定義コードとテンプレートパラメータとの依存性を解析し、その依存性がない場合には、関数定義共通化ステップＳ１０６により、共通関数を定義し、共通化前の複数の関数定義を削除する。その後、関数呼び出し置換ステップＳ１０７により、共通化前の関数呼び出しを共通関数への呼び出しに置換する。【選択図】図１
2005141380.tif 000002
【特許請求の範囲】
【請求項１】
テンプレート機構を有する高級言語で記述された入力プログラムを目的コードに変換するテンプレートコンパイル方法であって、
前記入力プログラムに含まれる複数の関数定義において、テンプレートが異なるテンプレートパラメータに対して同一の関数定義を生成するかどうかを判定する同一関数定義生成判定ステップと、
前記同一関数定義生成判定ステップにより同一の関数定義を生成すると判定されたとき、その同一の関数定義を生成する複数の関数定義をただ一つの共通関数定義に置換する関数定義共通化ステップと、
前記関数定義共通化ステップにより共通関数定義への置換が行われたとき、その共通化される前の前記複数の関数の呼び出しを前記共通関数定義の呼び出しに置換する関数呼び出し置換ステップとを備えた
ことを特徴とするテンプレートコンパイル方法。
【請求項２】
請求項１記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記複数の関数定義において、前記テンプレートが関数テンプレートであり、且つ、関数定義部分にテンプレートパラメータ依存箇所が存在するかどうかを解析する
ことを特徴とするテンプレートコンパイル方法。
【請求項３】
請求項２記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記解析の結果、テンプレートが関数テンプレートである前記複数の関数定義において、関数定義部分にテンプレートパラメータ依存箇所が存在しない場合には、少なくともファイル名、テンプレート関数名、及びインスタンス化関数名を含む非依存関数情報を生成する
ことを特徴とするテンプレートコンパイル方法。
【請求項４】
請求項１記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記複数の関数定義において、前記テンプレートがクラステンプレートであり、且つ、メンバ関数定義部分にテンプレートパラメータ依存箇所が存在するかどうかを解析する
ことを特徴とするテンプレートコンパイル方法。
【請求項５】
請求項４記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記解析の結果、テンプレートがクラステンプレートである前記複数の関数定義において、メンバ関数定義部分にテンプレートパラメータ依存箇所が存在しない場合には、少なくともファイル名、テンプレート関数名、及びインスタンス化関数名を含む非依存関数情報を生成する
ことを特徴とするテンプレートコンパイル方法。
【請求項６】
請求項１記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記複数の関数定義において、前記テンプレートが関数テンプレートであり且つ関数定義部分にテンプレートパラメータ依存の型変換が存在するかどうか、テンプレートパラメータ依存の引数による関数呼び出しが存在するかどうか、及び、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在するかどうかを各々解析する
ことを特徴とするテンプレートコンパイル方法。
【請求項７】
請求項６記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記解析の結果、関数定義部分にテンプレートパラメータ依存の型変換が存在せず、テンプレートパラメータ依存の引数による関数呼び出しが存在せず、且つ、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在する場合には、ファイル名、テンプレート関数名、パラメータサイズ、及びインスタンス関数名を含む特定パラメータ同一関数情報を生成する
ことを特徴とするテンプレートコンパイル方法。
【請求項８】
請求項１記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記複数の関数定義において、前記テンプレートがクラステンプレートであり且つメンバ関数定義部分にテンプレートパラメータ依存の型変換が存在するかどうか、テンプレートパラメータ依存の引数による関数呼び出しが存在するかどうか、及び、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在するかどうかを各々解析する
ことを特徴とするテンプレートコンパイル方法。
【請求項９】
請求項８記載のテンプレートコンパイル方法において、
前記同一関数定義生成判定ステップは、
前記解析の結果、メンバ関数定義部分にテンプレートパラメータ依存の型変換が存在せず、テンプレートパラメータ依存の引数による関数呼び出しが存在せず、且つ、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在する場合には、ファイル名、テンプレート関数名、パラメータサイズ、及びインスタンス関数名を含む特定パラメータ同一関数情報を生成する
ことを特徴とするテンプレートコンパイル方法。
【請求項１０】
請求項３又は５記載のテンプレートコンパイル方法において、
前記関数定義共通化ステップは、
前記同一関数定義生成判定ステップが生成した非依存関数情報を受け、
前記非依存関数情報のうち、同一テンプレートから生成されているインスタンス化関数名に対して共通関数名を登録し、
前記同一テンプレートから生成されているインスタンス化関数の関数定義コードを、前記共通関数の関数定義コードに変更する
ことを特徴とするテンプレートコンパイル方法。
【請求項１１】
請求項７又は９記載のテンプレートコンパイル方法において、
前記関数定義共通化ステップは、
前記同一関数定義生成判定ステップが生成した特定パラメータ同一関数情報を受け、
前記特定パラメータ同一関数情報のうち、同一テンプレートの同一パラメータサイズから生成されているインスタンス化関数名に対して共通関数名を登録し、
前記同一テンプレートの同一パラメータサイズから生成されているインスタンス化関数の関数定義コードを、前記共通関数の関数定義コードに変更する
ことを特徴とするテンプレートコンパイル方法。
【請求項１２】
請求項１記載のテンプレートコンパイル方法において、
前記関数呼び出し置換ステップは、
共通化される前の関数の先頭アドレスを使用した関数呼び出し命令を、前記関数定義共通化ステップでの共通関数定義の先頭アドレスを使用した関数呼び出し命令に置換する
ことを特徴とするテンプレートコンパイル方法。
【請求項１３】
請求項１記載のテンプレートコンパイル方法において、
前記関数呼び出し置換ステップは、
関数呼び出しが仮想関数呼び出しである場合には、仮想関数のテーブルに登録されている前記共通化される前の関数の先頭アドレスを、前記関数定義共通化ステップでの共通関数定義の先頭アドレスに置換する
ことを特徴とするテンプレートコンパイル方法。
【請求項１４】
請求項１３記載のテンプレートコンパイル方法において、
前記関数呼び出し置換ステップは、
前記仮想関数テーブルに登録されている前記共通化される前の関数の先頭アドレスを前記共通関数定義の先頭アドレスに置換した結果、登録されている内容が等しくなる複数の仮想関数テーブルが存在する場合には、この複数の仮想関数テーブルを、登録内容が同一の一つの共通仮想関数テーブルに置換する
ことを特徴とするテンプレートコンパイル方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、テンプレート機構を有する高級言語で記述されたプログラムを目的コードに変換するコンパイル方法に関する。
【背景技術】
【０００２】
近年のソフトウェア開発においては、プログラムの規模が大規模化してきており、それに伴って保守性、再利用性の高いオブジェクト指向言語が注目されている。
【０００３】
代表的なオブジェクト指向言語にＣ＋＋言語が挙げられる。Ｃ＋＋言語はテンプレート機構を有しており、保守性、再利用性の高いジェネリックプログラミングが可能となっている。また、ＳＴＬとよばれる標準テンプレートライブラリが通常コンパイラに提供されており、今後更にテンプレート機構を利用したプログラミングが増加すると思われる。
【０００４】
図１２にテンプレート機構を利用したＣ＋＋プログラムをコンパイルした場合の生成コード例を示す。
【０００５】
図１２のソースコード(a)及び(b)のように、Ｃ＋＋ではクラス群及び関数群を表すテンプレートを定義し、テンプレートパラメータを与えることによって容易に関数定義を生成することが可能である。ソースコード(c)では、(a)や(b)のテンプレートに対して、テンプレートパラメータint及びlongを与えることでA<int>型、A<long>型のクラス、及び戻り値がvoid型、引数がint型及びlong型である関数A<int>::f、A<long>::fを生成させると同時に、A<int>型のオブジェクト’a’、A<long>型のオブジェクト’b’を定義している。ソースコード(d)では、生成したメンバ関数A<int>::fやA<long>::fの呼び出しを行なっている。
【０００６】
図１２の生成コードは、ソースコードに対して従来のコンパイル方法でコンパイルを行なった結果である。テンプレートにパラメータint、longを与えた結果生成された関数A<int>::fの定義コード(f)や関数A<long>::fの定義コード(g)がそれぞれ生成され、また関数hの定義コード(e)において、(f)、(g)の定義がcall文によって呼び出されているのが判る。ここで、call命令のオペランドであるラベルは、関数定義の先頭アドレスを表すラベルである。以上のように、テンプレートを定義し、テンプレートパラメータを与えることにより、容易に複数のクラス、関数を生成することができる。
【０００７】
従来のコンパイルでは、テンプレートに対して異なるテンプレートパラメータを与えると、必ずそれぞれのパラメータ値に対する関数(静的関数、外部関数、仮想、非仮想メンバ関数を含む)は別の定義としてコード生成されている。例えば、前記の図１２では、テンプレートパラメータ intに対して、(f)の定義コード、longに対して、(g)の定義コードが生成されている。このため、「テンプレートから生成される関数定義のコードサイズ」×「テンプレートパラメータの種類」に従って、全体のコードサイズは著しく増大する。
【０００８】
しかし、テンプレートから生成される関数は、テンプレートパラメータが異なるからといって全て異なるコードが生成されるわけではなく、同一コードが生成される場合がある。前記した図１２の例では、A<int>::fとA<long>::fはテンプレートパラメータが異なるが、生成されている定義コード(f)と(g)は全く同じである。
【０００９】
従来の技術として、このようなコードサイズ増加を防ぐため、プログラムの共通部分を、型指定されないインプリメンテーションクラスとして、仮引数化されたテンプレートを有する型指定されたインターフェースクラスから分離するプログラム記述方法が提案されている（例えば、特許文献１参照）。
【特許文献１】特開平９−２３１０７７号公報（図８）
【発明の開示】
【発明が解決しようとする課題】
【００１０】
しかしながら、前記従来の技術では、プログラマーが意識してプログラムの共通部分を型指定されないインプリメンテーションクラスとしてプログラムを記述することを強制させるものであり、プログラマーに対する負担が大きい。
【００１１】
本発明の目的は、テンプレートコンパイル方法において、プログラマーに最適なプログラム記述を意識させることなく、テンプレート機構により増加するコードサイズを縮小する方法を提供することにある。
【課題を解決するための手段】
【００１２】
前記目的を達成するために、本発明では、テンプレートから生成される複数の関数定義コードのうち、同一コードとなる複数の関数定義コードをＣＰＵにより自動判定して、それらの同一コードとなる複数の関数定義コードの共有化を図ることとする。
【００１３】
すなわち、請求項１記載の発明のテンプレートコンパイル方法は、テンプレート機構を有する高級言語で記述された入力プログラムを目的コードに変換するテンプレートコンパイル方法であって、前記入力プログラムに含まれる複数の関数定義において、テンプレートが異なるテンプレートパラメータに対して同一の関数定義を生成するかどうかを判定する同一関数定義生成判定ステップと、前記同一関数定義生成判定ステップにより同一の関数定義を生成すると判定されたとき、その同一の関数定義を生成する複数の関数定義をただ一つの共通関数定義に置換する関数定義共通化ステップと、前記関数定義共通化ステップにより共通関数定義への置換が行われたとき、その共通化される前の前記複数の関数の呼び出しを前記共通関数定義の呼び出しに置換する関数呼び出し置換ステップとを備えたことを特徴とする。
【００１４】
請求項２記載の発明は、前記請求項１記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記複数の関数定義において、前記テンプレートが関数テンプレートであり、且つ、関数定義部分にテンプレートパラメータ依存箇所が存在するかどうかを解析することを特徴とする。
【００１５】
請求項３記載の発明は、前記請求項２記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記解析の結果、テンプレートが関数テンプレートである前記複数の関数定義において、関数定義部分にテンプレートパラメータ依存箇所が存在しない場合には、少なくともファイル名、テンプレート関数名、及びインスタンス化関数名を含む非依存関数情報を生成することを特徴とする。
【００１６】
請求項４記載の発明は、前記請求項１記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記複数の関数定義において、前記テンプレートがクラステンプレートであり、且つ、メンバ関数定義部分にテンプレートパラメータ依存箇所が存在するかどうかを解析することを特徴とする。
【００１７】
請求項５記載の発明は、前記請求項４記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記解析の結果、テンプレートがクラステンプレートである前記複数の関数定義において、メンバ関数定義部分にテンプレートパラメータ依存箇所が存在しない場合には、少なくともファイル名、テンプレート関数名、及びインスタンス化関数名を含む非依存関数情報を生成することを特徴とする。
【００１８】
請求項６記載の発明は、前記請求項１記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記複数の関数定義において、前記テンプレートが関数テンプレートであり且つ関数定義部分にテンプレートパラメータ依存の型変換が存在するかどうか、テンプレートパラメータ依存の引数による関数呼び出しが存在するかどうか、及び、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在するかどうかを各々解析することを特徴とする。
【００１９】
請求項７記載の発明は、前記請求項６記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記解析の結果、関数定義部分にテンプレートパラメータ依存の型変換が存在せず、テンプレートパラメータ依存の引数による関数呼び出しが存在せず、且つ、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在する場合には、ファイル名、テンプレート関数名、パラメータサイズ、及びインスタンス関数名を含む特定パラメータ同一関数情報を生成することを特徴とする。
【００２０】
請求項８記載の発明は、前記請求項１記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記複数の関数定義において、前記テンプレートがクラステンプレートであり且つメンバ関数定義部分にテンプレートパラメータ依存の型変換が存在するかどうか、テンプレートパラメータ依存の引数による関数呼び出しが存在するかどうか、及び、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在するかどうかを各々解析することを特徴とする。
【００２１】
請求項９記載の発明は、前記請求項８記載のテンプレートコンパイル方法において、前記同一関数定義生成判定ステップは、前記解析の結果、メンバ関数定義部分にテンプレートパラメータ依存の型変換が存在せず、テンプレートパラメータ依存の引数による関数呼び出しが存在せず、且つ、型サイズが同じであるテンプレートパラメータでインスタンス化された関数定義が既に存在する場合には、ファイル名、テンプレート関数名、パラメータサイズ、及びインスタンス関数名を含む特定パラメータ同一関数情報を生成することを特徴とする。
【００２２】
請求項１０記載の発明は、前記請求項３又は５記載のテンプレートコンパイル方法において、前記関数定義共通化ステップは、前記同一関数定義生成判定ステップが生成した非依存関数情報を受け、前記非依存関数情報のうち、同一テンプレートから生成されているインスタンス化関数名に対して共通関数名を登録し、前記同一テンプレートから生成されているインスタンス化関数の関数定義コードを、前記共通関数の関数定義コードに変更することを特徴とする。
【００２３】
請求項１１記載の発明は、請求項７又は９記載のテンプレートコンパイル方法において、前記関数定義共通化ステップは、前記同一関数定義生成判定ステップが生成した特定パラメータ同一関数情報を受け、前記特定パラメータ同一関数情報のうち、同一テンプレートの同一パラメータサイズから生成されているインスタンス化関数名に対して共通関数名を登録し、前記同一テンプレートの同一パラメータサイズから生成されているインスタンス化関数の関数定義コードを、前記共通関数の関数定義コードに変更することを特徴とする。
【００２４】
請求項１２記載の発明は、前記請求項１記載のテンプレートコンパイル方法において、前記関数呼び出し置換ステップは、共通化される前の関数の先頭アドレスを使用した関数呼び出し命令を、前記関数定義共通化ステップでの共通関数定義の先頭アドレスを使用した関数呼び出し命令に置換することを特徴とする。
【００２５】
請求項１３記載の発明は、請求項１記載のテンプレートコンパイル方法において、前記関数呼び出し置換ステップは、関数呼び出しが仮想関数呼び出しである場合には、仮想関数のテーブルに登録されている前記共通化される前の関数の先頭アドレスを、前記関数定義共通化ステップでの共通関数定義の先頭アドレスに置換することを特徴とする。
【００２６】
請求項１４記載の発明は、請求項１３記載のテンプレートコンパイル方法において、前記関数呼び出し置換ステップは、前記仮想関数テーブルに登録されている前記共通化される前の関数の先頭アドレスを前記共通関数定義の先頭アドレスに置換した結果、登録されている内容が等しくなる複数の仮想関数テーブルが存在する場合には、この複数の仮想関数テーブルを、登録内容が同一の一つの共通仮想関数テーブルに置換するとを特徴とする。
【００２７】
以上により、請求項１〜請求項１４記載の発明では、先ず、入力プログラムの複数の関数定義について、テンプレートが異なるテンプレートパラメータに対して同一の関数定義を生成するかどうかを判定し、その判定の結果、同一の関数定義を生成する場合には、それらの複数の関数定義を１つの共通関数定義に置換すると共に、それらの複数の関数定義に対する呼出しを前記共通関数定義に対する呼出しに置換する。
【００２８】
従って、入力プログラムにおいて、テンプレートに対して与えるパラメータが相互に異なる複数の関数定義が存在する場合であっても、それらの複数の関数定義が同一の定義コードを生成するときには、得られる出力コードにおいて、それらの複数の関数定義別に同一の定義コードが重複して存在することがなく、コードサイズの少ない効率の良い目的コードを生成することができる。
【発明の効果】
【００２９】
以上説明したように、請求項１〜１４記載の発明のテンプレートコンパイル方法によれば、入力プログラムにおいてテンプレートに対して与えるパラメータが相互に異なる複数の関数定義が存在する場合であっても、それらの複数の関数定義が同一の定義コードを生成するときには、得られる出力コードにおいて同一の定義コードが重複して存在することがないので、コードサイズの少ない効率の良い目的コードを生成することができる。
【００３０】
特に、請求項２記載の発明のテンプレートコンパイル方法によれば、関数テンプレートから生成されるテンプレートパラメータに依存しない関数に対しても、効率の良い目的コードを生成することができる。
【００３１】
また、請求項４記載の発明のテンプレートコンパイル方法によれば、クラステンプレートから生成されるテンプレートパラメータに依存しないメンバ関数に対しても、効率の良い目的コードを生成することができる。
【００３２】
更に、請求項６記載の発明のテンプレートコンパイル方法によれば、関数テンプレートから生成される特定のテンプレートパラメータの組み合わせにのみ依存しない関数に対しても、効率の良い目的コードを生成することができる。
【００３３】
加えて、請求項８記載の発明のテンプレートコンパイル方法によれば、クラステンプレートから生成される特定のテンプレートパラメータの組み合わせにのみ依存しないメンバ関数に対しても、効率の良い目的コードを生成することができる。
【００３４】
また、請求項１２及び請求項１３記載の発明のテンプレートコンパイル方法によれば、非仮想的な関数や仮想的な関数の呼び出しコードに対しても、効率の良い目的コードを生成することができる。
【００３５】
更に、請求項１４記載の発明のテンプレートコンパイル方法によれば、仮想関数テーブルのコードに対しても、効率の良い目的コードを生成することができる。
【発明を実施するための最良の形態】
【００３６】
以下、本発明のコンパイル方法の実施形態の一例について図面を参照しながら説明する。
【００３７】
図１は本発明の実施形態におけるコンパイルステップの構成図を示す。
【００３８】
図１において、このコンパイルステップは、入力ステップＳ１０２、構文解析ステップＳ１０３、同一関数定義生成判定ステップＳ１０５、関数定義共通化ステップＳ１０６、関数呼び出し置換ステップＳ１０７、中間コード生成ステップＳ１０９、最適化ステップＳ１１０、資源割付ステップＳ１１１及び出力ステップＳ１１２から構成されている。このコンパイルステップ中の各ステップは、ＣＰＵを備えたコンパイル装置がコンパイラに基づいて行なう処理である。
【００３９】
プログラム記憶部Ｄ１０１は、コンパイル対象の入力プログラムを保持している。
【００４０】
入力ステップＳ１０２は、プログラム記憶部Ｄ１０１に格納されている全てのプログラムを順次入力し、構文解析ステップＳ１０３に渡す。
【００４１】
構文解析ステップＳ１０３は、入力ステップＳ１０２から受け取ったプログラムの構文を解析し、シンボルテーブルの生成や構文木の生成などを行なう。
【００４２】
同一関数定義生成判定ステップＳ１０５は、構文解析ステップＳ１０３で生成された情報のうち、テンプレート関連情報を抽出し、テンプレートが、異なるテンプレートパラメータに対して同一の関数定義を生成するかどうかを解析する。
【００４３】
関数定義共通化ステップＳ１０６は、構文解析ステップＳ１０３で生成された情報のうち、関数定義関連情報を抽出し、また同一関数定義判定ステップＳ１０５から解析結果を受け取り、異なるテンプレートパラメータに対して同一の関数定義を生成した複数の関数定義をただ一つの共通関数定義に置換を行なう。
【００４４】
関数呼び出し置換ステップＳ１０７は、構文解析ステップＳ１０３で生成された情報のうち、関数呼び出し関連情報を抽出し、また関数定義共通化ステップＳ１０６から置換結果を受け取り、共通化された結果に基づいて、共通化される前の関数呼び出しを共通関数定義の呼び出しへと置換を行なう。
【００４５】
中間コード生成ステップＳ１０９は、構文解析ステップＳ１０３で生成された構文木を基に、中間コードを生成する。テンプレートから生成される関数定義及び仮想関数テーブルに関する中間コードを生成する際には、同一関数定義生成ステップＳ１０５、関数定義共通化ステップＳ１０６、関数呼び出し置換ステップＳ１０７を実行後に置換された情報を参照して、対応する中間コードを生成する。
【００４６】
最適化ステップＳ１１０は、中間コード生成ステップＳ１０９によって生成された中間コードに対して、各種の最適化を実行する。
【００４７】
資源割付ステップＳ１１１は、最適化ステップ１１０によって最適化された中間コードに含まれる全ての変数に対してレジスタやメモリなどのハードウェア資源を割り付ける。
【００４８】
出力ステップＳ１１２は、資源割付ステップＳ１１１によって資源割付された中間コードを目的コードに変換して、生成コード記憶部Ｄ１１３に出力する。
【００４９】
生成コード記憶部Ｄ１１３は、前記ステップＳ１０２〜Ｓ１１２までのコンパイルステップによって変換された目的コードを格納しておく。
【００５０】
尚、入力ステップＳ１０２、構文解析ステップＳ１０３、中間コード生成ステップＳ１０９、最適化ステップＳ１１０、資源割付ステップＳ１１１、出力ステップＳ１１２については、本発明の主眼ではないため、詳細な説明は省略する。
【００５１】
次に、同一関数定義生成判定ステップＳ１０５の処理について、図５に示すプログラムに適用した場合を例にして、図２を参照しながら説明する。
【００５２】
同一関数定義生成判定ステップＳ１０５の処理は、ステップａ１〜ａ１１によって行なわれる。以下、記号の順に説明していく。
【００５３】
ステップａ１では、構文解析ステップＳ１０３が生成した情報のうち、テンプレート関連の情報を抽出する。構文解析ステップＳ１０３によって、全ての入力ファイル中のテンプレートの情報が解析されているので、テンプレートに関する情報のみを抽出する。図５に示すプログラムでは、全ての入力ファイルｔｅｍｐｌａｔｅ１．ｃｃ、ｔｅｍｐｌａｔｅ２．ｃｃについて、各ファイル中で定義されているテンプレートは、ｔｅｍｐｌａｔｅ１．ｃｃでは関数テンプレートｇであり、ｔｅｍｐｌａｔｅ２．ｃｃではクラステンプレートＢであるので、図６（ａ）のような抽出結果が得られる。尚、図５の入力ファイルｔｅｍｐｌａｔｅ１．ｃｃ、ｔｅｍｐｌａｔｅ２．ｃｃの１行目の「＃ｉｎｃｌｕｄｅ」文は、その場所に“”で括られたファイルの内容を展開するという意味のプログラムである。
【００５４】
ステップａ２では、抽出した全テンプレート情報のうち、クラステンプレートのメンバ関数について、ループ１（ステップａ２〜ａ６）の処理を繰り返す。図６（ａ）では[２]と[３]がクラステンプレートのメンバ関数であるので、このメンバ関数[２]及び[３]についてループ１の処理を繰り返す。
【００５５】
ステップａ３では、メンバ関数のコードが、テンプレートパラメータに全く依存しないテンプレートコードを持つかどうかを調べる。Ｎｏの場合はステップａ４に、Ｙｅｓの場合はステップａ５に移行する。図６（ａ）のメンバ関数[２]についてステップａ３の判定を行なうと、メンバ関数[２]のコードは、テンプレートパラメータＴの値に関わらず、ｒｅｔｕｒｎ  ｂ；となり、Ｔの値に全く依存しないので、ステップａ３の判定はＹｅｓとなり、ステップａ５へと移行する。メンバ関数[３]のコードも、テンプレートパラメータＴの値に関わらず、ｒｅｔｕｒｎ  ｙ；となり、Ｔの値に全く依存しないので、ステップａ３の判定はＹｅｓとなり、ステップａ５へと移行する。
【００５６】
ステップａ４では、特定のテンプレートパラメータ値の組み合わせのみについて同一のコードが生成される関数が存在するかどうかを調べる。後述するステップａ７のループ２で行なわれる処理であるステップａ９とステップａ４との処理は同じである。図６（ａ）のメンバ関数[２]及び[３]は、ステップａ３でＹｅｓと判定されているので、ステップａ４の処理は行なわれない。処理の詳細はステップａ９の説明時に行なう。
【００５７】
ステップａ５では、ステップａ４でＹｅｓと判定されたメンバ関数に対するパラメータ非依存関数情報を生成する。図６（ａ）のメンバ関数[２]及び[３]は、パラメータ非依存関数であるので、少なくともファイル名、テンプレート関数名、テンプレートパラメータによって実体化（インスタンス化）されたインスタンス化関数名で構成される図６（ｂ）のパラメータ非依存関数情報が生成される。
【００５８】
ステップａ６では、ステップａ２に処理を移行し、ループ１の処理を繰り返す。
【００５９】
ステップａ７では、抽出した全テンプレート情報のうち、関数テンプレートについて、ループ２の処理を繰り返す。図６（ａ）では[１]が関数テンプレートである。この関数テンプレート[１]についてループ２の処理を実行する。
【００６０】
ステップａ８では、関数のコードが、テンプレートパラメータに全く依存しないテンプレートコードを持つかどうかを調べる。Ｎｏの場合はステップａ９、Ｙｅｓの場合はステップａ１０へ移行する。図６（ａ）の関数テンプレート[１]についてステップａ８の判定を行なうと、[１]のコードは、テンプレートパラメータＴの値によって、仮引数ａ、ｂの型が異なるため、テンプレートパラメータに依存する。従って、ステップａ８の判定はＮｏとなり、ステップａ９へと移行する。
【００６１】
ステップａ９は、特定のテンプレートパラメータ値の組み合わせのみについて同一のコードが生成される関数が存在するかどうかを調べる。ステップａ２のループ１で行なわれる処理であるステップａ４とステップａ９との処理は同じである。
【００６２】
前記ステップａ４及びステップａ９の処理は、ステップｂ１〜ｂ４によって行なわれる。以下記号の順に説明していく。
【００６３】
ステップｂ１では、関数コードの中に、明示的又は暗黙的な型変換が存在しないかどうかを判定する。Ｙｅｓの場合はステップｂ２に、Ｎｏの場合はステップａ４又はステップａ９の処理を抜ける。図６（ａ）の関数テンプレート[１]についてステップｂ１の判定を行なうと、関数テンプレート[１]のコード、ｒｅｔｕｒｎ  ａ＋ｂ；には型変換が存在しないので、ステップｂ１の判定はＹｅｓとなり、ステップｂ２へと移行する。
【００６４】
ステップｂ２では、関数コードの中に、パラメータ依存の引数による関数呼び出しが存在しないかどうかを判定する。Ｙｅｓの場合はステップｂ３に移動し、Ｎｏの場合はステップａ４又はステップａ９の処理を抜ける。図６（ａ）の[１]についてステップｂ２の判定を行なうと、[１]のコード、ｒｅｔｕｒｎ  ａ＋ｂ；の中には関数呼び出しが存在しないので、ステップｂ２の判定はＹｅｓとなり、ステップｂ３へと移行する。
【００６５】
ステップｂ３では、インスタンス化されたパラメータ値の中で、型サイズが同じであるパラメータで生成された関数定義が存在するかどうかを判定する。Ｙｅｓの場合はステップｂ４に移動し、Ｎｏの場合はステップａ４又はステップａ９の処理を抜ける。図６（ａ）の[１]についてステップｂ３の判定を行なうと、[１]のテンプレートに対してインスタンス化されているテンプレートパラメータはｉｎｔ型とｌｏｎｇ型である。コンパイル環境によっては、これらの型は同じサイズを持つ。ここでは、共に４ｂｙｔｅのサイズを持つと仮定する。型サイズが同じであるパラメータで生成された関数定義が存在するので、ステップｂ４へと移行する。
【００６６】
ステップｂ４では、ステップｂ１〜ステップｂ３までの判定で全てＹｅｓと判定された関数定義をもとに特定パラメータ同一関数情報を生成する。図６（ａ）の[１]は、ステップｂ１からステップｂ３までの判定で全てＹｅｓと判定され、テンプレートパラメータ値がｉｎｔの場合とｌｏｎｇの場合とで同一のコードが生成される。少なくともファイル名、テンプレート関数名、パラメータサイズ、インスタンス化関数名で構成される図６（ｃ）の特定パラメータ同一関数情報が生成される。
【００６７】
ステップａ１０では、ステップａ８でＹｅｓと判定された関数に対するパラメータ非依存関数情報を生成する。図６（ａ）の[１]は、ステップａ８でＮｏと判定されているので、ステップａ１０の処理は行なわれない。
【００６８】
ステップａ１１では、ステップａ７に処理を移行し、ループ２の処理を繰り返す。
【００６９】
以上、同一関数定義生成判定ステップＳ１０５の処理を図１０に示すプログラムに適用した場合、図６（ｂ）に示すパラメータ非依存関数情報及び図６（ｃ）に示す特定パラメータ同一関数情報が生成される。これらの結果が関数定義共通化ステップＳ１０６に渡される。
【００７０】
次に、関数定義共通化ステップＳ１０６の処理について、図３を参照しながら説明する。
【００７１】
関数定義共通化ステップＳ１０６の処理は、ステップｃ１〜ｃ８によって行なわれる。以下記号の順に説明していく。
【００７２】
ステップｃ１では、同一関数定義生成ステップＳ１０５から受け取った情報のうち、パラメータ非依存関数情報について、ループ１（ステップｃ１〜ｃ４）の処理を繰り返す。すなわち、本例では、図６（ｂ）のパラメータ非依存関数情報について、前記ループ１の処理を繰り返す。
【００７３】
ステップｃ２では、同一テンプレートから生成されているインスタンス化関数名に対して共通関数名を登録し、ステップｃ３へ移行する。例えば、図６（ｂ）に対してステップｃ２を実行することにより、図７（ａ）の[x]の部分が登録される。
【００７４】
ステップｃ３では、各インスタンス化関数の定義を構文解析結果から削除し、共通関数の定義を構文解析結果に登録し、ステップｃ４へ移行する。図７（ａ）の関数定義名情報[x]に対してステップｃ３を実行することにより、図７（ｂ）の[x]の部分で表現されている通り、インスタンス化関数の関数定義コードは削除され、共通関数の関数定義コードが新たに登録される。
【００７５】
ステップｃ４では、ステップｃ１に処理を移行し、ループ１の処理を繰り返す。
【００７６】
ステップｃ５では、同一関数定義生成ステップＳ１０５から受け取った情報のうち、特定パラメータ同一関数情報について、ループ２（ステップｃ５〜ｃ８）の処理を繰り返す。図６（ｃ）の特定パラメータ同一関数情報についてループ２の処理を繰り返す。
【００７７】
ステップｃ６では、同一テンプレートの同一パラメータサイズから生成されているインスタンス化関数名に対して共通関数名を登録し、ステップｃ７へ移行する。図６（ｃ）に対してステップｃ６を実行することにより、図７（ａ）に示した[y]の部分が登録される。
【００７８】
ステップｃ７では、各インスタンス化関数の定義を構文解析結果から削除し、共通関数の定義を関数定義部に登録し、ステップｃ８へ移行する。図７（ａ）に示した共通関数の定義名情報[y]に対してステップｃ７を実行することにより、図７（ｂ）の[y]の部分で表現されている通り、インスタンス化関数の関数定義コードは削除され、共通関数の関数定義コードが新たに構文解析結果に登録される。
【００７９】
ステップｃ８では、ステップｃ５に処理を移行し、ループ２の処理を繰り返す。
【００８０】
以上、関数定義共通化ステップＳ１０６の処理を図６（ｂ）及び図６（ｃ）に適用した場合、図７（ａ）に示す関数定義名及び図７（ｂ）に示す関数定義コードが生成され、これらの結果が関数呼び出し置換ステップＳ１０７に渡される。
【００８１】
次に、関数呼び出し置換ステップＳ１０７の処理について、図４を参照しながら説明する。
【００８２】
関数呼び出し置換ステップＳ１０７の処理は、ステップｄ１〜ｄ１３によって行なわれる。以下記号の順に説明していく。
【００８３】
ステップｄ１では、構文解析ステップＳ１０３で生成される情報のうち、関数呼び出し関連の情報を抽出する。また、各クラスに対する仮想関数テーブル情報が存在する場合には、この情報も抽出する。構文解析ステップＳ１０３によって、全ての入力ファイル中の関数呼び出し情報が解析されているので、関数呼び出しに関する情報及び仮想関数テーブル情報のみを抽出する。図５に示すプログラムでは、ｔｅｍｐｌａｔｅ１．ｃｃにおいて関数ｆｕｎｃ１が、テンプレートから生成される関数を呼び出しており、ｔｅｍｐｌａｔｅ２．ｃｃにおいても関数ｆｕｎｃ２がテンプレートから生成されるクラスのメンバ関数を呼び出しているので、図８（ａ）のような関数呼び出し情報の抽出結果が得られる。また、関数ｆｕｎｃ２において、クラスＡに継承されているクラスの仮想的な関数呼び出しを行なっているので、図８（ｂ）のような仮想関数テーブル情報の抽出結果が得られる。
【００８４】
ステップｄ２では、テンプレート生成関数を呼び出している全ての関数呼び出し情報について、ループ１の処理を繰り返す。図８（ａ）では関数ｆｕｎｃ１、ｆｕｎｃ２共にテンプレートから生成される関数を呼び出しているので、それぞれについてループ１の処理を繰り返す。
【００８５】
ステップｄ３では、共通関数名が登録された関数の呼び出しを共通関数呼び出しに置換する。図８（ａ）では符号（＃１）の関数呼出しが符号（＃２）の共通関数呼出しに、符号（＃３）の関数呼出しが符号（＃４）の共通関数呼出しに、符号（＃５）の関数呼出しが符号（＃６）の共通関数呼出しに、それぞれ置換される。
【００８６】
ステップｄ４では、関数呼び出しが仮想的な関数呼び出しであるかどうかの判定を行なう。Ｙｅｓの場合はステップｄ５に、Ｎｏの場合はステップｄ１３に移行する。図８（ａ）では、符号（＃４）が仮想的な関数呼び出しであるので、ステップｄ５に移行する。符号（＃２）や符号（＃６）は通常の呼び出しであるので、ステップｄ１３に移行する。
【００８７】
ステップｄ５では、仮想関数テーブルのうち、共通関数名が登録された関数を登録している仮想関数テーブルの全てについて、ループ２の処理を繰り返す。図８（ｂ）では、クラスＢ＜ｉｎｔ＞の仮想関数テーブル及びクラスＢ＜ｌｏｎｇ＞の仮想関数テーブルに対して、ループ２の処理を繰り返す。
【００８８】
ステップｄ６では、仮想関数テーブルに登録されている共通化された関数を共通関数に置換する。実際には関数へのアドレスが登録されているが、ここでは説明を簡易にするため単に関数としておく。図８（ｂ）では、符号（＃７）や符号（＃９）で登録されている関数は、関数定義共通化ステップＳ１０６で共通関数が登録されているので、符号（＃８）や符号（＃１０）で示したように、それぞれ共通関数に置換される。
【００８９】
ステップｄ７では、ステップｄ５に処理を移行し、ループ２の処理を繰り返す。
【００９０】
ステップｄ８では、置換が実行された仮想関数テーブルについて、ループ３の処理を繰り返す。図８（ｂ）では、仮想関数テーブルｖｔｂｌ＿Ｂ＜ｉｎｔ＞やｖｔｂｌ＿Ｂ＜ｌｏｎｇ＞についてループ３の処理を繰り返す。
【００９１】
ステップｄ９では、仮想関数テーブルに登録されている内容が、ステップｄ６の置換処理によって等しくなるものが存在するかどうかの判定を行なう。Ｙｅｓの場合はステップｄ１０に、Ｎｏの場合はステップｄ１２に移行する。図８（ｂ）では、ｖｔｂｌ＿Ｂ＜ｉｎｔ＞とｖｔｂｌ＿Ｂ＜ｌｏｎｇ＞とに登録されている内容が全く等しくなったので、ステップｄ１０に移行する。
【００９２】
ステップｄ１０では、等しくなった各仮想関数テーブルを削除し、共通仮想関数テーブルを生成する。図８（ｂ）の仮想関数テーブルｖｔｂｌ＿Ｂ＜ｉｎｔ＞やｖｔｂｌ＿Ｂ＜ｌｏｎｇ＞は、図９（ｂ）で示すように削除され、新たに共通仮想関数テーブルｖｔｂｌ＿Ｂが生成される。
【００９３】
ステップｄ１１では、仮想的関数呼び出し時に参照する仮想関数テーブルを共通仮想関数テーブルに置換する。図８（ａ）の仮想的呼び出しで参照していたｖｔｂｌ＿Ｂ＜ｉｎｔ＞及びｖｔｂｌ＿Ｂ＜ｌｏｎｇ＞は、図９（ａ）に示すように共通仮想関数テーブルｖｔｂｌ＿Ｂを参照するように置換される。
【００９４】
ステップｄ１２では、ステップｄ８に処理を移行し、ループ３の処理を繰り返す。
【００９５】
以上、同一呼び出し置換ステップＳ１０７の処理を図５に示すプログラムに適用した場合には、図９（ａ）に示す関数呼び出し情報及び図９（ｂ）に示す仮想関数テーブル情報が生成される。
【００９６】
中間コード生成ステップＳ１０９は、構文解析ステップＳ１０３で生成されたものに加えて、同一関数定義判定ステップＳ１０５、関数定義共通化ステップＳ１０６、関数呼び出し置換ステップＳ１０７で新たに生成されたものを含む全ての構文解析データを読み込み、最終的に生成コード記憶部Ｄ１１３に目的コードが生成され、格納される。
【００９７】
以上のように、本実施形態のコンパイルステップに、図５に示すプログラムを適用した結果として得られる出力コードを図１０に示す。また、比較のために、従来の方法でコンパイルを行なった結果得られる出力コードを図１１に示す。図１１の（ｃ）と（ｄ）、（ｆ）と（ｇ）、（ｌ）と（ｍ）、（ｎ）と（ｏ）のように重複していたコードが、本発明のコンパイルステップを適用することにより、図１０の（ｃ）、（ｅ）、（ｊ）、（ｋ）のように共通化されていることが判る。本実施形態のコンパイルステップを用いることにより、テンプレートに対して与えるパラメータが異なる場合でも、同一コードが生成される場合はコードサイズ及び実行ステップ数の少ない効率の良い目的コードを生成することができる。
【産業上の利用可能性】
【００９８】
以上説明したように、本発明は、入力プログラムにおいてテンプレートに対して与えるパラメータが相互に異なる複数の関数定義が存在する場合であっても、それらの複数の関数定義が同一の定義コードを生成するときには、得られる出力コードにおいて、その同一の１つの定義コードのみを存在させるので、コードサイズの少ない効率の良い出力コードを生成することができるテンプレートコンパイル方法等として有用である。
【図面の簡単な説明】
【００９９】
【図１】本発明の実施形態のテンプレートコンパイル方法におけるコンパイルステップを示す図である。
【図２】同コンパイルステップにおける同一関数定義生成ステップの処理フローチャートを示す図である。
【図３】同コンパイルステップにおける関数定義共通化ステップの処理フローチャートを示す図である。
【図４】同コンパイルステップにおける関数呼び出し置換ステップの処理フローチャートを示す図である。
【図５】プログラム記憶部に格納されるプログラムを示す図である。
【図６】（ａ）は同一関数定義ステップ内において抽出されるテンプレート情報を示す図、（ｂ）は同一関数定義ステップ内で生成されるパラメータ非依存関数情報を示す図、（ｃ）は同一関数定義ステップ内で生成される特定パラメータ同一関数情報を示す図である。
【図７】（ａ）は関数定義共通化ステップ内において共通関数名が登録された関数定義名情報を示す図、（ｂ）は関数定義共通化ステップ内において共通化前の関数定義コードが削除されて共通関数定義コードが登録された関数定義コード情報を示す図である。
【図８】（ａ）は関数呼び出し置換ステップ内において抽出される関数呼び出し情報と、共通関数への置換を示す図、（ｂ）は関数呼び出し置換ステップ内において抽出される仮想関数テーブル情報と、共通関数への置換を示す図である。
【図９】（ａ）は関数呼び出し置換ステップ内において仮想的呼び出し時の参照先を仮想関数テーブルから共通仮想関数テーブルへ置換させることを示す図、（ｂ）は関数呼び出し置換ステップ内において仮想関数テーブルの実体を共通仮想関数テーブルに置換させることを示す図である。
【図１０】本発明の実施形態のテンプレートコンパイル方法を用いた場合の出力結果を示す図である。
【図１１】従来のコンパイル方法を用いた場合の出力結果を示す図である。
【図１２】テンプレートを使用したプログラム例と、その出力コードを示す図である。
【符号の説明】
【０１００】
Ｄ１０１    プログラム記憶部
Ｓ１０２    入力ステップ
Ｓ１０３    構文解析ステップ
Ｓ１０５    同一関数定義生成判定ステップ
Ｓ１０６    関数定義共通化ステップ
Ｓ１０７    関数呼び出し置換ステップ
Ｓ１０９    中間コード生成ステップ
Ｓ１１０    最適化ステップ
Ｓ１１１    資源割り付けステップ
Ｓ１１２    出力ステップ
Ｄ１１３    生成コード記憶部
【図１】
2005141380.tif 000003
【図２】
2005141380.tif 000004
【図３】
2005141380.tif 000005
【図４】
2005141380.tif 000006
【図５】
2005141380.tif 000007
【図６】
2005141380.tif 000008
【図７】
2005141380.tif 000009
【図８】
2005141380.tif 000010
【図９】
2005141380.tif 000011
【図１０】
2005141380.tif 000012
【図１１】
2005141380.tif 000013
【図１２】
2005141380.tif 000014