(57)【特許請求の範囲】
【請求項１】
コンパイル装置が、高級言語で記述されたソースプログラムをオブジェクトコードに変換するコンパイル方法であって、
前記コンパイル装置の中間コード生成手段が、プログラム記憶部に記憶されているソースプログラムから中間コードを生成し、生成した前記中間コードをメモリに記憶する中間コード生成ステップと、
前記コンパイル装置の値渡し関数呼び出し参照渡し変換手段が、前記メモリに記憶されている前記中間コードにおいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に変換する値渡し関数呼び出し参照渡し変換ステップと、
前記コンパイル装置の値渡し関数定義参照渡し変換手段が、前記メモリに記憶されている前記中間コードにおいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する値渡し関数定義参照渡し変換ステップと、
前記コンパイル装置のオブジェクトコード変換手段が、前記メモリに記憶されている前記中間コードをオブジェクトコードに変換し、前記オブジェクトコードを生成コード記憶部に記憶するオブジェクトコード変換ステップとを含む
ことを特徴とするコンパイル方法。
【請求項２】
前記コンパイル方法は、さらに、
前記コンパイル装置の値渡し引数更新情報抽出部が、前記メモリに記憶されている前記中間コードから、少なくとも、値渡し引数を持つ関数と、当該値渡し引数を持つ関数を直接呼び出す関数と、当該値渡し引数を持つ関数を間接的に呼び出す可能性のある関数と、当該値渡し引数を持つ関数の値渡し引数と、当該値渡し引数が値渡し引数を持つ関数の定義内で更新されているか否かを示す更新判定情報とを含む値渡し引数更新情報を抽出し、抽出した前記値渡し引数更新情報を値渡し引数更新情報記憶部に書き込む値渡し引数更新情報抽出ステップを含み、
前記値渡し関数定義参照渡し変換ステップでは前記値渡し関数定義参照渡し変換手段が、前記値渡し関数呼び出し参照渡し変換ステップでは前記値渡し関数呼び出し参照渡し変換手段が、それぞれ、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づき、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合を特定する
ことを特徴とする請求項１に記載のコンパイル方法。
【請求項３】
前記値渡し関数呼び出し参照渡し変換ステップでは、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がない場合には、前記値渡し関数呼び出し参照渡し変換手段が前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を直接呼び出す関数を参照渡し引数を持つ関数を直接呼び出す関数に変換する
ことを特徴とする請求項２に記載のコンパイル方法。
【請求項４】
前記値渡し関数呼び出し参照渡し変換ステップでは、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し関数呼び出し参照渡し変換手段が前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を直接呼び出す関数および前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数を、参照渡し引数を持つ関数を直接呼び出す関数および参照渡し引数を持つ関数を間接的に呼び出す可能性のある関数にそれぞれ変換する
ことを特徴とする請求項２または３に記載のコンパイル方法。
【請求項５】
前記値渡し関数定義参照渡し変換ステップでは、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がない場合には、前記値渡し関数定義参照渡し変換手段が、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する
ことを特徴とする請求項２に記載のコンパイル方法。
【請求項６】
前記値渡し関数定義参照渡し変換ステップでは、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し関数定義参照渡し変換手段が、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換し、前記値渡し引数が関数定義内で更新されていれば、前記中間コードにおいて実際に値が更新される部分よりも前に、変換された参照渡し引数から引数値を参照してそのコピーを生成し、当該コピーを参照先に設定する
ことを特徴とする請求項２または５に記載のコンパイル方法。
【請求項７】
高級言語で記述されたソースプログラムをオブジェクトコードに変換するコンパイラであって、
請求項１〜６のいずれか１項に記載のコンパイル方法に含まれる各ステップをコンピュータに実行させる
ことを特徴とするコンパイラ。
【請求項８】
請求項７に記載のコンパイラを記録したコンピュータ読取可能な記録媒体。
【請求項９】
高級言語で記述されたソースプログラムをオブジェクトコードに変換するコンパイル装置であって、
プログラム記憶部に記憶されているソースプログラムから中間コードを生成し、生成した前記中間コードをメモリに記憶する中間コード生成手段と、
前記メモリに記憶されている前記中間コードにおいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に変換する値渡し関数呼び出し参照渡し変換手段と、
前記メモリに記憶されている前記中間コードにおいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する値渡し関数定義参照渡し変換手段と、
前記メモリに記憶されている前記中間コードをオブジェクトコードに変換し、前記オブジェクトコードを生成コード記憶部に記憶するオブジェクトコード変換手段とを備える
ことを特徴とするコンパイル装置。
【請求項１０】
前記コンパイル装置は、さらに、
前記メモリに記憶されている前記中間コードから、少なくとも、値渡し引数を持つ関数と、当該値渡し引数を持つ関数を直接呼び出す関数と、当該値渡し引数を持つ関数を間接的に呼び出す可能性のある関数と、当該値渡し引数を持つ関数の値渡し引数と、当該値渡し引数が値渡し引数を持つ関数の定義内で更新されているか否かを示す更新判定情報とを含む値渡し引数更新情報を抽出し、抽出した前記値渡し引数更新情報を値渡し引数更新情報記憶部に記憶する値渡し引数更新情報抽出部を備え、
前記値渡し関数定義参照渡し変換手段および前記値渡し関数呼び出し参照渡し変換手段は、それぞれ、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づき、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合を特定する
ことを特徴とする請求項９に記載のコンパイル装置。
【請求項１１】
前記値渡し関数呼び出し参照渡し変換手段は、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がない場合には、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を直接呼び出す関数を参照渡し引数を持つ関数を直接呼び出す関数に変換する
ことを特徴とする請求項１０に記載のコンパイル装置。
【請求項１２】
前記値渡し関数呼び出し参照渡し変換手段は、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を直接呼び出す関数および前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数を、参照渡し引数を持つ関数を直接呼び出す関数および参照渡し引数を持つ関数を間接的に呼び出す可能性のある関数にそれぞれ変換する
ことを特徴とする請求項１０または１１に記載のコンパイル装置。
【請求項１３】
前記値渡し関数定義参照渡し変換手段は、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がない場合には、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する
ことを特徴とする請求項１０に記載のコンパイル装置。
【請求項１４】
前記値渡し関数定義参照渡し変換手段は、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し引数更新情報記憶部に記憶されている前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換し、前記値渡し引数が関数定義内で更新されていれば、前記メモリに記憶されている前記中間コードにおいて実際に値が更新される部分よりも前に、変換された参照渡し引数から引数値を参照してそのコピーを生成し、当該コピーを参照先に設定する
ことを特徴とする請求項１０または１３に記載のコンパイル装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンパイル方法に関し、特に、Ｃ＋＋言語に代表されるオブジェクト指向高級言語で記述されたソースプログラムをオブジェクトプログラムに変換するコンパイル方法に関する。
【背景技術】
【０００２】
近年のソフトウェア開発においては、プログラムの規模が大規模化してきており、それに伴って保守性、再利用性の高いオブジェクト指向言語が注目されている。代表的なオブジェクト指向言語にＣ＋＋言語が挙げられる。Ｃ＋＋言語は、移植性の優れた高級言語であるＣ言語をオブジェクト指向が自然と記述できるように仕様拡張したものである。Ｃ＋＋言語では、プログラム中で関数を定義し、必要な箇所でその関数を呼び出して処理を実行することができる。関数に対して引数を与える場合、その方法として値渡しと参照渡し（ポインタ渡し）とが存在する。
【０００３】
従来のＣ＋＋言語では、関数に対して引数を与える場合、与えた引数のコピーを生成してメモリに格納している。値渡しの場合は、引数として渡す対象を完全にコピーしてメモリに格納する。例えば対象がクラスオブジェクトの場合であれば、まずそのクラスオブジェクトのコピーを生成する処理を行ない、生成したクラスオブジェクトをメモリに格納する。一方、参照渡しの場合は、対象がポインタ値（オブジェクトのアドレス値）であるので、そのポインタ値をコピーしてメモリに格納する。
【０００４】
非特許文献１の２２項によれば、値渡しにおけるクラスオブジェクトのコピーは、暗黙的に多くのコピーコンストラクタの呼び出しを引き起こす可能性があり、コンパイル結果のコードサイズ増加の原因となり得る。また、一般的に値渡しよりも参照渡し（リファレンス渡し）を使用するほうがコード生成効率がよいため、プログラマはできるだけ参照渡しを意識したプログラミングを行なうことが重要であるとしている。
【非特許文献１】Ｓｃｏｔｔ  Ｍｅｙｅｒｓ著、吉川邦夫訳、「Ｅｆｆｅｃｔｉｖｅ  Ｃ＋＋  改訂２版」、アスキー、１９９８年５月１日、２２項「値渡しよりも、リファレンス渡しを使おう」
【発明の開示】
【発明が解決しようとする課題】
【０００５】
しかしながら、非特許文献１の２２項に記載されている内容は、あくまでプログラマが参照渡しを意識してプログラミングを行なうべきであるということを明記したものであり、プログラマにコード生成効率を考慮したプログラミングを強いることにほかならない。
また、参照渡しを使用すると、エイリアシング問題（同じオブジェクトに対して複数の名前が使用されるため、意図せずにオブジェクトの状態を変更させる危険性がある問題）を引き起こす可能性がある。よって、プログラムにバグが混入しやすいという課題がある。
【０００６】
本発明は、かかる課題に鑑みてなされたものであり、プログラマが参照渡しを意識してプログラミングを行なう必要性をなくし、値渡しを使用した場合でもコード生成効率のよいコンパイル方法を提供することを目的とする。
【課題を解決するための手段】
【０００７】
本発明のある局面に係るコンパイル方法は、高級言語で記述されたソースプログラムをオブジェクトコードに変換するコンパイル方法であって、ソースプログラムから中間コードを生成する中間コード生成ステップと、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に変換することにより、前記中間コードを最適化する最適化ステップと、最適化された前記中間コードをオブジェクトコードに変換するオブジェクトコード変換ステップとを含む。好ましくは、前記最適化ステップは、前記中間コードから、少なくとも、値渡し引数を持つ関数と、当該値渡し引数を持つ関数を直接呼び出す関数と、当該値渡し引数を持つ関数を間接的に呼び出す可能性のある関数と、当該値渡し引数を持つ関数の値渡し引数と、当該値渡し引数が値渡し引数を持つ関数の定義内で更新されているか否かを示す更新判定情報とを含む値渡し引数更新情報を抽出する値渡し引数更新情報抽出サブステップと、前記値渡し引数更新情報に基づいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に変換する変換サブステップとを含む。
【０００８】
この方法によれば、値渡しでプログラムを記載したとしても、参照渡しのプログラムに変換される。このため、プログラマが参照渡しを意識してプログラミングを行なう必要がなくなる。
【０００９】
好ましくは、前記変換サブステップでは、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がない場合には、前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数を直接呼び出す関数を参照渡し引数を持つ関数を直接呼び出す関数に変換する。
【００１０】
この方法によれば、値渡し引数をもつ関数が定義内で引数を更新していなかった場合に、冗長である関数呼び出し側のコピー生成コードを削除することができ、効率のよいコードを生成することができる。
【００１１】
さらに好ましくは、前記変換サブステップでは、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を直接呼び出す関数および前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数を、参照渡し引数を持つ関数を直接呼び出す関数および参照渡し引数を持つ関数を間接的に呼び出す可能性のある関数にそれぞれ変換する。
【００１２】
この方法によれば、値渡し引数をもつ関数が定義内で引数を更新していた場合でも、冗長である関数呼び出し側のコピー生成コードを削除することができ、効率のよいコードを生成することができる。
【００１３】
本発明の他の局面に係るコンパイル方法は、高級言語で記述されたソースプログラムをオブジェクトコードに変換するコンパイル方法であって、ソースプログラムから中間コードを生成する中間コード生成ステップと、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換することにより、前記中間コードを最適化する最適化ステップと、最適化された前記中間コードをオブジェクトコードに変換するオブジェクトコード変換ステップとを含む。好ましくは、前記最適化ステップは、前記中間コードから、少なくとも、値渡し引数を持つ関数と、当該値渡し引数を持つ関数を直接呼び出す関数と、当該値渡し引数を持つ関数を間接的に呼び出す可能性のある関数と、当該値渡し引数を持つ関数の値渡し引数と、当該値渡し引数が値渡し引数を持つ関数の定義内で更新されているか否かを示す更新判定情報とを含む値渡し引数更新情報を抽出する値渡し引数更新情報抽出サブステップと、前記値渡し引数更新情報に基づいて、値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が当該値渡し引数を持つ関数の定義内で更新されていない場合に、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する変換サブステップとを含む。
【００１４】
この方法によれば、値渡しでプログラムを記載したとしても、参照渡しのプログラムに変換される。このため、プログラマが参照渡しを意識してプログラミングを行なう必要がなくなる。
【００１５】
好ましくは、前記変換サブステップでは、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がない場合には、前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数を間接的に呼び出す可能性のある関数がなく、かつ前記値渡し引数が値渡し引数を持つ関数の定義内で更新されていない場合に、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換する。
【００１６】
この方法によれば、値渡し引数をもつ関数が定義内で引数を更新していなかった場合に、値渡し引数を持つ関数定義における引数に対するアクセスが参照渡し引数を持つ関数定義と同等のアクセスになるため、効率のよいコードを生成することができる。
【００１７】
さらに好ましくは、前記変換サブステップでは、値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに強制的に変換せよとの指定がある場合には、当該指定がある値渡し引数を持つ関数について、前記値渡し引数更新情報に基づいて、前記値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換し、前記値渡し引数が関数定義内で更新されていれば、前記中間コードにおいて実際に値が更新される部分よりも前に、変換された参照渡し引数から引数値を参照してそのコピーを生成し、当該コピーを参照先に設定する。
【００１８】
この方法によれば、値渡し引数をもつ関数が定義内で引数を更新していた場合でも、値渡し引数を持つ関数定義における引数に対するアクセスが参照渡し引数を持つ関数定義と同等のアクセスになるため、効率のよいコードを生成することができる。
【００１９】
なお、本発明は、このような特徴的なステップを有するコンパイル方法として実現することができるだけでなく、当該コンパイル方法に含まれる特徴的なステップを手段とするコンパイラ装置として実現したり、当該コンパイル方法に含まれる特徴的なステップをコンピュータに実行させるコンパイラとして実現したりすることもできる。そして、そのようなコンパイラは、ＣＤ−ＲＯＭ等の記録媒体やインターネット等の伝送媒体を介して流通させることができるのは言うまでもない。
【発明の効果】
【００２０】
本発明のコンパイル方法によれば、プログラマが参照渡しを意識してプログラミングを行なう必要性がなくなる。
また、値渡しを使用した場合でも、コードサイズの小さいオブジェクトコードを生成することができる。
なお、ユーザーが高級言語プログラム内に直接アセンブラ言語を記述する構文（ａｓｍ文構文など）を用いて、値渡し引数を持つ関数を呼び出す関数を参照渡し引数を持つ関数を呼び出す関数に変換することにより中間コードを最適化するステップおよび値渡し引数を持つ関数の値渡しによる引数受け渡しを参照渡しによる引数受け渡しに変換することにより中間コードを最適化するステップのいずれか一方に準拠したアセンブラコードをソースプログラムを記述した場合であっても同様の効果が得られる。
【発明を実施するための最良の形態】
【００２１】
以下、本発明の実施の形態に係るコンパイラについて図面を参照しながら説明する。
図１は、コンパイラを実行するコンパイラ装置の外観図である。コンパイラ装置２２は、コンピュータ３４と、モニタ装置３２と、キーボード３６と、マウス３８と、ＣＤ−ＲＯＭ（Compact Disc-Read Only Memory）装置４０とを備えている。
コンピュータ３４は、コンパイラ等のプログラムを実行する処理装置である。モニタ装置３２は、処理結果等を表示するための表示装置である。キーボード３６およびマウス３８の各々は、コンピュータ３４に接続され、コンピュータ３４に対して指示等を入力するための入力装置である。ＣＤ−ＲＯＭ装置４０は、ＣＤ−ＲＯＭ４２に記録されたコンパイラ等のプログラムを読み込むための装置である。
【００２２】
図２は、コンパイラ装置２２のハードウェア構成を示すブロック図である。コンパイラ装置２２を構成するコンピュータ３４は、ＣＰＵ（Central Processing Unit）４４と、ＲＯＭ（Read Only Memory）４６と、ＲＡＭ（Random Access Memory）４８と、ハードディスク５０と、通信モデム５２と、バス５４とを備えている。
ＣＰＵ４４は、コンパイラ等の各種プログラムを実行する処理部である。ＲＯＭ４６は、各種プログラムや各種データを記憶する記憶部である。ＲＡＭ４８は、ＣＰＵ４４で実行されるプログラムや、当該プログラム実行時に生成されるデータを一時的に記憶する記憶部である。ハードディスク５０は、各種プログラムや、各種データを記憶する記憶装置であり、ヘッダファイルやソースプログラムを記憶するプログラム記憶部５６と、後述する値渡し引数更新情報を記憶する値渡し引数更新情報記憶部５８と、オブジェクトプログラムを記憶する生成コード記憶部６０とを含む。通信モデム５２は、インターネット等のネットワークを介してプログラムをダウンロードするための装置である。バス５４は、コンピュータ３４の各処理部を接続するための信号線である。
【００２３】
図３は、コンパイラの処理のフローチャートである。
コンパイラは、プログラム記憶部５６に記憶されているヘッダファイルおよびソースプログラムを読み込む（Ｓ１）。コンパイラは、読み込んだソースプログラムの構文を解析し、シンボルテーブルの生成や構文木の生成などを行なう（Ｓ２）。次に、コンパイラは、生成された構文木を元に、中間コードを生成する（Ｓ３）。その後、コンパイラは、生成された中間コードに対して各種最適化を実行する（Ｓ４）。また、コンパイラは、最適化された中間コードに含まれるすべての変数に対してレジスタやメモリなどのハードウェア資源を割り付け（Ｓ５）、資源割付された中間コードをオブジェクトコードに変換してオブジェクトプログラムを生成コード記憶部６０に出力する（Ｓ６）。
【００２４】
最適化処理（Ｓ４）は、値渡し引数更新情報抽出処理（Ｓ１１）と、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）と、値渡し関数定義参照渡し変換処理（Ｓ１３）と、その他の最適化処理（Ｓ１４）とを含む。
値渡し引数更新情報抽出処理（Ｓ１１）は、中間コードに基づいて、「値渡し引数を持つ関数」と、「値渡し引数を持つ関数を直接呼び出す関数」と、「値渡し引数を持つ関数を間接的に呼び出す可能性のある関数」と、「値渡し引数」と、値渡し引数が関数定義内で更新されているかどうかを示す「更新判定情報」とを抽出する処理である。
【００２５】
値渡し関数呼び出し参照渡し変換処理（Ｓ１２）は、値渡し引数更新情報抽出処理（Ｓ１１）で抽出された情報を元に、参照渡し変換が可能かどうかを判定し、値渡し関数の呼び出しを参照渡し関数の呼び出しに変換する処理である。
値渡し関数定義参照渡し変換処理（Ｓ１３）は、値渡し引数更新情報抽出処理（Ｓ１１）で抽出された情報を元に、参照渡し変換が可能かどうかを判定し、値渡し関数の値による引数受け渡しを、参照による引数受け渡しに変換する処理である。
【００２６】
値渡し引数更新情報抽出処理（Ｓ１１）、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）および値渡し関数定義参照渡し変換処理（Ｓ１３）の詳細については後述する。
なお、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）および値渡し関数定義参照渡し変換処理（Ｓ１３）は順序に依存せず、どちらから先に行なっても構わない。
その他の最適化処理（Ｓ１４）は、一般的な最適化処理であり、本発明の要旨ではないため、その説明は省略する。
【００２７】
図４は、値渡し引数更新情報記憶部５８に記憶されている値渡し引数更新情報６２の内容を説明するための図である。値渡し引数更新情報６２には、「値渡し引数を持つ関数」と、「値渡し引数を持つ関数を直接呼び出す関数」と、「値渡し引数を持つ関数を間接的に呼び出す可能性のある関数」と、「値渡し引数」と、「更新判定情報」と、「参照渡し変換判定情報」とが含まれる。これらの詳細な説明は、後述する処理の中で適宜説明する。
【００２８】
なお、ソースプログラム入力処理（Ｓ１）、構文解析処理（Ｓ２）、中間コード生成処理（Ｓ３）、その他の最適化処理（Ｓ１４）、資源割付処理（Ｓ５）、およびオブジェクト出力処理（Ｓ６）については、既存の処理と同様の処理であり本発明の主眼ではない。よって詳細な説明は省略する。
以下、本発明の主眼である値渡し引数更新情報抽出処理（Ｓ１１）、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）および値渡し関数定義参照渡し変換処理（Ｓ１３）について順次説明する。
【００２９】
図５は、値渡し引数更新情報抽出処理（Ｓ１１）の詳細を示すフローチャートである。
コンパイラは、現コンパイル対象の中間コードからすべての関数宣言、定義の情報を抽出する（Ｓ２１）。この場合のコンパイル対象は、単一の翻訳単位（単一のソースプログラム）に対するコンパイルであっても、複数にわたる翻訳単位（複数のソースプログラム）に対するコンパイルであっても構わない。
【００３０】
コンパイラは、抽出した関数宣言、定義から「値渡し引数を持つ関数」を抽出し、値渡し引数更新情報６２に記録する（Ｓ２２）。次に、記録した各値渡し関数を直接呼び出す（関数名などを使用した呼び出しであり、コンパイル時にどの関数が呼び出されているかが一意に決定する）関数を抽出し、値渡し引数更新情報６２に記録する（Ｓ２３）。同様に、記録した各値渡し関数を間接的に呼び出す（関数へのポインタなどを使用した呼び出しであり、コンパイル時にどの関数が呼び出されているかが一意には決まらない）可能性のある関数を抽出し、値渡し引数更新情報６２に記録する（Ｓ２４）。
【００３１】
図６は、値渡し関数を間接的に呼び出す可能性のある関数を含むソースプログラムの一例を示す図である。関数ｆｕｃｎ１の定義の中で、構造体Ａの値渡し引数を持つ関数の関節呼び出しｐ（ｘ）が存在する。この関数呼び出しｐ（ｘ）では、構造体Ａの値渡し引数を持つ関数ｆｕｎｃ２、ｆｕｎｃ３およびｆｕｎｃ４のいずれを実際に呼び出しているかは一意に特定することができない。このため、図７（ａ）〜図７（ｃ）に示すように、関数ｆｕｎｃ２、ｆｕｎｃ３およびｆｕｎｃ４の各々の値渡し引数更新情報６２に、値渡し関数を間接的に呼び出す可能性のある関数としてｆｕｎｃ１が記録されることになる。
【００３２】
次に、コンパイラは、記録した各値渡し関数の各値渡し引数に対して以下に続く処理を行なう（Ｓ２５）。値渡し引数が関数定義内で更新されている可能性があるかどうか判定し（Ｓ２６）、更新される可能性がなければ（Ｓ２６でＮｏ）、値渡し引数は更新されていないとの更新判定情報を値渡し引数更新情報６２に記録し（Ｓ２７）、更新される可能性があれば（Ｓ２６でＹｅｓ）、値渡し引数は更新されているとの更新判定情報を値渡し引数更新情報６２に記録する（Ｓ２８）。
【００３３】
以上の処理を実施することにより、現コンパイル対象における値渡し引数更新情報６２の「値渡し引数を持つ関数」、「値渡し引数を持つ関数を直接呼び出す関数」、「値渡し引数を持つ関数を間接的に呼び出す可能性のある関数」、「値渡し引数」および「更新判定情報」が抽出される。
【００３４】
次に、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）の詳細について説明する。図８は、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）の詳細を示すフローチャートである。
【００３５】
まず、コンパイラは、値渡しの関数を参照渡しの関数に強制的に変換するかどうかの判定を行なう（Ｓ３１）。ここで、強制的に変換するかどうかは、コマンドラインオプションやプラグマなどのユーザーの指示によるものや、コンパイラ内部で別途行なわれる最適化評価結果（オブジェクトプログラムをシミュレーションした後のプロファイル情報等）によるものである。コードサイズを小さくしたい場合には、参照渡しに強制的に変換する。
【００３６】
強制的な変換を行なわない場合は（Ｓ３１でＮｏ）、登録されている各値渡し引数更新情報６２について、以下のループ処理（Ｓ３２）を繰り返す。コンパイラは、着目している値渡し引数更新情報６２に含まれる「値渡し引数を持つ関数を直接呼び出す関数」および「値渡し引数を持つ関数を間接的に呼び出す可能性のある関数」がａｓｍ文等のアセンブラ記述により参照渡しによる呼び出しに変換されているか否かを調べる（Ｓ３３）。参照渡しによる呼び出しに変換されている場合には（Ｓ３３でＹｅｓ）、次の値渡し引数更新情報６２に着目してループ処理（Ｓ３２）を繰り返す。
【００３７】
アセンブラ記述により参照渡しによる呼び出しに変換されていなければ（Ｓ３３でＮｏ）、コンパイラは、着目している「値渡し引数を持つ関数」を間接呼び出しする可能性があるかどうかを判定する（Ｓ３４）。すなわち、値渡し引数更新情報６２の「値渡し引数を持つ関数を間接的に呼び出す可能性のある関数」の欄に関数名が記入されているか否かを調べる（Ｓ３４）。
【００３８】
間接的に呼び出す可能性のある関数が存在する場合には（Ｓ３４でＹｅｓ）、参照渡し変換の対象にならないので次の値渡し引数更新情報６２に処理を移す。
間接的に呼び出す可能性のある関数が存在しない場合には（Ｓ３４でＮｏ）、各「値渡し引数」について、ループ処理（Ｓ３５）を実行する。ループ処理（Ｓ３５）では、値渡し引数が更新されているかどうかの判定を行なう（Ｓ３６）。値渡し引数が更新されていれば（Ｓ３６でＹｅｓ）、参照渡し変換不可能と判定して、判定結果を値渡し引数更新情報６２の「参照渡し変換判定情報」に記録する（Ｓ３８）。値渡し引数が更新されていなければ（Ｓ３６でＮｏ）、参照渡し変換可能と判定して、判定結果を値渡し引数更新情報６２の「参照渡し変換判定情報」に記録する（Ｓ３７）。
【００３９】
次に、参照変換可能と判定された引数を持つ関数の各直接呼出し関数について、ループ処理（Ｓ３９）を実行する。ループ処理（Ｓ３９）では、値渡し引数による呼び出しを参照渡しによる呼び出しに変換する（Ｓ４０）。
一方、強制的な変換を行なう場合は（Ｓ３１でＹｅｓ）、登録されている値渡し引数更新情報６２のすべての値渡し引数に対して、「参照渡し変換判定情報」に参照渡し変換可能である情報を記録し、値渡し引数による呼び出しを参照渡しによる呼び出しに変換する（Ｓ４１，Ｓ４２，Ｓ４３，Ｓ４４，Ｓ４５）。
【００４０】
以上の処理を実施することで、変換候補となる値渡し引数による呼び出しを参照渡しによる呼び出しに変換することができる。
【００４１】
次に、値渡し関数定義参照渡し変換処理（Ｓ１３）の詳細について説明する。図９は、値渡し関数定義参照渡し変換処理（Ｓ１３）の詳細を示すフローチャートである。図９に示す処理のうち、値渡し引数更新情報６２の「参照渡し変換判定情報」を求めるための処理（Ｓ５１、Ｓ５３、Ｓ５２、Ｓ５４、Ｓ５５、Ｓ５６、Ｓ５７、Ｓ５８、Ｓ６１、Ｓ６２、Ｓ６３）は、図８に示した処理（Ｓ３１、Ｓ３３、Ｓ３２、Ｓ３４、Ｓ３５、Ｓ３６、Ｓ３７、Ｓ３８、Ｓ４１、Ｓ４２、Ｓ４３）と同一の処理であるので説明を省略する。これらは値渡しが参照渡しに変換可能かどうかを値渡し引数更新情報６２に記録する処理である。これらの同一の処理は、コンパイラの最適化処理（Ｓ４）において、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）と値渡し関数定義参照渡し変換処理（Ｓ１３）とのどちらを先に行なっても構わないようにするためである。このため、どちらか一方がすでに実施されて値渡し引数更新情報６２の「参照渡し変換判定情報」がすでに記録されている場合、これらの参照渡しに変換可能かどうかを判定して記録する処理を省略しても構わない。
【００４２】
参照渡しに強制的に変換しない場合で（Ｓ５１でＮｏ）、値渡しが参照渡しに変換可能か否かの判定結果が値渡し引数更新情報６２の「参照渡し変換判定情報」に記録された後では、参照渡し変換可能と判定された引数を持つ関数についてループ処理（Ｓ５９）を行う。ループ処理（Ｓ５９）では、値渡し引数による引数受け渡しを参照渡しによる引数受け渡しに変換する（Ｓ６０）。
【００４３】
一方、強制的な変換を行なう場合で（Ｓ５１でＹｅｓ）、値渡しが参照渡しに変換可能かの判定結果が値渡し引数更新情報６２の「参照渡し変換判定情報」に記録された後では、参照渡し変換可能と判定された引数を持つ関数についてループ処理（Ｓ６４）を行う。ループ処理（Ｓ６４）では、値渡し引数による引数受け渡しを参照渡しによる引数受け渡しに変換する（Ｓ６５）。次に、変換した参照渡し引数について、ループ処理（Ｓ６６）を行う。ループ処理（Ｓ６６）では、値渡し引数が関数定義内で更新されているかどうかの判定結果を「更新判定情報」より調べる（Ｓ６７）。値渡し引数が更新されていれば（Ｓ６７でＹｅｓ）、中間コードにおいて実際に値が更新される部分よりも前に、変換された参照渡し引数から引数値を参照してそのコピーを生成し、さらにそのコピーを参照先に再設定する（Ｓ６８）。この処理は、もともと値渡しによる引数受け渡しであるので関数呼び出し先での引数に対する更新が呼び出し元に反映されてはいけないが、参照渡しによる引数受け渡しに変換した結果、呼び出し元に更新結果が反映されてしまうことを防ぐために行なわれる。つまり、引数に対して更新が行なわれる場合は、従来関数呼び出し元で生成していた引数コピーを関数呼び出し先で生成するようにしていることになる。
【００４４】
このようにすることにより、呼び出す側で一時変数を作ると、呼び出すたびに一時変数を作り出さなければならないが、呼び出される側で一時変数を作ると、一時変数を作成するコードは１箇所にまとめられる。よって、コードサイズを小さくすることができる。
以上の処理を実施することにより、変換候補となる値渡し引数による引数受け渡しを参照渡しによる引数受け渡しに変換することができる。
【００４５】
以上のような値渡し引数更新情報抽出処理（Ｓ１１）、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）および値渡し関数定義参照渡し変換処理（Ｓ１３）と、その他の最適化処理（Ｓ１４）とを含む最適化処理（Ｓ４）を施した中間コードに対して、資源割付処理（Ｓ５）およびオブジェクトプログラム出力処理（Ｓ６）を行なうことにより、最終的に生成されるオブジェクトプログラムのオブジェクトコードのサイズが削減される。
【００４６】
以下、具体例を参照しながら値渡し引数の関数を参照渡し引数の関数に変換する最適化処理についてより詳細に説明する。
（具体例１）
図１０（ａ）は、プログラム記憶部５６に記憶されているヘッダファイルの一例を示し、図１０（ｂ）は、プログラム記憶部５６に記憶されているソースプログラムの一例を示す。以下では、このヘッダファイルおよびソースプログラムを入力した場合のコンパイラの動作を説明する。
【００４７】
図１０（ａ）に示すヘッダファイル「ｓｔｒｕｃｔ．ｈ」には構造体Ａの定義が記載されている。図１０（ｂ）に示すソースプログラム「ｐｒｏｇ１．ｃｃ」にはヘッダファイル「ｓｔｒｕｃｔ．ｈ」の読み込み処理、値渡し引数関数「ｖｏｉｄ  ｆ（Ａ  ｏｂｊ）」の定義、関数ｆを呼び出す関数「ｖｏｉｄ  ｇ（ｖｏｉｄ）」および関数「ｖｏｉｄ  ｈ（ｖｏｉｄ）」の定義が記述されている。
【００４８】
まず従来の方法による具体例を示す。関数ｆは「値渡し引数を持つ関数」であるので、関数ｇや関数ｈから関数ｆを呼び出すときは、引数の受け渡しは値渡しによる方法となる。
【００４９】
図１１は関数ｇから関数ｆを呼び出す場合のスタックフレーム例を示す。図１０（ｂ）に示す関数ｇの定義においては、局所引数ｘを値渡し引数として関数ｆを呼び出している。この場合のスタックフレーム構成は、図１１に示すように、局所変数を確保している領域（関数ｇ実行時のＳＰ（スタックポインタの値）＋１６からＳＰ＋２４）から引数値のコピーが実引数を確保する領域（関数ｇ実行時のＳＰ＋４からＳＰ＋１２）に格納されることになる。関数ｆに実行が移れば、引数へのアクセスは仮引数を確保する領域（関数ｆ実行時のＳＰ＋１６からＳＰ＋２４）に対してアクセスすることで実現される。
【００５０】
図１２は、従来の方法で実施された場合の、関数ｆおよび関数ｇの定義を表すアセンブラコードを示す。関数ｆの定義に示すように、仮引数ｏｂｊ．ｘ，ｏｂｊ．ｙ，ｏｂｊ．ｚの値はそれぞれスタックフレームのＳＰ＋１６、ＳＰ＋２０、ＳＰ＋２４から読み込みを行なっている。また関数ｇの定義に示すように、関数ｆの呼び出しを行なう前に、局所変数領域（ＳＰ＋１６からＳＰ＋２４）から実引数領域（ＳＰ＋４からＳＰ１２）へ値のコピーを実施していることがわかる。
【００５１】
次に、本実施の形態における具体例を示す。まず値渡し引数更新情報抽出処理（Ｓ１１）が実施されると、図１３（ａ）に示す値渡し引数更新情報６２が抽出される。つまり、「値渡し引数を持つ関数」としてｖｏｉｄ  ｆ（Ａ  ｏｂｊ）、「値渡し引数を持つ関数を直接呼び出す関数」としてｖｏｉｄ  ｇ（ｖｏｉｄ）、ｖｏｉｄ  ｈ（ｖｏｉｄ）、「値渡し引数を持つ関数を間接的に呼び出す可能性がある関数」は存在しない、関数ｆで値渡し対象となっている「値渡し引数」は第１引数Ａ  ｏｂｊ、関数定義内で引数の更新はされていないとの情報がが抽出される。
【００５２】
次に、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）が実施されると、関数ｆの値渡し引数「Ａ  ｏｂｊ」は関数定義内で参照はされているものの更新は行なわれていないので、強制的な参照渡しを行うか否かの判定処理（Ｓ３１）の結果に関わらず、図１３（ｂ）に示すように、第１引数の「参照渡し変換判定情報」が「可能」と記録される。よって、値渡し関数呼び出しが参照渡し関数呼び出しに変換される。
【００５３】
値渡し関数定義参照渡し変換処理（Ｓ１３）が実施される場合も同様で、強制的な参照渡しを行うか否かの判定処理（Ｓ５１）の結果に関わらず、結果的に参照渡し変換可能と記録されるので、関数ｆの値渡しによる引数受け渡しが、参照渡しによる関数受け渡しに変換される。
【００５４】
図１４に、値渡し引数を参照渡し引数に変換した場合のスタックフレーム例を示す。実引数領域（関数ｇ実行時のＳＰ＋４）には、引数値ではなく、引数への参照（つまりアドレス）に変更されていることがわかる。このため、スタックの使用領域が削減されていることがわかる。
【００５５】
図１５に、値渡し引数を参照渡し引数に変換した場合の、関数ｆ、関数ｇの定義を表すアセンブラコードを示す。関数ｆの定義に示すように、仮引数は引数値そのものではなく、引数値への参照（つまりアドレス）が渡されているとみなすので、仮引数へのアクセスは仮引数領域（関数ｆ実行時のＳＰ＋１６）に格納されている引数アドレスを経由して行なわれていることがわかる。また、関数ｇの定義に示すように、実引数領域（関数ｇ実行時のＳＰ＋４）に局所変数オブジェクトの先頭アドレス（関数ｇ実行時のＳＰ＋８のアドレス値）が設定されていることがわかる。このように参照渡しによる引数受け渡し方法に変換されているため、従来の方法における具体例を示した図１２のように、引数値のコピーを行なう必要がなくなる。よって、コードサイズが削減できていることがわかる。
【００５６】
（具体例２）
図１６（ａ）は、プログラム記憶部５６に記憶されているヘッダファイルの一例を示し、図１６（ｂ）は、プログラム記憶部５６に記憶されているソースプログラムの一例を示す。以下では、このヘッダファイルおよびソースプログラムを入力した場合のコンパイラの動作を説明する。
【００５７】
図１６（ａ）に示すヘッダファイル「ｃｌａｓｓ．ｈ」にはクラスＡの定義が記載されている。クラスＡには、メンバ変数ｘ，ｙおよびｚと、デフォルトコンストラクタＡ（ｖｏｉｄ）と、コピーコンストラクタＡ（Ａ  ＆ｏｂｊ）とメンバ関数ｇｅｔ＿ｘ，ｇｅｔ＿ｙ，ｇｅｔ＿ｚ，ｓｅｔ＿ｘ，ｓｅｔ＿ｙおよびｓｅｔ＿ｚとが定義されている。図１６（ｂ）に示すソースプログラム「ｐｒｏｇ２．ｃｃ」にはヘッダファイル「ｃｌａｓｓ．ｈ」の読み込み処理、値渡し引数関数「ｖｏｉｄ  ｆ（Ａ  ｏｂｊ）」の定義、関数ｆを呼び出す関数「ｖｏｉｄ  ｇ（ｖｏｉｄ）」および関数「ｖｏｉｄ  ｈ（ｖｏｉｄ）」の定義が記述されている。
【００５８】
まず従来の方法による具体例を示す。具体例１と同様に、関数ｆは「値渡し引数を持つ関数」であるので、関数ｇや関数ｈから関数ｆを呼び出すときは、引数の受け渡しは値渡しによる方法となる。図１７に関数ｇから関数ｆを呼び出す場合のスタックフレーム例を示す。図１０の関数ｇの定義において、局所引数ｘを値渡し引数として関数ｆを呼び出している。局所引数ｘはクラスＡにコピーコンストラクタ（ｃｌａｓｓ．ｈのＡ（Ａ  ＆ｏｂｊ））が定義されているので、値渡しによる引数受け渡しの場合は、暗黙的にコピーコンストラクタ呼び出しによる一時変数（ｔｍｐ．ｘ，ｔｍｐ．ｙおよびｔｍｐ．ｚ）の生成が行なわれる。この場合のスタックフレーム構成は、図１７に示すようになる。すなわち、局所変数を確保している領域（関数ｇ実行時のＳＰ＋２８からＳＰ＋３６）からコピーコンストラクタ呼び出しによって生成される値が、一時変数を格納する領域（関数ｇ実行時のＳＰ＋１６からＳＰ＋２４）に格納される。その後、一時変数（引数値）のコピーが実引数を確保する領域（関数ｇ実行時のＳＰ＋４からＳＰ＋１２）に格納されることになる。関数ｆに実行が移れば、引数へのアクセスは仮引数を確保する領域（関数ｆ実行時のＳＰ＋１６からＳＰ＋２４）に対してアクセスすることで実現される。
【００５９】
図１８に、従来の方法で実施された場合の、関数ｆ、関数ｇの定義を表すアセンブラコードを示す。関数ｆの定義に示すように、仮引数ｏｂｊ．ｘ，ｏｂｊ．ｙ，ｏｂｊ．ｚはそれぞれスタックフレームのＳＰ＋１６、ＳＰ＋２０、ＳＰ＋２４から読み込みを行なっている。また関数ｇの定義に示すように、関数ｆの呼び出しを行なう前に、コピーコンストラクタ呼び出しを行い、コピーコンストラクタ呼び出しにより生成される値を一時変数領域に格納した後、一時変数領域（ＳＰ＋１６からＳＰ＋２４）から実引数領域（ＳＰ＋４からＳＰ１２）へ値のコピーを実施していることがわかる。
【００６０】
次に本実施の形態における具体例を示す。まず値渡し引数更新情報抽出処理（Ｓ１１）が実施されると、図１９（ａ）に示す値渡し引数更新情報６２が抽出される。つまり、「値渡し引数を持つ関数」としてｖｏｉｄ  ｆ（Ａ  ｏｂｊ）、「値渡し引数を持つ関数を直接呼び出す関数」としてｖｏｉｄ  ｇ（ｖｏｉｄ）、ｖｏｉｄ  ｈ（ｖｏｉｄ）、「値渡し引数を持つ関数を間接的に呼び出す可能性がある関数」は存在しない、関数ｆで値渡し対象となっている「値渡し引数」は第１引数Ａ  ｏｂｊ、関数定義内で引数の更新はされていないとの情報が抽出される。
【００６１】
次に、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）が実施されると、関数ｆの値渡し引数「Ａ  ｏｂｊ」は関数定義内で参照はされているものの更新は行なわれていないので、強制的な参照渡しを行なうか否か判定処理（Ｓ３１）の結果に関わらず、図１９（ｂ）に示すように、第１引数の「参照渡し変換判定情報」が「可能」と記録される。よって、値渡し関数呼び出しが参照渡し関数呼び出しに変換される。
【００６２】
値渡し関数定義参照渡し変換処理（Ｓ１３）が実施される場合も同様で、強制的な参照渡しを行なうか否かの判定処理（Ｓ５１）の結果に関わらず、結果的に参照渡し可能と記録されるので、関数ｆの値渡しによる引数受け渡しが、参照渡しによる関数受け渡しに変換される。
値渡しによる引数受け渡しを参照渡しによる受け渡しに変換しているので、スタックフレームは具体例１と同じく図１４に示すようになる。
【００６３】
図１６（ａ）および図１６（ｂ）のプログラム例で示すクラスＡは、図１０（ａ）および図１０（ｂ）で示す構造体Ａとデータ構造が等しい。また、図１９（ｂ）の値渡し引数更新情報６２も図１３（ｂ）と等しくなるので、関数ｆ、関数ｇの定義を表すアセンブラコードは具体例１と同じ図１５に示すようになる。このように参照渡しによる引数受け渡し方法に変換されているため、図１８に示す従来の方法におけるアセンブラコードのように、コピーコンストラクタによる引数値のコピー生成およびコピー値の実引数領域への格納処理を行なう必要がなくなる。このため、コードサイズが削減できていることがわかる。
【００６４】
（具体例３）
図２０（ａ）は、プログラム記憶部５６に記憶されているヘッダファイルの一例を示し、図２０（ｂ）は、プログラム記憶部５６に記憶されているソースプログラムの一例を示す。以下では、このヘッダファイルおよびソースプログラムを入力した場合のコンパイラの動作を説明する。
【００６５】
図２０（ａ）に示すヘッダファイル「ｓｔｒｕｃｔ．ｈ」は、図１０（ａ）に示すヘッダファイル「ｓｔｒｕｃｔ．ｈ」と同じである。また、図２０（ｂ）に示すソースプログラム「ｐｒｏｇ３．ｃｃ」は、図１０（ｂ）に示すソースプログラム「ｐｒｏｇ１．ｃｃ」とほぼ同じであるが、関数ｆの定義において、引数ｏｂｊを更新している（「ｏｂｊ．ｘ  ＝  ｂ；」，「ｏｂｊ．ｙ  ＝  ｃ；」，「ｏｂｊ．ｚ  ＝  ａ；」）点が異なる。この場合のスタックフレーム例は、図１１と同様になる。図２１に、従来の方法で実施された場合の、関数ｆ、関数ｇの定義を表すアセンブラコードを示す。図１２とほぼ同じであるが、関数ｆの定義において、引数ｏｂｊを更新している処理が追加されている。
【００６６】
次に本実施の形態における具体例を示す。まず値渡し引数更新情報抽出処理（Ｓ１１）が実施されると、図２２（ａ）に示す値渡し引数更新情報６２が抽出される。つまり、「値渡し引数を持つ関数」としてｖｏｉｄ  ｆ（Ａ  ｏｂｊ）、「値渡し引数を持つ関数を直接呼び出す関数」としてｖｏｉｄ  ｇ（ｖｏｉｄ）、ｖｏｉｄ  ｈ（ｖｏｉｄ）、「値渡し引数を持つ関数を間接的に呼び出す可能性がある関数」は存在しない、関数ｆで値渡し対象となっている「値渡し引数」は第１引数Ａ  ｏｂｊ、関数定義内で引数の更新はされているとの情報が抽出される。
【００６７】
次に、値渡し関数呼び出し参照渡し変換処理（Ｓ１２）が実施されると、関数ｆの値渡し引数「Ａ  ｏｂｊ」は関数定義内で更新が行なわれているので、強制的な参照渡しの判定（Ｓ３１）で強制変換を行なわないとした場合は、図２２（ｂ）のように第１引数の「参照渡し変換判定情報」が「不可能」と記録され変換が行なわれない。一方、強制変換を行なうとした場合は、図２２（ｃ）に示すように、第１引数の「参照渡し変換判定情報」が「可能」と記録され、値渡し関数呼び出しが参照渡し関数呼び出しに変換される。
【００６８】
値渡し関数定義参照渡し変換処理（Ｓ１３）が実施される場合も同様で、強制的な参照渡しを行なわないとした場合は（Ｓ５１でＮｏ）、「参照渡し変換判定情報」が「不可能」と記録され変換が行われない。一方、強制変換を行なうとした場合は（Ｓ５１でＹｅｓ）、参照渡しへの変換が「可能」と記録され、関数ｆの値渡しによる引数受け渡しが参照渡しによる関数受け渡しに変換される。加えて、値渡しの更新が存在するので図９のＳ６８の処理が実施され、更新処理前に、変換された参照渡し引数から引数値を参照してコピーを生成し、そのコピーが参照先として設定されることになる。
【００６９】
図２３に、値渡し引数が関数定義内で更新されている場合で、強制的に参照渡しに変換する場合のスタックフレーム例を示す。従来の方法における具体例では関数呼び出し元で引数値のコピーが生成されるため、図１７のように関数呼び出し元（つまり関数ｇのアクセス領域）にコピーが確保されているのに対し、本発明では、関数呼び出し先で引数値のコピーが生成されるため、図２３のように関数呼び出し先（つまり関数ｆのアクセス領域）にコピーが確保されているのがわかる。
【００７０】
図２４に、値渡し引数を参照渡し引数に強制的に変換した場合の、関数ｆ、関数ｇの定義を表すアセンブラコードを示す。従来の方法による具体例である図１２では、関数ｇの定義中ならびに関数ｈの定義中でも引数値のコピーを生成して引数受け渡しを行なっているのに対して、本発明では図２４に示すように関数ｇや関数ｈでは引数値へのアドレスを用いた参照での引数受け渡しを実施し、関数ｆの定義中で引数値のコピーを生成して引数値に設定していることがわかる。このように引数値のコピーを呼び出し元の関数から呼び出し先の関数へ移動することで、値渡しの関数呼び出しが発生するたびに引数値のコピーを生成しなればならなかったものを、値渡し関数呼び出し先の一度のコピー生成にまとめることができる。このため、コードサイズを削減できていることがわかる。この効果は関数が呼び出される回数が多ければ多いほど高い。
【００７１】
以上説明したように、本実施の形態によると値渡し引数の関数および当該関数を呼び出す関数を参照渡し引数の関数および当該関数を呼び出す関数に変換している。このため、スタックフレームに引数をコピーする必要がなく、オブジェクトプログラムのコードサイズを小さくすることができる。
以上、本発明の実施の形態に係るコンパイラについて説明したが、本発明は、この実施の形態に限定されるものではない。
【００７２】
例えば、上述の実施の形態では、スタックフレームを用いた引数渡しについての具体例を挙げたが、コンパイル環境に応じては、レジスタなどを用いた引数渡しを使用しても構わない。
【産業上の利用可能性】
【００７３】
本発明にかかるコンパイル方法は、携帯電話やＰＤＡ（Personal Digital Assistant）等のコードサイズの小さなオブジェクトコードを必要とする組み込み機器用のコンパイル方法等に適用可能である。
【図面の簡単な説明】
【００７４】
【図１】本発明の実施の形態に係るコンパイラを実行するコンパイラ装置の外観図である。
【図２】図１に示したコンパイラ装置のハードウェア構成を示すブロック図である。
【図３】本発明の実施の形態に係るコンパイラの処理のフローチャートである。
【図４】値渡し引数更新情報記憶部に記憶されている値渡し引数更新情報の内容を説明するための図である。
【図５】値渡し引数更新情報抽出処理の詳細を示すフローチャートである。
【図６】値渡し関数を間接的に呼び出す可能性のある関数を含むソースプログラムの一例を示す図である。
【図７】値渡し関数を間接的に呼び出す可能性のある関数を含むソースプログラムに対する値渡し引数更新情報の一例を示す図である。
【図８】値渡し関数呼び出し参照渡し変換処理の詳細を示すフローチャートである。
【図９】値渡し関数定義参照渡し変換処理の詳細を示すフローチャートである。
【図１０】具体例１で用いられるプログラム記憶部に記憶されているファイルの一例を示す図であり、（ａ）は、ヘッダファイルの一例を示す図であり、（ｂ）は、ソースプログラムの一例を示す図である。
【図１１】具体例１において引数を値渡しする場合のスタックフレームの一例を示す図である。
【図１２】図１０に示すファイルを従来の方法を用いてコンパイルした場合のアセンブラコードの一例を示す図である。
【図１３】具体例１における値渡し引数更新情報の一例を示す図である。
【図１４】具体例１および具体例２において、引数を参照渡しに変換した後のスタックフレームの一例を示す図である。
【図１５】具体例１および具体例２において、引数を参照渡しに変換した後のアセンブラコードの一例を示す図である。
【図１６】具体例２で用いられるプログラム記憶部に記憶されているファイルの一例を示す図であり、（ａ）は、ヘッダファイルの一例を示す図であり、（ｂ）は、ソースプログラムの一例を示す図である。
【図１７】具体例２において引数を値渡しする場合のスタックフレームの一例を示す図である。
【図１８】図１６に示すファイルを従来の方法を用いてコンパイルした場合のアセンブラコードの一例を示す図である。
【図１９】具体例２における値渡し引数更新情報の一例を示す図である。
【図２０】具体例３で用いられるプログラム記憶部に記憶されているファイルの一例を示す図であり、（ａ）は、ヘッダファイルの一例を示す図であり、（ｂ）は、ソースプログラムの一例を示す図である。
【図２１】図２０に示すファイルを従来の方法を用いてコンパイルした場合のアセンブラコードの一例を示す図である。
【図２２】具体例３における値渡し引数更新情報の一例を示す図である。
【図２３】具体例３において、値渡し引数が関数定義内で更新されている場合に、強制的に参照渡しに変換する場合のスタックフレームの一例を示す図である。
【図２４】具体例３において、値渡し引数が関数定義内で更新されている場合に、強制的に参照渡しに変換する場合のアセンブラコードの一例を示す図である。
【符号の説明】
【００７５】
５６  プログラム記憶部
５８  値渡し引数更新情報記憶部
６０  生成コード記憶部
６２  値渡し引数更新情報
【図１】
0004652680.tif 000002
【図２】
0004652680.tif 000003
【図３】
0004652680.tif 000004
【図４】
0004652680.tif 000005
【図５】
0004652680.tif 000006
【図６】
0004652680.tif 000007
【図７】
0004652680.tif 000008
【図８】
0004652680.tif 000009
【図９】
0004652680.tif 000010
【図１０】
0004652680.tif 000011
【図１１】
0004652680.tif 000012
【図１２】
0004652680.tif 000013
【図１３】
0004652680.tif 000014
【図１４】
0004652680.tif 000015
【図１５】
0004652680.tif 000016
【図１６】
0004652680.tif 000017
【図１７】
0004652680.tif 000018
【図１８】
0004652680.tif 000019
【図１９】
0004652680.tif 000020
【図２０】
0004652680.tif 000021
【図２１】
0004652680.tif 000022
【図２２】
0004652680.tif 000023
【図２３】
0004652680.tif 000024
【図２４】
0004652680.tif 000025