(57)【特許請求の範囲】
【請求項１】
コンピュータを制御して、実行プログラムのソースコードをコンパイルして機械語コードを生成するプログラム変換方法において、
前記コンピュータのプログラム制御されたＣＰＵにより実現される論理レジスタ性質解析手段が、メモリから処理対象である実行プログラムを読み出し、当該実行プログラム中の所定の変数が所定の関数呼び出しを越えて生存するか否かを判断し、かつ当該変数が関数呼び出しを越えて生存する場合に、当該関数呼び出しがコンパイラにて生成された関数の呼び出しか、当該コンパイラにて生成された関数以外の関数である外部関数の呼び出しかを判断するステップと、
前記コンピュータのプログラム制御されたＣＰＵにより実現される物理レジスタ割付手段が、前記判断に基づいて、関数呼び出しを越えて生存しない前記変数を、関数呼び出しが行われるとレジスタ値が破壊される揮発性レジスタに割り付け、前記コンパイラにて生成された関数の呼び出しを越えて生存する前記変数を、関数呼び出しが行われてもレジスタ値が保存される不揮発性レジスタに割り付け、前記外部関数の呼び出しを越えて生存するが前記コンパイラにて生成された関数の呼び出しは越えない前記変数を、前記外部関数の呼び出しが行われてもレジスタ値が保存されるがコンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り付けるステップと、
前記コンピュータのプログラム制御されたＣＰＵにより実現されるコード生成手段が、前記割り付けに基づいて機械語コードを生成し、メモリに格納するステップと
を含むことを特徴とするプログラム変換方法。
【請求項２】
前記論理レジスタ性質解析手段が前記変数の性質を判断するステップは、前記実行プログラム中の各関数が存在するパスの実行頻度を解析するステップを含み、
前記物理レジスタ割付手段が前記変数をレジスタに割り付けるステップは、所定の関数呼び出しを越えて生存する前記変数であっても、当該変数が実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する場合には、当該変数を前記揮発性レジスタに割り付けるステップを含むことを特徴とする請求項１に記載のプログラム変換方法。
【請求項３】
前記コード生成手段が前記機械語コードを生成するステップは、実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する前記変数に関して、レジスタに割り付けられた当該変数を関数呼び出しの前後で退避・復元するコードを付加するステップを含むことを特徴とする請求項２に記載のプログラム変換方法。
【請求項４】
コンピュータを制御して、実行プログラムのソースコードをコンパイルして機械語コードを生成するプログラム変換方法において、
前記コンピュータのプログラム制御されたＣＰＵにより実現される論理レジスタ性質解析手段が、前記実行プログラム中の所定の変数を、
Ａ群：生存区間がコンパイラにて生成された関数であって頻繁に実行される関数を跨ぐ変数と、
Ｂ群：生存区間が頻繁に実行される、前記コンパイラにて生成された関数以外の関数である外部関数を跨ぎ、かつ前記コンパイラにて生成された関数であって頻繁に実行される関数を跨がない変数と、
Ｃ群：その他の変数と
に分類するステップと、
前記コンピュータのプログラム制御されたＣＰＵにより実現される物理レジスタ割付手段が、Ａ群に分類された変数を関数呼び出しが行われてもレジスタ値が保存される不揮発性レジスタに割り当て、Ｂ群に分類された変数を前記外部関数の呼び出しが行われてもレジスタ値が保存されるが前記コンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り当て、Ｃ群に分類された変数を関数呼び出しが行われるとレジスタ値が破壊される揮発性レジスタに割り当てるステップと、
前記コンピュータのプログラム制御されたＣＰＵにより実現されるコード生成手段が、前記割り当てにしたがって、機械語コードを生成し、メモリに格納するステップと
を含むことを特徴とするプログラム変換方法。
【請求項５】
実行プログラムのソースコードを読み込み、機械語コードに変換するデータ処理装置において、
前記実行プログラム中の変数に対して論理レジスタの割付を行う論理レジスタ割付部と、
所定の前記変数が所定の関数呼び出しを越えて生存するか否かを解析し、かつ当該変数が関数呼び出しを越えて生存する場合に、当該関数呼び出しがコンパイラにて生成された関数の呼び出しか、当該コンパイラにて生成された関数以外の関数である外部関数の呼び出しかを解析する、プログラム制御されたＣＰＵにより実現される論理レジスタ性質解析部と、
前記論理レジスタ性質解析部による解析結果に基づいて、関数呼び出しを越えて生存しない前記変数を、関数呼び出しが行われるとレジスタ値が破壊される揮発性レジスタに割り付け、前記コンパイラにて生成された関数の呼び出しを越えて生存する前記変数を、関数呼び出しが行われてもレジスタ値が保存される不揮発性レジスタに割り付け、前記外部関数の呼び出しを越えて生存するが前記コンパイラにて生成された関数の呼び出しは越えない前記変数を、前記外部関数の呼び出しが行われてもレジスタ値が保存されるがコンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り付ける、プログラム制御されたＣＰＵにより実現される物理レジスタ割付部と、
前記物理レジスタ割付部によるレジスタの割付の決定を反映させて機械語コードを生成する、プログラム制御されたＣＰＵにより実現されるコード生成部と
を備えることを特徴とするデータ処理装置。
【請求項６】
前記論理レジスタ性質解析部は、前記実行プログラム中の各関数が存在するパスの実行頻度を解析し、
前記物理レジスタ割付部は、所定の関数呼び出しを越えて生存する前記変数であっても、当該変数が実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する場合には、当該変数を前記揮発性レジスタに割り付け、
前記コード生成部は、実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する前記変数に関して、レジスタに割り付けられた当該変数を関数呼び出しの前後で退避・復元するコードを付加することを特徴とする請求項５に記載のデータ処理装置。
【請求項７】
コンピュータを制御して、所定の実行プログラム中の変数に対してレジスタ割付を行うプログラムであって、
前記実行プログラム中の所定の変数が所定の関数呼び出しを越えて生存するか否かを判断し、かつ当該変数が関数呼び出しを越えて生存する場合に、当該関数呼び出しがコンパイラにて生成された関数の呼び出しか、当該コンパイラにて生成された関数以外の関数である外部関数の呼び出しかを判断する処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される論理レジスタ性質解析手段に実行させ、
前記判断に基づいて、関数呼び出しを越えて生存しない前記変数を、関数呼び出しが行われるとレジスタ値が破壊される揮発性レジスタに割り付け、前記コンパイラにて生成された関数の呼び出しを越えて生存する前記変数を、関数呼び出しが行われてもレジスタ値が保存される不揮発性レジスタに割り付け、前記外部関数の呼び出しを越えて生存するが前記コンパイラにて生成された関数の呼び出しは越えない前記変数を、前記外部関数の呼び出しが行われてもレジスタ値が保存されるがコンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り付ける処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される物理レジスタ割付手段に実行させることを特徴とするプログラム。
【請求項８】
前記論理レジスタ性質解析手段に、前記実行プログラム中の各関数が存在するパスの実行頻度を解析する処理をさらに実行させ、
前記物理レジスタ割付手段に、所定の関数呼び出しを越えて生存する前記変数であっても、当該変数が実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する場合には、当該変数を前記揮発性レジスタに割り付ける処理をさらに実行させ、
前記コンピュータのプログラム制御されたＣＰＵにより実現されるコード生成手段に、実行頻度の低いパスに存在する関数の呼び出しのみを越えて生存する前記変数に関して、レジスタに割り付けられた当該変数を関数呼び出しの前後で退避・復元するコードを付加する処理をさらに実行させることを特徴とする請求項７に記載のプログラム。
【請求項９】
コンピュータを制御して、所定の実行プログラム中の変数に対してレジスタ割付を行うプログラムであって、
前記実行プログラム中の変数のうち、生存区間がコンパイラにて生成された関数を跨がず、かつ当該コンパイラにて生成された関数以外の関数である外部関数を跨ぐ変数を抽出する処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される論理レジスタ性質解析手段に実行させ、
抽出された前記変数を前記外部関数の呼び出しが行われてもレジスタ値が保存されるが前記コンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り当てる処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される物理レジスタ割付手段に実行させることを特徴とするプログラム。
【請求項１０】
コンピュータを制御して、所定の実行プログラム中の変数に対してレジスタ割付を行うプログラムであって、
前記実行プログラム中の所定の変数を、
Ａ群：生存区間がコンパイラにて生成された関数であって頻繁に実行される関数を跨ぐ変数と、
Ｂ群：生存区間が頻繁に実行される、前記コンパイラにて生成された関数以外の関数である外部関数を跨ぎ、かつ前記コンパイラにて生成された関数であって頻繁に実行される関数を跨がない変数と、
Ｃ群：その他の変数と
に分類する処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される論理レジスタ性質解析手段に実行させ、
Ａ群に分類された変数を関数呼び出しが行われてもレジスタ値が保存される不揮発性レジスタに割り当て、Ｂ群に分類された変数を前記外部関数の呼び出しが行われてもレジスタ値が保存されるが前記コンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタに割り当て、Ｃ群に分類された変数を関数呼び出しが行われるとレジスタ値が破壊される揮発性レジスタに割り当てる処理を、前記コンピュータのプログラム制御されたＣＰＵにより実現される物理レジスタ割付手段に実行させることを特徴とするプログラム。
【請求項１１】
前記プログラムは、コンピュータが前記実行プログラムを実行する際に動的（ダイナミック）にコンパイルを行うコンパイラであることを特徴とする請求項１０に記載のプログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、コンピュータプログラムのコンパイルにおいて実行されるレジスタ割付に関する。
【０００２】
【従来の技術】
コンピュータプログラム（以下、単にプログラムと称す）は、複数の関数（メソッド）の集合体として構成される。プログラムをコンパイルする場合、コンパイラは、プログラムを構成するそれぞれの関数に対して同一のレジスタセットを用いてレジスタの割り当てを行う。したがって、プログラムの所定の部分でレジスタの値が関数呼び出しを越えて生存する場合は、そのレジスタ値を一時的にメモリに保存することが必要となる。
【０００３】
ところで、ＣＰＵが提供するレジスタには、関数を越えるとレジスタ値が保持されない揮発性レジスタ（volatile register）と、関数を越えてもレジスタ値が保持される不揮発性レジスタ（non-volatile register）とがある。
そこで、プログラムの所定の部分でレジスタの値が関数呼び出しを越えて生存する場合に、レジスタ値を保存する方法には次の２つの方法がある。
一つは、変数を揮発性レジスタに割り当て、関数呼び出しの前にレジスタを退避し、復帰の後にレジスタを復元する方法、すなわちコーラーメソッド（caller method：呼び出し側メソッド（関数））においてレジスタ値を退避・復元する方法である。
もう一つは、変数を不揮発性レジスタに割り当て、呼び出された関数において、当該レジスタの使用前にレジスタ値を退避し、使用後に退避前のレジスタ値を復元する方法、すなわちコーリーメソッド（callee method：被呼び出し側メソッド（関数））においてレジスタ値を退避・復元する方法である。
【０００４】
不揮発性レジスタと揮発性レジスタの分類は、レジスタ使用慣習として、マシン（ＣＰＵ）の供給者が定めるものである。したがって、ソフトウェアによるシステムの開発者は、この慣習に従って開発を行わなければならない。
従来のシステム開発では、マシンの供給者が定めたレジスタ使用慣習に従い、通常、関数を越えて生存しない変数には揮発性レジスタを割り当て、関数を越えて生存する変数には不揮発性レジスタを割り当てていた。また、インプリメンテーションのバリエーションとしては、関数を越えて生存する変数に揮発性レジスタを割り当てる方式も存在するが、これは、不揮発性レジスタが供給されていない等の特殊な事情がないかぎり合理的な方法とは考えられていない。
【０００５】
【発明が解決しようとする課題】
複数の相互リンク可能なソフトウェアによるシステムがある場合、通常、それぞれのシステムにおいて、上記従来の技術で説明したように、定められた不揮発性レジスタと揮発性レジスタの使用慣習に従ってコード生成を行う。これは、各システムが相互にリンクされる、すなわち相互に関数呼び出しが行われることを前提としている。
ここで、相互リンク可能なシステムの一方がＪＩＴ（Just In Time）コンパイラであるとし、ＪＩＴコンパイラにて生成されたコードとオブジェクト生成等の外部関数との関係を考えると、ＪＩＴコンパイラにて生成されたコードが外部関数を呼び出す場合がほとんどであり、その逆は極めて稀である。このような場合、外部関数で不揮発性レジスタと定められているレジスタの値を、必ずしもＪＩＴコンパイラ内で保存しなければならないとは限らない。
しかしながら、従来は、マシンの供給者により定められた不揮発性レジスタをそのまま固定的に不揮発性レジスタとして使用しているので、本質的には必要とないレジスタ内容の退避・復元が実行されていた。
【０００６】
また、上述したように、関数を越えて生存する変数には通常、不揮発性レジスタが割り当てられる。これは、そのような変数を揮発性レジスタに割り付けるよりも不揮発性レジスタに割り付けたほうが、有利なコードパターンが多く発生すると考えられているからである。すなわち、関数を越えて生存する変数を揮発性レジスタに割り付けた場合、最悪の場合で、その変数が定義されて最後に使用されるまでに呼び出された関数の数だけ退避・復元が必要となるのに対し、不揮発性レジスタに割り付けた場合は、その変数の生存区間の外側で多くても１度だけ退避・復元を行えばよいと言える。
しかしながら、関数を越えて生存する変数が存在しても、その関数が稀にしか呼び出されない場合がある。そして、上記従来の手法では、そのような変数も不揮発性レジスタに割り付けられるため、その変数の生存区間の前後でのレジスタ内容の退避・復元が、ほとんどの場合に無駄になってしまっていた。
【０００７】
そこで、本発明は、関数を越えて生存する変数のレジスタへの割り付を工夫することにより、レジスタの内容の退避・復元を効率的に行い、コンパイル処理の実行効率を向上させることを目的とする。
【０００８】
【課題を解決するための手段】
上記の目的を達成する本発明は、コンピュータを制御して、実行プログラムのソースコードをコンパイルして機械語コードを生成する、次のようなプログラム変換（コンパイル）方法として実現される。すなわち、このプログラム変換方法は、処理対象である実行プログラム中の所定の変数に関して、所定の関数呼び出しを越えて生存するか否かを判断し、この変数が関数呼び出しを越えて生存する場合、さらに、この関数呼び出しがコンパイラにて生成された関数の呼び出しか、外部関数の呼び出しかを判断するステップと、この判断に基づいて、揮発性レジスタ（volatile register）、不揮発性レジスタ（non-volatile register）、または外部関数の呼び出しが行われてもレジスタ値が保存されるがコンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタ（semi-volatile register）のいずれに、この変数を割り付けるかを決定するステップと、この決定に基づいて機械語コードを生成するステップとを含むことを特徴とする。
ここで、この変数の割付先を決定するステップは、所定の変数の生存区間が外部関数の呼び出しのみを越える場合（すなわち、コンパイラにて生成された関数の呼び出しを越えない場合）に、この変数を準揮発性レジスタに割り付けるステップを含む。
【０００９】
また、本発明の他のプログラム変換方法は、実行プログラムを実行した際の、かかる実行プログラムを構成する関数の実行頻度を調べてメモリに格納するステップと、この実行プログラム中の変数に対して、この変数が所定の関数呼び出しを越えて生存する場合に、この関数の実行頻度に応じて、揮発性レジスタまたは不揮発性レジスタのどちらに変数を割り当てるかを決定するステップと、この決定されたレジスタの割り当てを反映して機械語コードを生成するステップとを含むことを特徴とする。
ここで、この変数の割付先を決定するステップは、所定の変数の生存区間が実行頻度の低い関数の呼び出しを越える場合に、この変数を揮発性レジスタに割り付けるステップを含む。
【００１０】
また、本発明のさらに他のプログラム変換方法は、実行プログラムを実行した際の、かかる実行プログラムを構成する関数の実行頻度を調べてメモリに格納するステップと、この実行プログラム中の変数に対して、この変数が所定の関数呼び出しを越えて生存する場合に、この関数の実行頻度に応じて、レジスタに割り付けられた変数を関数呼び出しの前後で退避・復元するコード、またはこの変数を呼び出された関数内で退避・復元するコードのどちらを付加するかを決定するステップと、この決定に基づいて機械語コードを生成し、メモリに格納するステップとを含むことを特徴とする。
ここで、この変数の割付先を決定するステップは、レジスタに割り付けられた所定の変数の生存区間が実行頻度の低い関数の呼び出しを越える場合に、この変数を呼び出された関数内で退避・復元するコードを実行プログラムに付加する処理を含む。
【００１１】
さらにまた、本発明の他のプログラム変換方法は、処理対象である実行プログラム中の所定の変数を、
Ａ群：生存区間がコンパイラにて生成された関数であって頻繁に実行される関数を跨ぐような変数と、
Ｂ群：生存区間が頻繁に実行される外部関数を跨ぎ、かつ前記コンパイラにて生成された関数であって頻繁に実行される関数を跨がないような変数と、
Ｃ群：その他の変数とに分類するステップと、Ａ群に分類された変数を不揮発性レジスタ（non-volatile register）に割り当て、Ｂ群に分類された変数を外部関数の呼び出しが行われてもレジスタ値が保存されるが前記コンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタ（semi-volatile register）に割り当て、Ｃ群に分類された変数を揮発性レジスタ（volatile register）に割り当てるステップと、この割り当てにしたがって、機械語コードを生成するステップとを含むことを特徴とする。
【００１２】
また、上記の目的を達成する本発明は、実行プログラムのソースコードを読み込み、機械語コードに変換する、次のように構成されたデータ処理装置として実現される。すなわち、このデータ処理装置は、実行プログラム中の変数に対して論理レジスタの割付を行う論理レジスタ割付部と、所定の変数が所定の関数呼び出しを越えて生存するか否かを解析し、かつ、この変数が関数呼び出しを越えて生存する場合に、この関数呼び出しがコンパイラにて生成された関数の呼び出しか、外部関数の呼び出しかを解析する論理レジスタ性質解析部と、この解析結果に基づいて、揮発性レジスタ（volatile register）、不揮発性レジスタ（non-volatile register）、または外部関数の呼び出しが行われてもレジスタ値が保存されるがコンパイラにて生成された関数の呼び出しが行われるとレジスタ値が破壊される準揮発性レジスタ（semi-volatile register）のいずれかに、この変数を割り付ける物理レジスタ割付部と、レジスタ割付の決定を反映させて機械語コードを生成するコード生成部とを備えることを特徴とする。
【００１３】
さらに、本発明による他のデータ処理装置は、実行プログラム中の変数に対して、この変数が所定の関数呼び出しを越えて生存する場合に、この関数の実行頻度に応じて、揮発性レジスタ（volatile register）または不揮発性レジスタ（non-volatile register）のどちらかに変数を割り付けるレジスタ割付部と、揮発性レジスタに割り付けられた変数を関数呼び出しの前後で退避・復元するコードを実行プログラムに付加し、前記不揮発性レジスタに割り付けられた変数を呼び出された関数内で退避・復元するコードを実行プログラムに付加するための情報を生成する退避・復元情報生成部と、生成された情報に基づいて機械語コードを生成するコード生成部とを備えることを特徴とする。
【００１４】
さらにまた、本発明は、上述したプログラム変換方法の各ステップに対応する処理をコンピュータに実行させ、またはコンピュータを用いて上記のデータ処理装置の各機能を実現させるプログラム（例えば、ＪａｖａにおけるＪＩＴコンパイラのような、実行プログラムの実行に際して動的（ダイナミック）にコンパイルを行うコンパイラ）として実現することができる。このプログラムは、磁気ディスクや光ディスク、半導体メモリ、その他の記録媒体に格納して配布したり、ネットワークを介して配信したりすることにより提供することができる。
【００１５】
【発明の実施の形態】
以下、添付図面に示す実施の形態に基づいて、この発明を詳細に説明する。
図１は、本実施の形態によるデータ処理方法を実現するコンピュータシステムのシステム構成を示す図である。
図１を参照すると、本実施の形態におけるコンピュータシステムは、ソースプログラム（入力コード）をコンパイルするコンパイラ１００と、コンパイラ１００にてコンパイルされたオブジェクトプログラム（出力コード）を実行して種々の処理を行うプログラム実行部２００と、メモリ３００とを備える。コンパイラ１００及びプログラム実行部２００は、パーソナルコンピュータやワークステーションなどのコンピュータシステムにおけるプログラム制御されたＣＰＵにて実現される。メモリ３００は、コンピュータ装置のメインメモリであり、ＲＡＭ等で実現される。メモリ３００には、ＣＰＵを制御してコンパイラ１００として動作させるためのプログラムやコンパイルの対象のプログラムが格納されると共に、コンパイラ１００のコンパイル処理において、レジスタから退避される変数が一時的に格納される。なお、メモリ３００に格納されるプログラムは、必要に応じて、適宜磁気ディスクその他の外部記録装置に保存されることは言うまでもない。
【００１６】
図１において、コンパイラ１００は、バイトコード（byte code）で記述された入力コードを入力して処理し、機械語で記述された出力コードを生成して出力する。この入力コードの入力は、コード生成装置４００にて生成された入力コードを直接入力したり、コード生成装置４００にて生成された入力コードを記憶した記憶装置５００から入力したり、ネットワーク６００上に存在するコード生成装置４００や記憶装置５００からネットワーク６００を介して入力したりすることにより行われる。コンパイラ１００により生成された出力コードは、プログラム実行部２００により実行される。
なお、本実施の形態において、コンパイラ１００は、ＪａｖａにおけるＪＩＴコンパイラのような、実行プログラムを実行する際に動的に実行プログラムのコンパイル処理を行うコンパイラである。以下、本実施の形態では、ＪａｖａのＪＩＴコンパイラを例として説明する。また、プログラム実行部２００は、コンパイラ１００にてコンパイルされた実行プログラムのオブジェクトコード（機械語コード）を実行するほか、当該実行プログラムをインタープリタによっても実行する。そして、実行プログラムを実行した際に、その実行プロファイル（以下、単にプロファイル）を取得してメモリ３００に蓄積する。
【００１７】
図２は、本実施の形態におけるコンパイラ１００の構成を説明する図である。図２を参照すると、コンパイラ１００は、コンパイルの対象であるプログラムに対して論理レジスタの割付を行う論理レジスタ割付部１１０と、各論理レジスタに関して、割り付けられた変数の生存区間がどのように関数を跨いでいるかを解析する論理レジスタ性質解析部１２０と、論理レジスタ性質解析部１２０による解析結果に基づき論理レジスタと物理レジスタのマッピングを行う物理レジスタ割付部１３０と、物理レジスタ割付部１３０によるマッピングの結果に基づき、各物理レジスタにおいてどのような退避・復元を実行するかについての情報を生成する退避・復元情報生成部１４０と、退避・復元情報生成部１４０により生成された情報を反映させてオブジェクトコードを生成するコード生成部１５０とを備える。
【００１８】
図２に示したコンパイラ１００の各構成要素は、コンピュータプログラムにより制御されたＣＰＵにて実現される仮想的なソフトウェアブロックである。ＣＰＵを制御する当該コンピュータプログラムは、ＣＤ−ＲＯＭやフロッピーディスクなどの記録媒体に格納して配布したり、ネットワークを介して伝送したりすることにより提供される。
なお、図２に示したコンパイラ１００の構成要素は、本実施の形態における特徴的な機能に関するものである。図示しないが、コンパイラ１００は、実際には、入力コードの字句解析や構文解析、各種の最適化処理といったコンパイル処理における一般的な機能を有することは言うまでもない。
【００１９】
本実施の形態では、プログラムにおける変数が関数呼び出しを越えて生存する場合に、レジスタ値である当該変数の退避・復元を効率的に行うため、次に説明する二つの手法にて変数のレジスタへの割付を行う。一つは、本実施の形態にて定義される準揮発性レジスタを用いる手法、もう一つは、変数を用いる関数の呼び出し頻度を考慮する手法である。
【００２０】
１．準揮発性レジスタを用いる手法
・準揮発性レジスタの導入
ＪａｖａのＪＩＴコンパイラなどで行われる動的なコンパイル処理（Dynamic Compilation）では、コンパイラ１００は、プログラムの実行中にオブジェクトコードを動的に生成し、当該プログラムの実行中だけ使用する。従って、外部関数からの呼び出しがあったかどうかを完全に把握できるため、外部関数からの呼び出し点で不揮発性レジスタを退避しておけば、コンパイラ１００が生成したコードの中では、その不揮発性レジスタを自由に揮発性レジスタに変更できる。プログラムの定常実行状態では、外部関数からの呼び出しはほとんど無いため、不揮発性レジスタを揮発性レジスタに変更することの不都合は事実上無いと言ってよい。
【００２１】
そこで、マシンで定められている不揮発性レジスタの一部を、コンパイラ１００が生成したコード内では揮発性レジスタとして使用する。ここでは、そのように用いられるレジスタを準揮発性レジスタ（semi-volatile register）と呼称する。準揮発性レジスタは、次のように扱われる。
（１）定められた不揮発性レジスタの中からコンパイラ１００が生成したコード内で揮発性レジスタとして使用する準揮発性レジスタを決定する。その個数は不揮発性レジスタの数を超えない限りいくつでもよい。
（２）コンパイラ１００にて生成されたコードが外部から呼び出されるポイントでは、準揮発性レジスタを退避する。例えば、インタープリタとコンパイラとが混在する実行環境（mixed-mode execution環境）では、コンパイラ１００にて生成されたコードをインタープリタが呼び出すときに準揮発性レジスタの内容を退避する。
【００２２】
図３は、インタープリタとコンパイラとが混在する実行環境での関数呼び出しの様子を示す図である。
図３において、準揮発性レジスタは、コンパイラ１００にて生成されたコード（図ではＪＩＴ関数と記載）内では揮発性レジスタとして扱われ、インタープリタ及び外部関数の実行においては不揮発性レジスタとして扱われる。コンパイラ１００にて生成されたコードが外部関数を呼び出す場合には、直接関数呼び出しが行われるが、外部関数がコンパイラ１００にて生成されたコードを呼び出す場合には、インタープリタ及びJIT Invokerを介して関数呼び出しが行われるため、ここで準揮発性レジスタの内容が退避される。
【００２３】
・準揮発性レジスタを用いたレジスタ内容の退避・復元回数の削減
図４は、レジスタの種類と性質を示す図表である。
図４に示すように、準揮発性レジスタの導入により、レジスタの種類は揮発性レジスタ、準揮発性レジスタ、不揮発性レジスタの３種類となる。これらのレジスタを、プログラム中の変数の種類に応じて使い分ける。すなわち、プログラムの解析により、変数を、生存区間が関数を跨がないものと、生存区間がコンパイラ１００にて生成された関数を跨ぐものと、生存区間が外部関数を跨ぐがコンパイラ１００にて生成された関数は跨がないものとに分ける。このうち、生存区間が関数を跨がない変数には揮発性レジスタを割り当て、生存区間がコンパイラ１００にて生成された関数を跨ぐものには不揮発性レジスタを割り当てるのは、これまで通りである。そして、生存区間が外部関数を跨ぐがコンパイラ１００にて生成された関数は跨がない変数を準揮発性レジスタに割り当てる。
【００２４】
図５は、生存区間が外部関数を跨ぐがコンパイラ１００にて生成された関数は跨がない変数に関して必要となるレジスタ内容の退避・復元を説明する図である。
生存区間が外部関数を跨ぐがコンパイラ１００にて生成された関数は跨がない変数を準揮発性レジスタに割り当てることにより、図５に示すように、当該変数については、コンパイラ１００にて生成されたコード内では、レジスタ内容の退避・復元を伴わずにレジスタ割り当てできるようになる。一方、従来のレジスタ割付では、そのような変数を揮発性レジスタに割り当てた場合、関数呼び出し前後のレジスタ内容の退避・復元が必要であり、また、不揮発性レジスタに割り当てた場合はレジスタ使用前後の退避・復元が必要であった。
したがって、かかるレジスタ内容の退避・復元を削減することにより、コンパイル処理の実行効率が向上する。
【００２５】
２．変数を用いる関数の呼び出し頻度を考慮する手法
生存区間が関数を跨ぐ変数に対しては、不揮発性レジスタを割り当てる方が有利なコードパターンが多く発生すると考えられることから、通常、この種の変数には不揮発性レジスタが割り当てられている。しかし、稀にしか呼ばれない関数を跨ぐ変数に不揮発性レジスタを割り当ててしまうと、その変数の生存区間の前後におけるレジスタ内容の退避・復元が無駄になってしまう。
そこで、所定の変数に関し、プロファイル等の情報を利用して、当該変数が跨ぐ関数の呼び出しが稀に実行されるものであるかどうかを判断し、判断結果に応じて割り当てるレジスタを選択する。
【００２６】
すなわち、変数が跨ぐ関数の全てが稀にしか実行されない場合、その変数を揮発性レジスタに割り当て、関数呼び出しの前にレジスタ内容を退避し、復帰の後に退避前のレジスタ内容を復元する（コーラーメソッドによるレジスタ値の退避・復元）。
一方、変数が跨ぐ関数のうち、１つでも頻繁に実行されるものがある場合は、その変数を不揮発性レジスタに割り当て、そのレジスタの使用前にレジスタ内容を退避し、使用後に退避前のレジスタ内容を復元する（コーリーメソッドによるレジスタ値の退避・復元）。
【００２７】
図６は、関数の実行頻度に応じたレジスタの割り当てによるレジスタ内容の退避・復元を説明する図である。
図６に示すように、関数の実行頻度を考慮することにより、稀にしか実行されない関数を跨ぐレジスタ値の復元・退避が行われる位置は、そのレジスタの生存区間の前後から生存区間が跨ぐ関数の前後に変更される。この関数は稀にしか実行されないので、その関数の前後の復元・退避も稀にしか行われない。すなわち、事実上、レジスタ内容の退避・復元のコストが削減されることになる。
【００２８】
上述した１．２．の手法を統合すると、プログラム中の関数が割り付けられるレジスタを選択するには、次の基準が必要であることがわかる。すなわち、
（１）変数の生存区間がコンパイラ１００にて生成された関数（コード）を跨ぐか。
（２）変数の生存区間が外部関数を跨ぐか。
（３）変数の生存区間が跨ぐ関数自体の呼び出しの発生頻度。
これらの基準のさまざまな組み合わせを考慮した上で、本実施の形態では、割り当てるレジスタを決定するための変数の範疇を以下の３つと定める。
Ａ群：生存区間がコンパイラ１００にて生成された関数を頻繁に実行されるパスで跨ぐことがある変数
Ｂ群：生存区間が、外部関数を頻繁に実行されるパスで跨ぐことがあり、かつコンパイラ１００にて生成された関数を頻繁に実行されるパスで跨ぐことがない（コンパイラ１００にて生成された関数を全て稀にしか実行されないパスで跨ぐか、もしくは全く跨がない）変数
Ｃ群：その他の（全ての関数を稀にしか実行されないパスのみで跨ぐか、もしくは全く跨がない）変数
【００２９】
次に、本実施の形態で提案した上記の手法を、図１、図２に示したコンパイラ１００にて実現する場合の、各構成要素の動作について説明する。
図２に示したコンパイラ１００の構成において、論理レジスタ割付部１１０は、メモリ３００から読み出されて構文解析などの前処理が行われたプログラムに対して、従来と同様の方法で論理レジスタの割付を行う。また、コード生成部１５０は、従来と同様の方法でオブジェクトコードの生成を行い、生成されたオブジェクトコードをメモリ３００に格納する。
【００３０】
論理レジスタ性質解析部１２０は、次のようにして、各論理レジスタに関して、割り付けられた変数の生存区間がどのように関数を跨いでいるかを解析する。図７は、論理レジスタ性質解析部１２０による解析処理の動作を説明するフローチャートである。
特に図示しないが、プログラム実行部２００によりコンパイル対象であるプログラムがインタープリタやコンパイル処理を経て実行された際に、そのプロファイルが取得されてメモリ３００に格納されているものとする。
図７を参照すると、論理レジスタ性質解析部１２０は、まず全ての関数に関して、メモリ３００に格納されているプロファイル等の情報を取得し、この情報を利用して、その関数が存在するパスの実行頻度（稀にしか実行されないパスか、頻繁に実行されるパスか）を解析する（ステップ７０１）。そして、全ての論理レジスタに対して順次以下の処理を実行する（ステップ７０２）。
【００３１】
まず、着目中の論理レジスタに対して、その論理レジスタの生存区間が、コンパイラ１００が生成する関数を、頻繁に実行されるパスで跨ぐかどうかを判定する（ステップ７０３）。もしそうであるならば、当該論理レジスタをＡ群に分類する（ステップ７０４）。
次に、その論理レジスタの生存区間が、外部関数を頻繁に実行されるパスで跨ぐかどうかを判定する（ステップ７０５）。もしそうであるならば、当該論理レジスタをＢ群に分類する（ステップ７０６）。
そしてさらに、その論理レジスタの生存区間が、全ての関数を稀にしか実行されないパスで跨ぐか、またはまったく関数を跨いでいないならば、当該論理レジスタをＣ群に分類する（ステップ７０７）。なお、論理レジスタの性質上、Ａ、Ｂ、Ｃ群のいずれかに当てはまることが保証されている。
以上の処理が全ての論理レジスタに対して行われたならば、論理レジスタ性質解析部１２０の処理を終了する（ステップ７０２）。
【００３２】
物理レジスタ割付部１３０は、論理レジスタ性質解析部１２０による解析結果に基づいて、論理レジスタと物理レジスタのマッピングを行う。
図８は、物理レジスタ割付部１３０によるマッピング処理の動作を説明するフローチャートである。
図８を参照すると、物理レジスタ割付部１３０は、各論理レジスタに対して、順次以下の処理を実行する（ステップ８０１）。
まず、着目中の論理レジスタに対して、その論理レジスタがＡ群に分類されているならば、その論理レジスタを不揮発性レジスタに割り付ける（ステップ８０２、８０３）。
次に、その論理レジスタがＢ群に分類されているならば、その論理レジスタを準揮発性レジスタに割り付ける（ステップ８０４、８０５）。
そしてさらに、その論理レジスタがＣ群に分類されているならば、その論理レジスタを揮発性レジスタに割り付ける（ステップ８０６）。
以上の処理が全ての論理レジスタに対して行われたならば、物理レジスタ割付部１３０の処理を終了する（ステップ８０１）。
【００３３】
退避・復元情報生成部１４０は、物理レジスタ割付部１３０によるマッピングの結果に基づいて、各物理レジスタにおいてどのような退避・復元を実行するかについての情報を生成する。
図９は、退避・復元情報生成部１４０による情報生成処理の動作を説明するフローチャートである。
図９を参照すると、退避・復元情報生成部１４０は、物理レジスタ割付部１３０にて割り付けが行われた各物理レジスタに対して、順次以下の処理を実行する（ステップ９０１）。
まず、着目中の物理レジスタに対して、その物理レジスタが不揮発性レジスタであれば、コンパイル対象となっているメソッドの入口に、その物理レジスタの内容をメモリに退避することを表す情報を付加し、出口にその物理レジスタの内容をメモリから復元することを表す情報を付加する（ステップ９０２、９０３）。
次に、その物理レジスタが準揮発性レジスタまたは揮発性レジスタであれば、その物理レジスタに割り付けられている変数の生存区間が跨ぐ各関数に対して、その関数を呼び出す関数呼び出しの前にその論理レジスタの内容をメモリに退避することを表す情報を付加し、関数呼び出しの後にその論理レジスタの内容をメモリから復元することを表す情報を付加する（ステップ９０４）。
以上の処理が全ての論理レジスタに対して行われたならば、退避・復元情報生成部１４０の処理を終了する（ステップ９０１）。この後、退避・復元情報生成部１４０にて生成された情報に基づき、コード生成部１５０によるオブジェクトコードの生成処理において、実際の退避・復元コードが生成される。
【００３４】
【発明の効果】
以上説明したように、本発明によれば、レジスタの内容の退避・復元を効率的に行い、コンパイル処理の実行効率を向上させることができる。
【図面の簡単な説明】
【図１】  本実施の形態によるデータ処理方法を実現するコンピュータシステムのシステム構成を示す図である。
【図２】  本実施の形態におけるコンパイラの構成を説明する図である。
【図３】  インタープリタとコンパイラとが混在する実行環境での関数呼び出しの様子を示す図である。
【図４】  本実施の形態において用いられるレジスタの種類と性質を示す図表である。
【図５】  生存区間が外部関数を跨ぐがコンパイラにて生成された関数は跨がない変数に関して必要となるレジスタ内容の退避・復元を説明する図である。
【図６】  関数の実行頻度に応じたレジスタの割り当てによるレジスタ内容の退避・復元を説明する図である。
【図７】  論理レジスタ性質解析部による解析処理の動作を説明するフローチャートである。
【図８】  物理レジスタ割付部によるマッピング処理の動作を説明するフローチャートである。
【図９】  退避・復元情報生成部による情報生成処理の動作を説明するフローチャートである。
【符号の説明】
１００…コンパイラ、１１０…論理レジスタ割付部、１２０…論理レジスタ性質解析部、１３０…物理レジスタ割付部、１４０…退避・復元情報生成部、１５０…コード生成部、２００…プログラム実行部、３００…メモリ
【図１】
0003871312.tif 000002
【図２】
0003871312.tif 000003
【図３】
0003871312.tif 000004
【図４】
0003871312.tif 000005
【図５】
0003871312.tif 000006
【図６】
0003871312.tif 000007
【図７】
0003871312.tif 000008
【図８】
0003871312.tif 000009
【図９】
0003871312.tif 000010