(57)【特許請求の範囲】
【請求項１】
ソースコードに含まれる可変個の引数を有する対象のテンプレート関数の処理を、前記対象のテンプレート関数の可変個の引数をまとめる演算子に基づき定義されたいずれかの仮引数に対応する前記対象のテンプレート関数の呼び出し元の実引数列に含まれる実引数の数分複製し、
複製した前記数分の処理の各処理内における前記対象のテンプレート関数の仮引数のうちの前記いずれかの仮引数以外の他の仮引数を、前記実引数列に含まれる各実引数を受け入れるために作成した各作成仮引数に置換し、
前記各処理内における前記他の仮引数が前記対象のテンプレート関数とは異なる他の関数の実引数である場合、前記他の仮引数の型に合致する関数を検索する検索処理または前記ソースコードに含まれるテンプレート関数に基づき前記他の仮引数の型に合致する関数を生成する生成処理を実行し、前記他の関数の呼び出しを前記検索処理または前記生成処理で得られた関数の呼び出しに置換し、
前記対象のテンプレート関数の処理内の再帰呼び出し部分に、置換した前記数分の処理のうちの前記実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入し、前記各処理内の再帰呼び出し部分に、前記各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理を挿入する、
制御部を有することを特徴とする情報処理装置。
【請求項２】
前記ソースコードは、仮引数がなく前記対象のテンプレート関数と同一名称の関数を含み、
前記制御部は、
置換した前記数分の処理のうちの前記実引数列の末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分に、前記同一名称の関数の処理を挿入する、
ことを特徴とする請求項１に記載の情報処理装置。
【請求項３】
前記制御部は、
前記各処理内における前記他の仮引数を前記各作成仮引数に置換するとともに、前記各処理内における前記いずれかの仮引数と前記演算子とが結合した文字列を、前記各作成仮引数に受け入れられる実引数より後ろ全ての実引数のそれぞれを受け入れる作成仮引数に置換する、
ことを特徴とする請求項１または２に記載の情報処理装置。
【請求項４】
前記ソースコードは、仮引数がなく前記対象のテンプレート関数と同一名称の第１の関数と、仮引数が１つであり前記対象のテンプレート関数と同一名称の第２の関数とを含み、
前記制御部は、
置換した前記数分の処理のうちの前記実引数列の末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分に、前記第１の関数または前記第２の関数のうちの当該再帰呼び出し部分の実引数に応じた関数の処理を挿入する、
ことを特徴とする請求項３に記載の情報処理装置。
【請求項５】
コンピュータが、
ソースコードに含まれる可変個の引数を有する対象のテンプレート関数の処理を、前記対象のテンプレート関数の可変個の引数をまとめる演算子に基づき定義されたいずれかの仮引数に対応する前記対象のテンプレート関数の呼び出し元の実引数列に含まれる実引数の数分複製し、
複製した前記数分の処理の各処理内における前記対象のテンプレート関数の仮引数のうちの前記いずれかの仮引数以外の他の仮引数を、前記実引数列に含まれる各実引数を受け入れるために作成した各作成仮引数に置換し、
前記各処理内における前記他の仮引数が前記対象のテンプレート関数とは異なる他の関数の実引数である場合、前記他の仮引数の型に合致する関数を検索する検索処理または前記ソースコードに含まれるテンプレート関数に基づき前記他の仮引数の型に合致する関数を生成する生成処理を実行し、前記他の関数の呼び出しを前記検索処理または前記生成処理で得られた関数の呼び出しに置換し、
前記対象のテンプレート関数の処理内の再帰呼び出し部分に、置換した前記数分の処理のうちの前記実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入し、前記各処理内の再帰呼び出し部分に、前記各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理を挿入する、
処理を実行することを特徴とするコンパイル方法。
【請求項６】
コンピュータに、
ソースコードに含まれる可変個の引数を有する対象のテンプレート関数の処理を、前記対象のテンプレート関数の可変個の引数をまとめる演算子に基づき定義されたいずれかの仮引数に対応する前記対象のテンプレート関数の呼び出し元の実引数列に含まれる実引数の数分複製し、
複製した前記数分の処理の各処理内における前記対象のテンプレート関数の仮引数のうちの前記いずれかの仮引数以外の他の仮引数を、前記実引数列に含まれる各実引数を受け入れるために作成した各作成仮引数に置換し、
前記各処理内における前記他の仮引数が前記対象のテンプレート関数とは異なる他の関数の実引数である場合、前記他の仮引数の型に合致する関数を検索する検索処理または前記ソースコードに含まれるテンプレート関数に基づき前記他の仮引数の型に合致する関数を生成する生成処理を実行し、前記他の関数の呼び出しを前記検索処理または前記生成処理で得られた関数の呼び出しに置換し、
前記対象のテンプレート関数の処理内の再帰呼び出し部分に、置換した前記数分の処理のうちの前記実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入し、前記各処理内の再帰呼び出し部分に、前記各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理を挿入する、
処理を実行させることを特徴とするコンパイルプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置、コンパイル方法、およびコンパイルプログラムに関する。
【背景技術】
【０００２】
従来、ソースコード内にテンプレートと呼ばれる記載に従ったテンプレート関数を定義することがある。コンパイラは、テンプレート関数の呼び出し元の実引数の型に基づいて仮引数の型を決定し、決定した型を仮引数とする関数を生成する。さらに、可変個引数を有するテンプレート関数を定義することがある。また、関数の読み出し元に、呼び出された関数の処理を挿入することにより、関数の呼び出しにかかるオーバヘッドを削減する、インライン最適化と呼ばれる技術がある。
【０００３】
関連する先行技術として、例えば、コンストラクタ関数の処理を仮想関数ポインタ設定文とそれ以外の文にわけ、仮想関数ポインタ設定文をクラス変数宣言の直後にインライン展開し、それ以外の文を関数の呼び元に展開するものがある。また、関数定義コードとテンプレートパラメタとの依存性を解析し、依存性がない場合には、共通関数を定義し、共通化前の複数の関数定義を削除し、共通化前の関数呼び出しを共通関数への呼び出しに置換する技術がある。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２００２−１４０１９８号公報
【特許文献２】特開２００５−１４１３８０号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
しかしながら、従来技術によれば、可変個引数を有するテンプレート関数をコンパイルする際に、不要な関数が生成されることがある。具体的には、可変個引数を有するテンプレート関数から生成された関数の処理をインライン最適化により呼び出し元に挿入した場合、生成された関数は他から呼び出されることがなく不要となるにも関わらず残ってしまうことがある。そして、不要な関数が多くなる分、コンパイラが使用するメモリ量が増大したり、コンパイルにかかる時間が増大したりすることになる。
【０００６】
１つの側面では、本発明は、可変個引数を有するテンプレート関数のコンパイルの際における不要な関数の生成を抑制することができる情報処理装置、コンパイル方法、およびコンパイルプログラムを提供することを目的とする。
【課題を解決するための手段】
【０００７】
本発明の一側面によれば、ソースコードに含まれる可変個の引数を有する対象のテンプレート関数の処理を、対象のテンプレート関数の可変個の引数をまとめる演算子に基づき定義されたいずれかの仮引数に対応する対象のテンプレート関数の呼び出し元の実引数列に含まれる実引数の数分複製し、複製した数分の処理の各処理内における対象のテンプレート関数の仮引数のうちのいずれかの仮引数以外の他の仮引数を、実引数列に含まれる各実引数を受け入れるために作成した各作成仮引数に置換し、各処理内における他の仮引数が対象のテンプレート関数とは異なる他の関数の実引数である場合、他の仮引数の型に合致する関数を検索する検索処理またはソースコードに含まれるテンプレート関数に基づき他の仮引数の型に合致する関数を生成する生成処理を実行し、他の関数の呼び出しを検索処理または生成処理で得られた関数の呼び出しに置換し、対象のテンプレート関数の処理内の再帰呼び出し部分に、置換した数分の処理のうちの実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入し、各処理内の再帰呼び出し部分に、各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理を挿入する情報処理装置、コンパイル方法、およびコンパイルプログラムが提案される。
【発明の効果】
【０００８】
本発明の一態様によれば、可変個引数を有するテンプレート関数のコンパイルの際における不要な関数の生成を抑制することができるという効果を奏する。
【図面の簡単な説明】
【０００９】
【図１】図１は、本実施の形態にかかる情報処理装置１０１の動作例を示す説明図である。
【図２】図２は、テンプレート関数のインスタンシェートの一例を示す説明図である。
【図３】図３は、情報処理装置１０１のハードウェア構成例を示す説明図である。
【図４】図４は、情報処理装置１０１の機能構成例を示す説明図である。
【図５】図５は、ソースコードｓｒｃの一例を示す説明図である。
【図６】図６は、ソースコードｓｒｃのインスタンシェートの結果の一例を示す説明図である。
【図７】図７は、ソースコードｓｒｃの中間言語１情報４２１の一例を示す説明図である。
【図８】図８は、関数パラメタパック展開の過程を示す説明図（その１）である。
【図９】図９は、関数パラメタパック展開の過程を示す説明図（その２）である。
【図１０】図１０は、関数パラメタパック展開の過程を示す説明図（その３）である。
【図１１】図１１は、関数パラメタパック展開の過程を示す説明図（その４）である。
【図１２】図１２は、関数パラメタパック展開後の中間言語１情報４２２の一例を示す説明図である。
【図１３】図１３は、関数パラメタパック展開後のソースイメージの一例を示す説明図である。
【図１４】図１４は、コンパイル処理手順の一例を示すフローチャートである。
【図１５】図１５は、関数パラメタパック展開処理手順の一例を示すフローチャート（その１）である。
【図１６】図１６は、関数パラメタパック展開処理手順の一例を示すフローチャート（その２）である。
【発明を実施するための形態】
【００１０】
以下に図面を参照して、開示の情報処理装置、コンパイル方法、およびコンパイルプログラムの実施の形態を詳細に説明する。
【００１１】
図１は、本実施の形態にかかる情報処理装置１０１の動作例を示す説明図である。図１に示す情報処理装置１０１は、コンパイルを行うコンピュータである。例えば、情報処理装置１０１は、利用者が用意したソースコードをコンパイルして、実行可能なプログラムを作成する。以下、実行可能なプログラムを、「オブジェクトプログラム」と称する。ここで、作成したオブジェクトプログラムは、情報処理装置１０１をターゲットとするものでもよいし、他のコンピュータをターゲットとするものでもよい。また、情報処理装置１０１は、例えば、ハイ・パフォーマンス・コンピューティング（ＨＰＣ：Ｈｉｇｈ  Ｐｅｒｆｏｒｍａｎｃｅ  Ｃｏｍｐｕｔｉｎｇ）分野で使用されるコンピュータである。
【００１２】
利用者が用意したソースコードは、プログラム言語に従って記述される。プログラム言語としては、Ｃ＋＋がある。Ｃ＋＋では、テンプレートと呼ばれる記載に従ったテンプレート関数を定義することができる。Ｃ＋＋の規格に従ったコンパイラは、テンプレート関数の呼び出し元の実引数の型に基づいて仮引数の型を決定し、決定した型を仮引数とする関数を生成するという、テンプレート関数のインスタンシェートと呼ばれる処理を実行する。テンプレート関数のインスタンシェートの一例については、図２で説明する。ここで、仮引数とは、関数で定義される変数のうち、実行時に呼び出し元から渡される値を受け入れる変数である。これに対し、実引数とは、関数を呼び出す際に、関数に渡す値である。仮引数と実引数とを総称して、「引数」と呼ばれる。
【００１３】
さらに、Ｃ＋＋１１（ＩＳＯ（Ｉｎｔｅｒｎａｔｉｏｎａｌ  Ｏｒｇａｎｉｚａｔｉｏｎ  ｆｏｒ  Ｓｔａｎｄａｒｄｉｚａｔｉｏｎ）／ＩＥＣ（Ｉｎｔｅｒｎａｔｉｏｎａｌ  Ｅｌｅｃｔｒｏｔｅｃｈｎｉｃａｌ  Ｃｏｍｍｉｓｓｉｏｎ）  １４８８２：２０１１）から採用された可変個引数テンプレートには、引数の可変個部分を一括して処理するためのパラメタパックが導入されている。テンプレート引数には、型情報リストを一括して処理するテンプレートパラメタパックがある。また、テンプレート関数の引数には、テンプレートパラメタパックの型情報が適用された引数リストを一括して処理するための関数パラメタパックがある。具体的には、可変個の引数をまとめる演算子「．．．」に基づき定義された仮引数は、その仮引数の関数の呼び出し元の実引数列が渡される。「．．．」は、ｐａｃｋ演算子やｕｎｐａｃｋ演算子と呼ばれる。例えば、下記のように、テンプレート関数が定義されているとする。
【００１４】
ｔｅｍｐｌａｔｅ  ＜ｃｌａｓｓ  ＴＨ，ｃｌａｓｓ．．．  Ａｒｇｓ＞
ｖｏｉｄ  ｆｕｎｃ（ＴＨ  ｈｅａｄ，Ａｒｇｓ．．．  ａｒｇｓ）
｛
…
｝
【００１５】
上述の定義では、仮引数ａｒｇｓは、「Ａｒｇｓ．．．」というｕｎｐａｃｋ演算子「．．．」が付与された型で定義されている。これに対し、例えば、「ｆｕｎｃ（１，２Ｌ，３ｕ）；」という呼び出しがある場合、仮引数ａｒｇｓには、｛２Ｌ，３ｕ｝というように、呼び出し元の実引数がまとめられた実引数列が渡される。また、他の例として「ｆｕｎｃ（１，２Ｌ，３ｕ，４．０Ｆ，５．０）；」という呼び出しがある場合、仮引数ａｒｇｓには、｛２Ｌ，３ｕ，４．０Ｆ，５．０｝というような実引数列が渡される。すなわち、上述の定義では、仮引数ａｒｇｓは、関数ｆｕｎｃ（）の第二引数であるため、呼び出し元の実引数列のうちの二番目以降の実引数列が渡される。このように、呼び出し元の実引数列のうち、テンプレート関数における関数パラメタパックとなる仮引数の位置に応じた実引数を先頭とした実引数列が、関数パラメタパックとなる仮引数に渡されることになる。
【００１６】
また、関数の読み出し元に、呼び出された関数の処理を挿入することにより、関数の呼び出しにかかるオーバヘッドを削減する、インライン最適化と呼ばれる技術がある。
【００１７】
このように、Ｃ＋＋では、クラスやテンプレート等により生産性の向上が図られている。しかしながら、可変個引数を有するテンプレート関数をコンパイルする際に、不要な関数が生成されることがある。具体的には、可変個引数を有するテンプレート関数から生成された関数の処理をインライン最適化により呼び出し元に挿入した場合、生成された関数は他から呼び出されることがなく不要となるにも関わらず残ってしまうことがある。そして、不要な関数が多くなる分、コンパイラが使用するメモリ量が増大したり、コンパイルにかかる時間が増大したりすることになる。
【００１８】
すなわち、インライン最適化を使わないと、再帰呼び出し関数のコードを展開することができないが、インライン最適化を行ったとしても不要関数が残ってしまうと、翻訳性能に悪影響を及ぼすことになる。
【００１９】
そこで、本実施の形態では、可変個の仮引数を持つテンプレート関数のコンパイル時、可変個の仮引数に渡す実引数分、関数の処理を複製した各処理内の仮引数を実引数の受け入れ用の仮引数に置換し、関数の再帰呼び出し部分に順次挿入することについて説明する。
【００２０】
図１を用いて、情報処理装置１０１の動作例について説明する。情報処理装置１０１は、ソースコードｓｒｃを記憶する。ソースコードｓｒｃには、コード１０２として、可変個の引数を有するテンプレート関数ｆｕｎｃ（）と、コード１０３として、関数ｆｕｎｃ（）を呼び出す関数ｍａｉｎ（）とを含む。また、コード１０２には、関数ｆｕｎｃ（）の処理として、コード１０４が含まれる。
【００２１】
本実施の形態では、テンプレート関数ｆｕｎｃ（）が、可変個の引数、すなわち、関数パラメタパックを有するので、関数パラメタパックの展開を行う。ここで、情報処理装置１０１は、各関数について、関数パラメタパックの展開を行う対象となるか判定する。具体的な判定基準については、図７で説明する。図１の例では、情報処理装置１０１は、関数ｆｕｎｃを、パラメタパックの展開を行う対象のテンプレート関数であると判定する。以下、パラメタパックの展開を行う対象のテンプレート関数を、「対象の関数」と呼称する場合がある。
【００２２】
情報処理装置１０１は、図１の（１）で示すように、関数ｆｕｎｃ（）の処理を、関数ｆｕｎｃ（）の関数の「．．．」に基づき定義されたいずれかの仮引数に対応する関数ｆｕｎｃ（）の呼び出し元の実引数列に含まれる実引数の数分複製する。図１の場合、関数パラメタパックとなるいずれかの仮引数は、演算子「．．．」に基づき定義されたａｒｇｓとなる。そして、仮引数ａｒｇｓに対応する実引数列は、コード１０３内で関数ｆｕｎｃ（）を呼び出している「ｆｕｎｃ（１，２Ｌ，３ｕ）」のうちの｛２Ｌ，３ｕ｝となり、その実引数列に含まれる実引数の数は、２つとなる。また、関数パラメタパックに渡される実引数の個数は、下記（１）式で算出することができる。
【００２３】
関数パラメタパックに渡される実引数の個数＝関数呼び出しの実引数の数−関数パラメタパックの位置＋１  …（１）
【００２４】
従って、情報処理装置１０１は、関数ｆｕｎｃ（）の処理となるコード１０４を、２つ分複製する。コード１０４を複製することにより、情報処理装置１０１は、コード１１１、１１２を得る。
【００２５】
次に、情報処理装置１０１は、図１の（２）で示すように、複製した数分の処理の各処理内における関数ｆｕｎｃ（）の仮引数のうちの仮引数ａｒｇｓ以外の他の仮引数を、各作成仮引数に置換する。ここで、関数ｆｕｎｃ（）の仮引数のうちの仮引数ａｒｇｓ以外の他の仮引数は、第一引数であるｈｅａｄとなる。他の仮引数は、１つである場合もあるし、複数である場合もある。また、作成仮引数は、仮引数ａｒｇｓに対応する実引数列｛２Ｌ，３ｕ｝に含まれる各実引数を受け入れるために作成した仮引数である。具体的には、情報処理装置１０１は、情報処理装置１０１のメモリ上に、（１）式で得られた数分の作成仮引数を生成する。このとき、各作成仮引数の名称は、その各作成仮引数が参照される範囲内で他の仮引数、他の作成仮引数、ローカル変数等と区別がつけばどのような名称でもよい。そして、各作成仮引数の型は、対応する各実引数の型と同じとする。また、各作成仮引数は、情報処理装置１０１のメモリ上に作成されるが、各作成仮引数の順番はどのようなものでもよい。以下では、説明を簡略化するため、各作成仮引数の順番は、対応する各実引数の順番と同一であるものとする。
【００２６】
具体的には、情報処理装置１０１は、コード１１１内における「ｈｅａｄ」を、実引数列の一番目の実引数２Ｌを受け入れるために作成した作成仮引数ａｒｇｓ１に置換する。作成仮引数ａｒｇｓ１の型は、実引数２Ｌに対応するｌｏｎｇとなる。さらに、情報処理装置１０１は、コード１１２内における「ｈｅａｄ」を、実引数列の二番目の実引数３ｕを受け入れるために作成した作成仮引数ａｒｇｓ２に置換する。作成仮引数ａｒｇｓ２の型は、実引数３ｕに対応するｕｎｓｉｇｎｅｄ  ｉｎｔとなる。
【００２７】
さらに、情報処理装置１０１は、コード１１１、１１２内の仮引数ａｒｇｓと「．．．」とが結合した文字列「ａｒｇｓ．．．」を、各作成仮引数に受け入れられる実引数より後ろ全ての実引数のそれぞれを受け入れる作成仮引数に置換する。ここで、「ａｒｇｓ．．．」の意味は、ａｒｇｓにまとめられた実引数列を展開することを示す。具体的には、コード１１１では、情報処理装置１０１は、文字列「ａｒｇｓ．．．」を、コード１１１における作成仮引数「ａｒｇｓ１」に受け入れられる実引数２Ｌより後ろ全ての実引数として、３ｕを受け入れる作成仮引数ａｒｇｓ２に置換する。また、コード１１２では、情報処理装置１０１は、コード１１１における作成仮引数「ａｒｇｓ１」に受け入れられる実引数３ｕより後ろの実引数はないので、この場合、文字列「ａｒｇｓ．．．」を空文字列“”に置換する。
【００２８】
ここで、情報処理装置１０１は、複製した各処理内における他の仮引数が関数ｆｕｎｃ（）とは異なる他の関数の実引数である場合、検索処理または生成処理を実行し、他の関数の呼び出しを検索処理または生成処理で得られた関数の呼び出しに置換する。ここで、検索処理は、他の仮引数の型に合致する関数を検索する処理である。また、生成処理は、ソースコードｓｒｃに含まれるテンプレート関数に基づき他の仮引数の型に合致する関数を生成する、テンプレート関数のインスタンシェートである。図１の例では、他の仮引数となるｈｅａｄが、関数ｆｕｎｃ（）とは異なる他の関数の実引数とはなっていないため、情報処理装置１０１は、検索処理または生成処理で得られた関数の呼び出しに置換する処理を行わない。検索処理または生成処理で得られた関数の呼び出しに置換する処理の一例については、図１１で説明する。
【００２９】
そして、情報処理装置１０１は、図１の（３）で示すように、関数ｆｕｎｃ（）の処理内の再帰呼び出し部分に、置換した数分の処理のうちの実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入する。さらに、情報処理装置１０１は、各処理内の再帰呼び出し部分に、各処理の次の処理を挿入する。ここで、各処理の次の処理を、実引数の順番を用いて説明すると、次の処理とは、各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理となる。
【００３０】
具体的には、関数ｆｕｎｃ（）の再帰呼び出し部分に、コード１２１を挿入する。さらに、情報処理装置１０１は、コード１２１の再帰呼び出し部分に、コード１２１の作成仮引数ａｒｇｓ１に受け入れられる実引数２Ｌの次の位置の実引数３ｕを受け入れる作成仮引数ａｒｇｓ２に置換したコード１２２を挿入する。
【００３１】
以上により、情報処理装置１０１は、不要となる関数の作成を抑制することができる。そして、不要となる関数の作成が抑制されることにより、最適化の入力となるコードを削減し、最適化の処理時間や必要なメモリ量を削減することができる。次に、テンプレート関数のインスタンシェートの一例を、図２を用いて説明する。
【００３２】
図２は、テンプレート関数のインスタンシェートの一例を示す説明図である。テンプレート関数のインスタンシェートによる実体生成では、実引数の情報に基づいて仮引数の情報を生成する。例えば、図２で示すソースコード２０１は、テンプレート関数ｆｏｏ（）を含むプログラムである。テンプレート関数ｆｏｏ（）は、仮引数として、テンプレート引数ｐａｒａｍを含む。
【００３３】
そして、コンパイラは、テンプレート関数ｆｏｏ（）の呼び出しを検出した場合、テンプレート関数ｆｏｏ（）のインスタンシェートを行う。この際、コンパイラは、実引数１０から仮引数の型ｉｎｔを決定し、コード２０２として「ｖｏｉｄ  ｆｏｏ（ｉｎｔ  ｐａｒａｍ）｛｝」というように、実引数に対応した関数ｆｏｏ（）を生成する。このように、本実施の形態では、型情報を用いたテンプレート関数のインスタンシェートを対象とする。次に、情報処理装置１０１のハードウェア構成図について、図３を用いて説明する。
【００３４】
（情報処理装置１０１のハードウェア構成図）
図３は、情報処理装置１０１のハードウェア構成例を示す説明図である。図３において、情報処理装置１０１は、ＣＰＵ（Ｃｅｎｔｒａｌ  Ｐｒｏｃｅｓｓｉｎｇ  Ｕｎｉｔ）３０１と、ＲＯＭ（Ｒｅａｄ−Ｏｎｌｙ  Ｍｅｍｏｒｙ）３０２と、ＲＡＭ（Ｒａｎｄｏｍ  Ａｃｃｅｓｓ  Ｍｅｍｏｒｙ）３０３と、を含む。また、情報処理装置１０１は、ディスクドライブ３０４およびディスク３０５と、通信インターフェース３０６と、を含む。また、ＣＰＵ３０１〜ディスクドライブ３０４、通信インターフェース３０６はバス３０７によってそれぞれ接続される。
【００３５】
ＣＰＵ３０１は、情報処理装置１０１の全体の制御を司る演算処理装置である。また、情報処理装置１０１は、複数のＣＰＵを有してもよい。ＲＯＭ３０２は、ブートプログラムなどのプログラムを記憶する不揮発性メモリである。ＲＡＭ３０３は、ＣＰＵ３０１のワークエリアとして使用される揮発性メモリである。
【００３６】
ディスクドライブ３０４は、ＣＰＵ３０１の制御に従ってディスク３０５に対するデータのリードおよびライトを制御する制御装置である。ディスクドライブ３０４には、例えばディスクドライブ、光ディスクドライブ、ソリッドステートドライブなどを採用することができる。ディスク３０５は、ディスクドライブ３０４の制御で書き込まれたデータを記憶する不揮発性メモリである。例えばディスクドライブ３０４が磁気ディスクドライブである場合、ディスク３０５には、磁気ディスクを採用することができる。また、ディスクドライブ３０４が光ディスクドライブである場合、ディスク３０５には、光ディスクを採用することができる。また、ディスクドライブ３０４がソリッドステートドライブである場合、ディスク３０５には、半導体素子によって形成された半導体メモリ、いわゆる半導体ディスクを採用することができる。
【００３７】
通信インターフェース３０６は、ネットワークと内部のインターフェースを司り、他の装置からのデータの入出力を制御する制御装置である。具体的に、通信インターフェース３０６は、通信回線を通じてネットワークを介して情報処理装置１０１を利用する利用者端末等の他の装置に接続される。通信インターフェース３０６には、例えば、モデムやＬＡＮ（Ｌｏｃａｌ  Ａｒｅａ  Ｎｅｔｗｏｒｋ）アダプタなどを採用することができる。
【００３８】
また、情報処理装置１０１の管理者が、情報処理装置１０１を直接操作する場合、情報処理装置１０１は、ディスプレイ、キーボード、マウスといったハードウェアを有してもよい。
【００３９】
（情報処理装置１０１の機能構成図）
図４は、情報処理装置１０１の機能構成例を示す説明図である。情報処理装置１０１は、制御部４００を有する。制御部４００は、構文・意味解析部４０１と、関数パラメタパック展開部４０２と、中間言語変換部４０３と、最適化・コード生成部４０４と、を含む。制御部４００は、記憶装置に記憶されたプログラムをＣＰＵ３０１が実行することにより、各部の機能を実現する。記憶装置とは、具体的には、例えば、図３に示したＲＯＭ３０２、ＲＡＭ３０３、ディスク３０５などである。また、各部の処理結果は、ＲＡＭ３０３や、ＣＰＵ３０１のレジスタ、ＣＰＵ３０１のキャッシュメモリ等に格納される。
【００４０】
ここで、コンパイルの工程には、字句解析、構文解析、意味解析を行うフロントエンドと、最適化処理やコード生成を行うバックエンドとがある。フロントエンドは、プログラム言語の仕様に依存する処理であり、ターゲットのアーキテクチャには依存しない。一方、バックエンドは、プログラム言語の仕様には依存せず、ターゲットのアーキテクチャに依存する処理である。構文・意味解析部４０１〜中間言語変換部４０３は、フロントエンドに含まれる。また、最適化・コード生成部４０４は、バックエンドに含まれる。
【００４１】
また、情報処理装置１０１は、ソースコードｓｒｃ、中間言語１情報４２１、関数パラメタパック展開後の中間言語１情報４２２、中間言語２情報４２３、オブジェクトプログラムｏｂｊにアクセス可能である。ソースコードｓｒｃ、中間言語１情報４２１〜中間言語２情報４２３は、ＲＡＭ３０３、ディスク３０５といった記憶装置に格納されている。
【００４２】
構文・意味解析部４０１は、ソースコードｓｒｃを読み込んで、構文解析、意味解析を行い、中間言語１情報４２１を生成する。ソースコードｓｒｃの一例を、図５で示す。また、中間言語１情報４２１の一例を、図７で示す。
【００４３】
関数パラメタパック展開部４０２は、中間言語１情報４２１から、関数パラメタパックを展開し、関数パラメタパック展開後の中間言語１情報４２２を生成する。関数パラメタパック展開後の中間言語１情報４２２の一例を、図１２で示す。また、関数パラメタパック展開部４０２は、複製部４１１と、置換部４１２と、挿入部４１３とを含む。図４の説明では、関数パラメタパックを有する対象のテンプレート関数を、対象の関数と呼ぶ。
【００４４】
複製部４１１は、ソースコードｓｒｃに含まれる対象の関数の処理を、ｕｎｐａｃｋ演算子「．．．」に基づき定義されたいずれかの仮引数に対応する対象の関数の呼び出し元の実引数列に含まれる実引数の数分複製する。
【００４５】
置換部４１２は、複製部４１１が複製した数分の処理の各処理内における対象の関数の仮引数のうちのいずれかの仮引数以外の他の仮引数を、実引数列に含まれる各実引数を受け入れるために作成した各作成仮引数に置換する。
【００４６】
また、置換部４１２は、各処理内における他の仮引数が対象の関数とは異なる他の関数の実引数である場合、検索処理または生成処理を実行し、他の関数の呼び出しを検索処理または生成処理で得られた関数の呼び出しに置換する。
【００４７】
また、置換部４１２は、各処理内における他の仮引数を各作成仮引数に置換するとともに、各処理内におけるいずれかの仮引数を、各作成仮引数に受け入れられる実引数より後ろ全ての実引数のそれぞれを受け入れる作成仮引数に置換する。
【００４８】
挿入部４１３は、対象の関数の処理内の再帰呼び出し部分に、置換した数分の処理のうちの実引数列の先頭の実引数を受け入れる作成仮引数に置換した処理を挿入する。さらに挿入部４１３は、各処理内の再帰呼び出し部分に、各処理の作成仮引数に受け入れられる実引数の次の位置の実引数を受け入れる作成仮引数に置換した処理を挿入する。
【００４９】
ここで、ソースコードｓｒｃには、仮引数がなく対象のテンプレート関数と同一名称の関数が含まれる。そして、挿入部４１３は、置換部４１２が置換した数分の処理のうちの実引数列の末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分に、前述の同一名称の関数の処理を挿入する。
【００５０】
また、ソースコードには、仮引数がなく対象のテンプレート関数と同一名称の第１の関数と、仮引数が１つであり対象のテンプレート関数と同一名称の第２の関数とが含まれてもよい。そして、挿入部４１３は、置換した数分の処理のうちの実引数列の末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分に、第１の関数または第２の関数のうちの当該再帰呼び出し部分の実引数に応じた関数の処理を挿入する。例えば、挿入部４１３は、末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分において、実引数が０個であれば第１の関数の処理を挿入し、実引数が１個であれば第２の関数の処理を挿入する。
【００５１】
中間言語変換部４０３は、関数パラメタパック展開後の中間言語１情報４２２から、中間言語２情報４２３を生成する。最適化・コード生成部４０４は、中間言語２情報４２３からオブジェクトプログラムｏｂｊを生成する。
【００５２】
図５は、ソースコードｓｒｃの一例を示す説明図である。図５では、関数パラメタパックを使用したソースコードｓｒｃを示す。ソースコードｓｒｃ内のコード５０１は、引数なし復帰値なしの関数ｆｕｎｃ（）を記載したコードである。また、ソースコードｓｒｃ内のコード５０２は、テンプレート関数ｆｕｎｃ（）を記載したコードである。また、ソースコードｓｒｃ内のコード５０３は、引数なし復帰値ｉｎｔ型の関数ｍａｉｎ（）を記載したコードである。
【００５３】
さらに、コード５０２の１行目には、テンプレート引数が定義されており、具体的には、テンプレートパラメタパック「Ａｒｇｓ」が定義されている。また、コード５０２の２行目には、関数パラメタパックが適用された関数ｆｕｎｃ（）が定義されており、さらに、テンプレートパラメタパックの型情報「Ａｒｇｓ」が適用された仮引数「ａｒｇｓ」が定義されている。ここで、仮引数「ａｒｇｓ」等の前に付与された「．．．」は、ｐａｃｋ演算子と呼ばれる。また、コード５０２の５行目には、コード５１１として、関数パラメタパックが適用された関数ｆｕｎｃ（）の参照が定義されている。このように、コード５０２は、再帰呼び出しがある。
【００５４】
コード５０３の３行目には、コード５１２として、関数パラメタパックが適用された関数ｆｕｎｃ（）への引数渡しが定義されている。次に、ソースコードｓｒｃのインスタンシェートの結果を、図６を用いて説明する。
【００５５】
図６は、ソースコードｓｒｃのインスタンシェートの結果の一例を示す説明図である。図２で示したテンプレート関数のインスタンシェートと同様に、関数パラメタパックを有するテンプレート関数の場合にも、同様に仮引数の情報が生成される。図６のインスタンシェート結果６００が示すように、ソースコードｓｒｃのインスタンシェートの結果、関数６０１〜６０５が生成される。なお、図６に示すインスタンシェート結果６００は、処理系が生成する中間言語をソースイメージで表現したものである。
【００５６】
関数６０１は、コード５１１、すなわち、「ｆｕｎｃ（１，２Ｌ，３ｕ，４．０Ｆ，５．０）；」の呼び出しから生成された関数ｆｕｎｃ（）である。関数６０１は、コード６１１として、ｆｕｎｃ（）の再帰呼び出しがある。
【００５７】
関数６０２は、コード６１１、すなわち、「ｆｕｎｃ（ａｒｇｓ１，ａｒｇｓ２，ａｒｇｓ３，ａｒｇｓ４）；」の呼び出しから生成された関数ｆｕｎｃ（）である。関数６０２は、コード６１２として、ｆｕｎｃ（）の再帰呼び出しがある。
【００５８】
関数６０３は、コード６１２、すなわち、「ｆｕｎｃ（ａｒｇｓ１，ａｒｇｓ２，ａｒｇｓ３）；」の呼び出しから生成された関数ｆｕｎｃ（）である。関数６０３は、コード６１３として、ｆｕｎｃ（）の再帰呼び出しがある。
【００５９】
関数６０４は、コード６１３、すなわち、「ｆｕｎｃ（ａｒｇｓ１，ａｒｇｓ２）；」の呼び出しから生成された関数である。関数ｆｕｎｃ（）６０４は、コード６１４として、ｆｕｎｃ（）の再帰呼び出しがある。
【００６０】
関数６０５は、コード６１４、すなわち、「ｆｕｎｃ（ａｒｇｓ１）；」の呼び出しから生成された関数ｆｕｎｃ（）である。関数６０５は、コード６１５として、ｆｕｎｃ（）の再帰呼び出しがある。
【００６１】
関数６０１〜６０５のうち、関数６０２〜６０５は、コード５１１に記載された関数パラメタパックの参照から間接的に生成されるものであるため、関数６０２〜６０５の呼び出し箇所は、翻訳単位に閉じている。
【００６２】
このように、ソースコードｓｒｃのインスタンシェートの結果、関数６０１〜６０５が生成されるが、コード５１１から直接呼び出されるのは関数６０１であり、関数６０２〜６０５は、関数６０１から呼び出される。ここで、関数６０２〜６０５の処理を、関数６０１内に展開することができれば、関数６０２〜６０５を削除することが可能である。図７〜図１３を用いて、関数６０２〜６０５を生成しないようにする方法について説明する。まず、パラメタパック展開前となる中間言語１情報４２１の一例を、図７を用いて説明する。
【００６３】
図７は、ソースコードｓｒｃの中間言語１情報４２１の一例を示す説明図である。図７に示す中間言語１情報４２１は、テンプレート関数ｆｕｎｃ情報７０１と、関数ｍａｉｎ情報７０２とを含む。
【００６４】
テンプレート関数ｆｕｎｃ情報７０１は、仮引数情報７１１と、テンプレート関数ｆｕｎｃ内のｆｕｎｃの呼び出し式情報７１２とを含む。仮引数情報７１１は、第一引数がｈｅａｄであり、第二引数がａｒｇｓであることを示す。また、仮引数情報７１１は、仮引数ｈｅａｄのパラメタパックがＦＡＬＳＥであり、型がテンプレートパラメタとなることを示す。同様に、仮引数情報７１１は、仮引数ａｒｇｓのパラメタパックがＴＲＵＥであり、型がテンプレートパラメタとなることを示す。
【００６５】
テンプレート関数ｆｕｎｃ内のｆｕｎｃの呼び出し式情報７１２は、関数情報ｆｕｎｃの呼び出しに用いる情報として、実引数情報７２１を含む。実引数情報７２１は、第一引数として、型が、第二引数のテンプレートパラメタであり、パラメタパックの展開がＴＲＵＥとなることを示す。
【００６６】
関数ｍａｉｎ情報７０２は、ｍａｉｎ関数内のｆｕｎｃの呼び出し式情報７３１を含む。ｍａｉｎ関数内のｆｕｎｃの呼び出し式情報７３１は、関数情報ｆｕｎｃの呼び出しに用いる情報として、実引数情報７４１を含む。実引数情報７４１は、第一引数の型がｉｎｔ型であり、第一引数の値が１であることを示す。また、実引数情報７４１は、第二引数の型がｌｏｎｇ型であり、第二引数の値が２Ｌであることを示す。また、実引数情報７４１は、第三引数の型がｕｎｓｉｇｎｅｄ  ｉｎｔ型であり、第三引数の値が３ｕであることを示す。また、実引数情報７４１は、第四引数の型がｆｌｏａｔ型であり、第四引数の値が４．０Ｆであることを示す。また、実引数情報７４１は、第五引数の型がｄｏｕｂｌｅ型であり、第五引数の値が５．０であることを示す。
【００６７】
次に、テンプレート関数ｆｕｎｃ（）について、関数パラメタパックを利用した再帰呼び出し関数の展開方法について、図８〜図１１を用いて説明する。まず、情報処理装置１０１は、パラメタパックの展開を行うか否かの判定のため、以下の４つの条件を全て満たすかを判断する。この条件の具体的なフローチャートは、図１５で示す。
【００６８】
１つ目の条件は、パラメタパックの展開を行うか否かの判定対象となる関数が、テンプレート関数であることである。２つ目の条件は、前述の判定対象の関数内に、再帰呼び出しがあることである。３つ目の条件は、その再帰呼び出しの実引数が、関数パラメタパックの仮引数であることである。４つ目の条件は、その再帰呼び出しの実引数以外で、関数パラメタパックの仮引数が参照されていないことである。４つ目の条件が満たされない場合、インライン展開が複雑となるため、本実施の形態では、インライン最適化を行わないものとする。
【００６９】
コード５０２に含まれるテンプレート関数ｆｕｎｃ（）は、上述した４つの条件全てを満たすため、関数パラメタパックの展開を行う対象のテンプレート関数となる。次に、図８〜図１１を用いて、関数パラメタパック展開の過程を示す。
【００７０】
図８は、関数パラメタパック展開の過程を示す説明図（その１）である。まず、情報処理装置１０１は、テンプレート関数ｆｕｎｃ（）の本体の中間言語情報、すなわち、テンプレート関数ｆｕｎｃ情報７０１を複製する。次に、情報処理装置１０１は、テンプレート関数ｆｕｎｃ（）の関数パラメタパックに渡される実引数の個数を算出する。具体的には、情報処理装置１０１は、（１）式に従って、関数パラメタパックに渡される実引数の個数を算出する。（１）式における関数パラメタパックの位置は、コード５０２の例では、「ａｒｇｓ」の位置は左から２番目であるため、２となる。従って、コード５０２では、関数パラメタパックに渡される実引数の個数は、５−２＋１＝４となる。また、関数パラメタパックに渡される実引数列は、｛２Ｌ，３ｕ，４．０Ｆ，５．０｝となる。
【００７１】
そして、情報処理装置１０１は、算出した実引数の個数分の仮引数の中間言語情報を作成する。ここで、作成の元となる情報は、関数パラメタパックの仮引数の中間言語情報である。図８の例では、情報処理装置１０１は、仮引数情報７１１の第二引数の中間言語情報に基づいて、４つ分の仮引数の中間言語情報８０１〜８０４を作成する。ここで、中間言語情報８０１〜８０４の４つの仮引数は、関数パラメタパックに渡される実引数を受け入れる引数であり、図１で前述した作成仮引数となる。情報処理装置１０１は、作成した中間言語情報８０１〜８０４を、複製したテンプレート関数ｆｕｎｃ情報７０１に登録する。
【００７２】
また、中間言語情報８０１〜８０４の作成仮引数の型は、関数呼び出しの実引数の型と同じとする。具体的には、中間言語情報８０１の作成仮引数の型は、関数呼び出しの実引数のうち、関数パラメタパックの仮引数の位置の実引数の型であるｌｏｎｇとなる。また、中間言語情報８０２の型は、関数パラメタパックの仮引数の位置を基準として２番目に位置する実引数の型であるｕｎｓｉｇｎｅｄ  ｉｎｔとなる。また、中間言語情報８０３の型は、関数パラメタパックの仮引数の位置を基準として３番目に位置する実引数の型であるｆｌｏａｔとなる。また、中間言語情報８０４の型は、関数パラメタパックの仮引数の位置を基準として４番目に位置する実引数の型であるｄｏｕｂｌｅとなる。また、中間言語情報８０１〜８０４の作成仮引数の名称は、図１で説明したように、その作成仮引数が参照される範囲内で他の仮引数や変数と区別がつけばどのような名称でもよい。図８の例では、中間言語情報８０１〜８０４の作成仮引数の名称は、それぞれ、関数パラメタパックの仮引数「ａｒｇｓ」に番号を付与したａｒｇｓ１〜４とする。
【００７３】
図９は、関数パラメタパック展開の過程を示す説明図（その２）である。次に、情報処理装置１０１は、算出した実引数の個数分の対象の関数本体の処理、具体的には文、式といったコードを複製する。図９の例では、情報処理装置１０１は、テンプレート関数ｆｕｎｃ（）の本体の処理であるコード９００を、４つ分複製し、複製コード９０１〜９０４を得る。
【００７４】
そして、情報処理装置１０１は、複製コード９０１〜９０４のそれぞれについて、複製コード内で参照している関数パラメタパックの仮引数ではない他の仮引数を、作成した中間言語情報の作成仮引数に置換する。さらに、情報処理装置１０１は、複製コード９０１〜９０４のそれぞれについて、複製コード内で参照している関数パラメタパックの仮引数を、置換した作成仮引数に受け入れられる実引数より後ろ全ての実引数のそれぞれを受け入れる作成仮引数に置換する。
【００７５】
ここで、関数パラメタパックの仮引数ではない他の仮引数は、図９の例では、ｈｅａｄとなる。例えば、複製コード９０１の場合、情報処理装置１０１は、複製コード９０１内のｈｅａｄを、中間言語情報８０１の作成仮引数ａｒｇｓ１に置換する。さらに、情報処理装置１０１は、複製コード９０１内のａｒｇｓ．．．を、仮引数ａｒｇｓ１に受け入れられる実引数より後ろの全ての実引数を受け入れる各作成仮引数、すなわちａｒｇｓ２、ａｒｇｓ３、ａｒｇｓ４に置換し、置換後の複製コード９１１を得る。
【００７６】
同様に、情報処理装置１０１は、複製コード９０２内のｈｅａｄを、中間言語情報８０２の仮引数ａｒｇｓ２に置換し、複製コード９０２内のａｒｇｓ．．．を、作成仮引数ａｒｇｓ３、ａｒｇｓ４に置換する。置換後、情報処理装置１０１は、置換後の複製コード９１２を得る。同様に、情報処理装置１０１は、複製コード９０３内のｈｅａｄを、中間言語情報８０３の仮引数ａｒｇｓ３に置換し、複製コード９０３内のａｒｇｓ．．．を、作成仮引数ａｒｇｓ４に置換する。置換後、情報処理装置１０１は、置換後の複製コード９１３を得る。
【００７７】
また、複製コード９０４の置換において、ａｒｇｓ４に受け入れられる実引数より後ろの実引数はない。従って、情報処理装置１０１は、複製コード９０４内のｈｅａｄを、中間言語情報８０４の仮引数ａｒｇｓ４に置換し、複製コード９０４内のａｒｇｓ．．．を、引数なしとして“”に置換する。
【００７８】
ここで、関数パラメタパックの仮引数ではない仮引数が、対象の関数とは異なる他の関数の実引数となる場合もある。この場合の処理については、図１１で説明する。
【００７９】
図１０は、関数パラメタパック展開の過程を示す説明図（その３）である。次に、情報処理装置１０１は、対象の関数本体にある再帰呼び出し部分に、置換した複製コードを順次挿入する。ここで、挿入する複製コードは、図９で、仮引数を置換した複製コードとなることもあるし、図１１で説明する、関数を置換した複製コードとなることもある。例えば、図１０の例では、情報処理装置１０１は、コード９００の再帰呼び出し部分となる「ｆｕｎｃ（ａｒｇｓ．．．）；」に、複製コード９１１を挿入する。そして、情報処理装置１０１は、複製コード９１１の再帰呼び出し部分となる「ｆｕｎｃ（ａｒｇｓ２，ａｒｇｓ３，ａｒｇｓ４）；」に、複製コード９１２を挿入する。このように、情報処理装置１０１は、対象の関数本体にある再帰呼び出し部分に、置換した複製コードを順次挿入する。図１０の上部に示す結果が、コード９００の再帰呼び出し部分に、置換後の複製コード９１１〜９１４を順次挿入した結果となる。
【００８０】
ただし、対象の関数が復帰値を返す場合、情報処理装置１０１は、複製コード内にある再帰呼び出しの結果の値を、元の再帰呼び出しの結果の値として利用できるように代入処理を追加する。例えば、対象の関数の最後が、「ｒｅｔｕｒｎ  ａ＋ｂ；」となっているとする。この場合、情報処理装置１０１は、複製コード内の「ｒｅｔｕｒｎ」を削除するとともに、ａ＋ｂの結果を一時変数に記憶するコードを生成し、さらに、元の再帰呼び出しの結果が格納される変数に、一時変数の値を代入する代入処理を追加する。
【００８１】
対象の関数本体にある再帰呼び出し部分に、置換した複製コードを順次挿入した後、最後の複製コード内の再帰呼び出しについては、予め用意してある引数なしの関数本体の処理で置換する。図１０の例では、複製コード９１４の「ｆｕｎｃ（）；」に、コード５０１の処理で置換する。また、復帰値がある場合には、情報処理装置１０１は、前述の処理と同様に、代入処理を行う。図１０下部に示す結果が、複製コード９１４の再帰呼び出し部分に、コード５０１の処理を挿入した結果となる。
【００８２】
また、図１０の例では、最後の複製コード内の再帰呼び出しが実引数なしとなっているが、実引数ありとなる場合もある。例えば、テンプレート関数の中間言語情報に、３つの仮引数の情報があり、１つ目と２つ目との仮引数のパラメタパックがＦＡＬＳＥとなり、３つ目の仮引数のパラメタパックがＴＲＵＥとなる場合である。この場合、関数呼び出しの実引数の数が奇数個である場合、最後の複製コード内の再帰呼び出しの実引数が１個となる場合と、実引数が０個となる場合とがありえる。従って、プログラムの作成者は、予め、仮引数がない第１の関数と仮引数が１個の第２の関数とを用意しておく。なお、関数呼び出しの実引数の数が偶数個である場合、最後の複製コード内の再帰呼び出しの実引数は０となる。
【００８３】
そして、情報処理装置１０１は、最後の複製コード内の再帰呼び出しの実引数が０個であれば、第１の関数の処理を挿入し、実引数が１個であれば、第２の関数の処理を挿入する。
【００８４】
次に、関数パラメタパックの仮引数ではない仮引数が、対象の関数とは異なる他の関数の実引数となる場合について、図１１を用いて説明する。
【００８５】
図１１は、関数パラメタパック展開の過程を示す説明図（その４）である。図１１で示すソースコードｓｒｃ１の処理では、コード１１０１に示すように、ソースコードｓｒｃの処理に加え、対象の関数とは異なる他の関数として、ｆｕｎｃ１（）関数の呼び出しと、ｆｕｎｃ２（）関数の呼び出しとを含むものである。複製コード１１１１、１１１２は、コード１１０１を複製したものである。さらに、ソースコードｓｒｃ１には、コード１１０２として「ｖｏｉｄ  ｆｕｎｃ１（ｌｏｎｇ  ｐａｒａｍ）」という関数の処理と、コード１１０３として「ｖｏｉｄ  ｆｕｎｃ１（ｕｎｓｉｇｎｅｄ  ｉｎｔ  ｐａｒａｍ）」という関数の処理とを含む。さらに、ソースコードｓｒｃ１には、コード１１０４として「ｔｅｍｐｌａｔｅ  ＜ｃｌａｓｓ  Ｔ＞ｖｏｉｄ  ｆｕｎｃ２（Ｔ  ｐａｒａｍ）」というテンプレート関数の定義を含む。
【００８６】
また、情報処理装置１０１は、図８で示した手順に従って作成した中間言語情報１１２１、１１２２を有する。中間言語情報１１２１は、作成仮引数の名称がａｒｇｓ１であり、作成仮引数の型がｌｏｎｇ型であることを示す。また、中間言語情報１１２２は、作成仮引数の名称がａｒｇｓ２であり、作成仮引数の型がｕｎｓｉｇｎｅｄ  ｉｎｔ型であることを示す。
【００８７】
情報処理装置１０１は、関数パラメタパックの仮引数ではない仮引数が、対象の関数とは異なる他の関数の実引数となる場合、中間言語情報の型に基づいて、他の関数を検索する検索処理または、インスタンシェートにより関数を生成する生成処理を実行する。図１１の場合、情報処理装置１０１は、複製コード１１１１について、検索処理として、関数名がｆｕｎｃ１であり、ａｒｇｓ１の型であるｌｏｎｇを仮引数に持つ関数を、ソースコードｓｒｃ１から検索する。この場合、情報処理装置１０１は、コード１１０２を検出し、複製コード１１１１内のｆｕｎｃ１（ｈｅａｄ）；を、検索処理により検出したｆｕｎｃ１（ａｒｇｓ１）；に変換する。
【００８８】
また、情報処理装置１０１は、複製コード１１１１について、検索処理として、関数名がｆｕｎｃ２であり、ｌｏｎｇを仮引数に持つ関数を検索する。この場合、情報処理装置１０１は、条件にあった関数を見つけることができないが、コード１１０４で定義したテンプレート関数ｆｕｎｃ２を検出することができる。従って、情報処理装置１０１は、生成処理として、コード１１０４から、ｌｏｎｇを仮引数に持つ関数ｆｕｎｃ２を生成する。そして、情報処理装置１０１は、複製コード１１１１内のｆｕｎｃ２（ｈｅａｄ）；を、生成処理により検出したｆｕｎｃ２（ａｒｇｓ１）；に変換する。情報処理装置１０１は、複製コード１１１２についても同様に、検索処理または生成処理を実行する。
【００８９】
図１２は、関数パラメタパック展開後の中間言語１情報４２２の一例を示す説明図である。図１２に示す関数パラメタパック展開後の中間言語１情報４２２は、関数ｆｕｎｃ情報１２０１と、関数ｍａｉｎ情報７０２とを含む。関数ｍａｉｎ情報７０２は、図７と同一の情報であるため、説明を省略する。
【００９０】
関数ｆｕｎｃ情報１２０１は、仮引数情報１２１１を有する。仮引数情報１２１１は、第一引数がｈｅａｄであり、第一引数の型がｉｎｔであることを示す。また、仮引数情報１２１１は、第二引数がａｒｇｓ１であり、第二引数の型がｌｏｎｇであることを示す。また、仮引数情報１２１１は、第三引数がａｒｇｓ２であり、第三引数の型がｕｎｓｉｇｎｅｄ  ｉｎｔであることを示す。また、仮引数情報１２１１は、第四引数がａｒｇｓ３であり、第四引数の型がｆｌｏａｔであることを示す。また、仮引数情報１２１１は、第五引数がａｒｇｓ４であり、第五引数の型がｄｏｕｂｌｅであることを示す。
【００９１】
図１３は、関数パラメタパック展開後のソースイメージの一例を示す説明図である。図１３に示すプログラム１３０１は、本実施の形態を実施することにより生成される関数パラメタパック展開後の中間言語１情報４２２を、ソースイメージで表現したものである。
【００９２】
次に、情報処理装置１０１が行うコンパイル処理のフローチャートについて、図１４〜図１６を用いて説明する。
【００９３】
図１４は、コンパイル処理手順の一例を示すフローチャートである。情報処理装置１０１は、ソースコードｓｒｃを読み込んで解析し、中間言語１情報４２１を生成する（ステップＳ１４０１）。次に、情報処理装置１０１は、関数パラメタパックを持つテンプレート関数か否かを判断する（ステップＳ１４０２）。関数パラメタパックを持つテンプレート関数である場合（ステップＳ１４０２：Ｙｅｓ）、情報処理装置１０１は、関数パラメタパック展開処理を実行する（ステップＳ１４０３）。関数パラメタパック展開処理については、図１５、図１６で説明する。
【００９４】
ステップＳ１４０３の処理終了後、または、関数パラメタパックを持つテンプレート関数でない場合（ステップＳ１４０２：Ｎｏ）、情報処理装置１０１は、中間言語変換部以降を実施してオブジェクトプログラムｏｂｊを生成する（ステップＳ１４０４）。ステップＳ１４０４の処理終了後、情報処理装置１０１は、コンパイル処理を終了する。
【００９５】
図１５は、関数パラメタパック展開処理手順の一例を示すフローチャート（その１）である。また、図１６は、関数パラメタパック展開処理手順の一例を示すフローチャート（その２）である。情報処理装置１０１は、テンプレート関数内に再帰呼び出しがあるか否かを判断する（ステップＳ１５０１）。
【００９６】
テンプレート関数内に再帰呼び出しがない場合（ステップＳ１５０１：Ｎｏ）、情報処理装置１０１は、関数パラメタパック展開による中間言語１情報４２２を生成する（ステップＳ１５０５）。ステップＳ１５０５の処理を行うと、情報処理装置１０１は、図６に相当する中間言語１情報を生成する。ステップＳ１５０５の処理終了後、情報処理装置１０１は、関数パラメタパック展開処理を終了する。
【００９７】
一方、テンプレート関数内に再帰呼び出しがある場合（ステップＳ１５０１：Ｙｅｓ）、情報処理装置１０１は、呼び出し時の実引数が関数パラメタパックの仮引数か否かを判断する（ステップＳ１５０２）。呼び出し時の実引数が関数パラメタパックの仮引数である場合（ステップＳ１５０２：Ｙｅｓ）、情報処理装置１０１は、関数パラメタパックの仮引数の参照が呼び出しの実引数だけか否かを判断する（ステップＳ１５０３）。関数パラメタパックの仮引数の参照が呼び出しの実引数だけである場合（ステップＳ１５０３：Ｙｅｓ）、情報処理装置１０１は、テンプレート関数と同一名称の引数を持たない関数があるか否かを判断する（ステップＳ１５０４）。
【００９８】
呼び出し時の実引数が関数パラメタパックの仮引数でない場合（ステップＳ１５０２：Ｎｏ）、または、関数パラメタパックの仮引数の参照が呼び出しの実引数以外にある場合（ステップＳ１５０３：Ｎｏ）、テンプレート関数と同一名称の引数を持たない関数がない場合（ステップＳ１５０４：Ｎｏ）、情報処理装置１０１は、ステップＳ１５０５の処理に移行する。
【００９９】
テンプレート関数と同一名称の引数を持たない関数がある場合（ステップＳ１５０４：Ｙｅｓ）、情報処理装置１０１は、再帰呼び出し以外のテンプレート関数の呼び出し式を探索する（ステップＳ１６０１）。次に、情報処理装置１０１は、呼び出し式が見つかったか否かを判断する（ステップＳ１６０２）。
【０１００】
呼び出し式が見つかった場合（ステップＳ１６０２：Ｙｅｓ）、情報処理装置１０１は、テンプレート関数本体の中間言語情報を複製する（ステップＳ１６０３）。次に、情報処理装置１０１は、関数パラメタパックに渡される実引数の数を算出する（ステップＳ１６０４）。そして、情報処理装置１０１は、「関数パラメタパックに渡される実引数の数」の個数分の作成仮引数を表す中間言語情報を作成する（ステップＳ１６０５）。ステップＳ１６０５の処理を実行すると、情報処理装置１０１は、図８相当の中間言語情報を作成する。
【０１０１】
次に、情報処理装置１０１は、作成した中間言語情報を、複製したテンプレート関数本体の仮引数情報の関数パラメタパックの仮引数情報に置換する（ステップＳ１６０６）。ステップＳ１６０６の処理について、図７、図８を用いて説明する。情報処理装置１０１は、複製したテンプレート関数本体の仮引数情報７１１の第二引数の部分を、図８で作成した中間言語情報８０１〜８０４に置換する。
【０１０２】
そして、情報処理装置１０１は、「関数パラメタパックに渡される実引数の数」の個数分、テンプレート関数のコードを複製する（ステップＳ１６０７）。次に、情報処理装置１０１は、複製した複製コード内で参照されている関数パラメタパックの仮引数情報を、複製した仮引数情報に順次置換する（ステップＳ１６０８）。
【０１０３】
そして、情報処理装置１０１は、複製コードを、再帰呼び出しの式の箇所に順次挿入する（ステップＳ１６０９）。ここで、具体的には、情報処理装置１０１は、複製したテンプレート関数本体の再帰呼び出しの式の箇所に、関数パラメタパックの仮引数に対応する実引数群の先頭の実引数を受け入れる作成仮引数に置換した置換コードを挿入する。そして、情報処理装置１０１は、実引数群の順番に従って、複製コードを、１つまえの複製コードの箇所に挿入する。次に、情報処理装置１０１は、最後の複製コードで関数パラメタパックを使用している箇所を、引数なしの同名関数のコードに置き換えて挿入する（ステップＳ１６１０）。そして、情報処理装置１０１は、ステップＳ１６０１の処理に移行する。
【０１０４】
呼び出し式が見つからなかった場合（ステップＳ１６０２：Ｎｏ）、情報処理装置１０１は、テンプレート関数および引数なしの同名関数の中間言語情報を削除する（ステップＳ１６１１）。ステップＳ１６１１の処理終了後、情報処理装置１０１は、関数パラメタパック展開処理を終了する。
【０１０５】
以上説明したように、情報処理装置１０１は、可変個の仮引数を持つテンプレート関数のコンパイル時、可変個の仮引数に渡す実引数分、関数の処理を複製した各処理内の仮引数を実引数の受け入れ用の仮引数に置換し、関数の再帰呼び出し部分に順次挿入する。これにより、情報処理装置１０１は、不要となる関数の作成を抑制することができる。そして、不要となる関数の作成が抑制されることにより、最適化の入力となるコードを削減し、最適化の処理時間や必要なメモリ量を削減することができる。また、関数のコードが削減されるため、情報処理装置１０１は、不要な最適化処理を行わなくなり、翻訳性能の改善を図ることができる。
【０１０６】
また、情報処理装置１０１は、ｕｎｐａｃｋ演算子に基づいて定義された仮引数に対応する実引数列の末尾の実引数を受け入れる作成仮引数に置換した処理の再帰呼び出し部分に、ソースコードｓｒｃ内のテンプレート関数と同一名称の関数の処理を挿入する。これにより、情報処理装置１０１は、本実施の形態による関数パラメタパックを展開した後のコードに対しても、同一名称の関数に対してインライン最適化を行う場合と同等の最適化を行うことができる。
【０１０７】
また、情報処理装置１０１は、複製した各処理内における他の仮引数を各作成仮引数に置換するとともに、各処理内におけるいずれかの仮引数を、各作成仮引数に受け入れられる実引数より後ろ全ての実引数のそれぞれを受け入れる作成仮引数に置換する。これにより、情報処理装置１０１は、複製した各処理について、インスタンシェートを行った場合と同一の処理結果を得ることができる。より具体的には、例えば、図９に示した複製コード９１１は、図６に示した関数６０２内の処理と同一のものとなる。同様に、図９に示した複製コード９１２は、図６に示した関数６０３内の処理と同一のものとなる。
【０１０８】
また、ソースコードｓｒｃに、仮引数が０個の対象のテンプレート関数と同一名称である第１の関数と、仮引数が１つの対象のテンプレート関数と同一名称である第２の関数があってもよい。このとき、情報処理装置１０１は、最後の置換コードの再帰呼び出し部分に、第１の関数または第２の関数のうち、最後の置換コードの再帰呼び出し部分の実引数に応じた関数の処理を挿入する。これにより、情報処理装置１０１は、最後の複製コード内の再帰呼び出しの実引数が１つとなる場合と、実引数が０個となる場合とが起こる場合であっても、適切な関数の処理を挿入することができる。
【０１０９】
なお、本実施の形態で説明したコンパイル方法は、予め用意されたプログラムをパーソナル・コンピュータやワークステーション等のコンピュータで実行することにより実現することができる。本コンパイルプログラムは、ハードディスク、フレキシブルディスク、ＣＤ−ＲＯＭ（Ｃｏｍｐａｃｔ  Ｄｉｓｃ−Ｒｅａｄ  Ｏｎｌｙ  Ｍｅｍｏｒｙ）、ＤＶＤ（Ｄｉｇｉｔａｌ  Ｖｅｒｓａｔｉｌｅ  Ｄｉｓｋ）等のコンピュータで読み取り可能な記録媒体に記録され、コンピュータによって記録媒体から読み出されることによって実行される。また本コンパイルプログラムは、インターネット等のネットワークを介して配布してもよい。
【符号の説明】
【０１１０】
１０１  情報処理装置
４００  制御部
４０１  構文・意味解析部
４０２  パラメタパック展開部
４０３  中間言語変換部
４０４  最適化・コード生成部
４１１  複製部
４１２  置換部
４１３  挿入部
【図１】
0006651977.tif 000002
【図２】
0006651977.tif 000003
【図３】
0006651977.tif 000004
【図４】
0006651977.tif 000005
【図５】
0006651977.tif 000006
【図６】
0006651977.tif 000007
【図７】
0006651977.tif 000008
【図８】
0006651977.tif 000009
【図９】
0006651977.tif 000010
【図１０】
0006651977.tif 000011
【図１１】
0006651977.tif 000012
【図１２】
0006651977.tif 000013
【図１３】
0006651977.tif 000014
【図１４】
0006651977.tif 000015
【図１５】
0006651977.tif 000016
【図１６】
0006651977.tif 000017