(57)【特許請求の範囲】
【請求項１】
変換処理対象コードを機械語コードへ変換するコード変換装置において、
所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目手段、
各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目手段、
ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出手段、
前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出手段、
相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算手段、
各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算手段、
相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定手段、
前記判定手段の判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定手段、
ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成手段、及び
プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成手段、
を有していることを特徴とするコード変換装置。
【請求項２】
前記変換処理対象コードはJavaのバイトコードであることを特徴とする請求項１記載のコード変換装置。
【請求項３】
前記コード変換装置はJITコンパイラであることを特徴とする請求項１記載のコード変換装置。
【請求項４】
前記第１及び前記第２の機械語コード部分生成手段は、前記機械語コード部分Ｈ１，Ｈ２を、前記イテレーションＢaを実行する機械語コード範囲に配置することを特徴とする請求項１記載のコード変換装置。
【請求項５】
機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換装置において、
前記第１の機械語コード部分生成手段は、前記機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、前記機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成手段は、前記機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、前記機械語コード部分Ｈ２を生成する、
ことを特徴とする請求項１記載のコード変換装置。
【請求項６】
ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成するグラフ生成手段、
を有し、
前記第１及び前記第２の着目手段は、前記ポインタ参照ロード命令及び前記データ依存ロード命令をロード依存グラフに基づき検出することを特徴とする請求項１記載のコード変換装置。
【請求項７】
ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについてバイトコードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録するアドレス記録手段、
を有し、
前記第１及び第２の検出手段は、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する、
ことを特徴とする請求項６記載のコード変換装置。
【請求項８】
データＵb,2のプリフェッチが有意義か否かを予測する予測手段、
前記予測手段が有意義でないと予測した場合には、前記第１及び前記第２の機械語生成手段による前記機械語コード部分Ｈ１，Ｈ２の生成を中止させる中止手段、
を有していることを特徴とする請求項１記載のコード変換装置。
【請求項９】
データＵb,2をロードするデータ依存ロード命令を対象データ依存ロード命令、該対象データ依存ロード命令と呼ぶことにし、
前記予測手段は、データＵb,2にデータ依存する命令が存在する場合、及び／又は対象データ依存ロード命令とは別のデータ依存ロード命令がロードするデータＸに対して該データＸ用の機械語コード部分Ｈ２がすでに生成されていてデータＵb,2はデータＸとは同一のキャッシュラインには入らない場合、プリフェッチ命令の挿入が有意義と予測することを特徴とする請求項８記載のコード変換装置。
【請求項１０】
式：Ｕa,0＋ｐ・Ｆｘに基づきアドレス（Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ３を生成する第３の機械語コード部分生成手段、及び
キャッシュラインのサイズＦｓとしてＦｓ≧が２・Ｆｘであるならば前記第３の機械語コード部分生成手段による機械語コード部分Ｈ３の生成は中止とする制御手段、
を有していることを特徴とする請求項１記載のコード変換装置。
【請求項１１】
変換処理対象コードを機械語コードへ変換するコード変換方法において、
コンピュータが、所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目ステップ、
コンピュータが、各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目ステップ、
コンピュータが、ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出ステップ、
コンピュータが、前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出ステップ、
コンピュータが、相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算ステップ、
コンピュータが、各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算ステップ、
コンピュータが、相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定ステップ、
コンピュータが、前記判定ステップにおける判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定ステップ、
コンピュータが、ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成ステップ、及び
コンピュータが、プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成ステップ、
を有していることを特徴とするコード変換方法。
【請求項１２】
前記変換処理対象コードはJavaのバイトコードであることを特徴とする請求項１１記載のコード変換方法。
【請求項１３】
前記コード変換方法はJITコンパイラであることを特徴とする請求項１１記載のコード変換方法。
【請求項１４】
前記第１及び前記第２の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ１，Ｈ２を、前記イテレーションＢaを実行する機械語コード範囲に配置することを特徴とする請求項１１記載のコード変換方法。
【請求項１５】
機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換方法において、
前記第１の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、前記機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、前記機械語コード部分Ｈ２を生成する、
ことを特徴とする請求項１１記載のコード変換方法。
【請求項１６】
コンピュータが、ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成するグラフ生成ステップ、
を有し、
前記第１及び前記第２の着目ステップでは、前記ポインタ参照ロード命令及び前記データ依存ロード命令をロード依存グラフに基づき検出することを特徴とする請求項１１記載のコード変換方法。
【請求項１７】
コンピュータが、ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについてバイトコードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録するアドレス記録ステップ、
を有し、
前記第１及び第２の検出ステップでは、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する、
ことを特徴とする請求項１６記載のコード変換方法。
【請求項１８】
コンピュータが、データＵb,2のプリフェッチが有意義か否かを予測する予測ステップ、及び
コンピュータが、前記予測ステップにおいて有意義でないと予測した場合には、前記第１及び前記第２の機械語生成ステップにおける前記機械語コード部分Ｈ１，Ｈ２の生成を中止させる中止ステップ、
を有していることを特徴とする請求項１１記載のコード変換方法。
【請求項１９】
データＵb,2をロードするデータ依存ロード命令を対象データ依存ロード命令、該対象データ依存ロード命令と呼ぶことにし、
前記予測ステップでは、データＵb,2にデータ依存する命令が存在する場合、及び／又は対象データ依存ロード命令とは別のデータ依存ロード命令がロードするデータＸに対して該データＸ用の機械語コード部分Ｈ２がすでに生成されていてデータＵb,2はデータＸとは同一のキャッシュラインには入らない場合、プリフェッチ命令の挿入が有意義と予測することを特徴とする請求項１８記載のコード変換方法。
【請求項２０】
コンピュータが、式：Ｕa,0＋ｐ・Ｆｘに基づきアドレス（Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ３を生成する第３の機械語コード部分生成ステップ、及び
コンピュータが、キャッシュラインのサイズＦｓとしてＦｓ≧が２・Ｆｘであるならば前記第３の機械語コード部分生成ステップにおける機械語コード部分Ｈ３の生成は中止とする制御ステップ、
を有していることを特徴とする請求項１１記載のコード変換方法。
【請求項２１】
請求項１〜１０のいずれかに記載のコード変換装置の各手段としてコンピュータを機能させるためのコード変換用プログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、Java（Javaは登録商標）のバイトコード等を機械語コードへ変換するコード変換装置、コード変換方法、JITコンパイラ、JITコンパイル方法及びプログラムに係り、詳しくは適切なプリフェッチを組み込んだ機械語コードを生成するコード変換装置、コード変換方法及びプログラム、並びにヒープメモリ内のデータ構造に基づき適切な機械語コードを生成するJITコンパイラ、JITコンパイル方法及びプログラムに関するものである。
【０００２】
【従来の技術】
最初に、Java Just-In-Time(以下JIT)コンパイラについて説明する。
【０００３】
Javaとは、サン・マイクロシステムズ社(Sun Microsystems Inc.)によって開発されたオブジェクト指向のプログラミング言語である。Javaプログラミング言語で記述されたプログラムは、Javaバイトコードコンパイラによってバイトコード(bytecode)と呼ばれる形式のプログラムに変換され、Java仮想計算機(Java virtual machine; JVM)によって実行される。Java仮想計算機は、実際の計算機上で稼動するプログラムであり、計算機毎のプロセッサおよびオペレーティングシステムの違いを吸収して、単一のJavaプログラミング言語による実行環境を異なる種類の計算機上で提供する。
【０００４】
バイトコード形式のプログラムは、Java仮想計算機が稼動するいかなる計算機においても実行することができる。しかし、Java仮想計算機はバイトコードを1命令ずつ解釈して実行するため、プログラムの実行が遅いという問題がある。特に、同じプログラムをCやC++などのプログラミング言語で記述したものと実行時間を比較すると、著しく実行速度が遅い。なぜならば、これらの言語では、コンパイラによってプログラムを予め実際の計算機上で稼動する機械語命令形式に変換してから実行するからである。この問題に対して、Java仮想計算機はバイトコードの実行中に、バイトコード形式のプログラムを機械語命令形式のプログラムにコンパイルし、得られた機械語命令形式のプログラムを実際の計算機上で直接実行することでプログラムの実行速度を向上する。 このように、バイトコードから機械語への変換をプログラムの実行時に行うコンパイラを、Java JITコンパイラと呼ぶ。この方式は、プログラムの実行中にJITコンパイルを行うため、プログラムの実行時間に加えてJITコンパイルの時間が必要になるが、機械語形式による実行が高速であるため、Java仮想計算機のみによるバイトコードの実行より遥かに高速である。一般にJava JITコンパイラは、Javaプログラミング言語における手続きであるメソッド(method)を単位として、Javaプログラムがメソッドを呼び出す直前にJITコンパイルを行う。また、JITコンパイルにかかる時間を減らすため、Java仮想計算機はプログラム中で頻繁に実行されるメソッドだけをJITコンパイルする。
【０００５】
次に、JITコンパイラが生成した機械語命令形式のプログラムにおける、キャッシュメモリへのプリフェッチ命令の利用について説明する。
【０００６】
近年のプロセッサでは、演算の実行が主記憶の参照に比べて著しく高速であるため、プロセッサが頻繁に使用するデータの一部をプロセッサ内の高速だが容量が限られているキャッシュメモリに格納する。ロード命令が読み出すアドレス(address; メモリ上の番地)がキャッシュメモリ内に存在する場合は、ロード命令は高速に実行される。ロード命令が読み出すアドレスがキャッシュメモリ内に存在しない場合は、最近参照されていないアドレスがキャッシュメモリから追い出され、代わりに今参照されたアドレスがキャッシュメモリ内に読み込まれるまで、ロード命令の実行は遅延される。これをキャッシュミス(cache miss)と呼ぶ。
【０００７】
プログラムが同じメモリアドレスを繰り返し参照する場合にはキャッシュメモリによるメモリ参照の高速化の効果が大きいが、プログラムが次々と異なるアドレスを参照する場合には、頻繁にキャッシュミスが発生し、キャッシュメモリによるメモリ参照の高速化の効果が小さくなる。この問題に対して、近年のプロセッサはプリフェッチ命令を提供している。プリフェッチ命令はメモリ参照を行う機械語命令で、参照されたメモリがキャッシュメモリ内に存在しない場合は、通常のロード命令と同様、主記憶からキャッシュメモリへのメモリ内容の読み込みを行う。しかし、プリフェッチ命令は読み出された結果をプロセッサに返さないため、プリフェッチ命令の実行は他の命令を遅延することがない。プリフェッチ命令をロード命令より充分先に実行しておくことで、ロード命令を実行するときのキャッシュミスを防ぐことができる。
【０００８】
Java仮想計算機が、配列(array)やオブジェクト(object)などのJavaプログラムで使用されるデータ構造を格納するメモリの領域を、ヒープメモリ(heap memory)と呼ぶ。Java仮想計算機がバイトコード形式のプログラムを実行する場合も、Java JITコンパイラによって生成された機械語命令形式のプログラムを実行する場合のいずれも、データ構造は同一のヒープメモリ上に生成される。Javaプログラムでは、配列やオブジェクトが頻繁に生成されるため、メモリ参照の割合が多い。したがってJavaプログラムの実行を高速化するには、キャッシュミスによる性能低下を防ぐことが重要である。その際、JITコンパイラが生成する機械語命令形式のプログラム中に、ヒープ上のアドレスに対するプリフェッチ命令を挿入することで、配列やオブジェクト中のデータに対するロード命令が実行されるときのキャッシュミスを防ぐことができる。
【０００９】
プリフェッチングは、キャッシュミスが頻繁に発生するプログラムを高速化するための有効な手段である。多くの数値計算プログラムは、巨大なベクトルや行列を参照するためキャッシュミスの頻度が高いが、Javaなど近年のオブジェクト指向プログラミング言語においても、大量のオブジェクトがヒープメモリ上に生成されるため、それらを参照する際にキャッシュミスが頻繁に発生する。プリフェッチングを用いてプログラムを高速化するためには、以下の三点に注意する必要がある。第一に、プリフェッチ命令とデータを実際に参照するロード命令の間隔を適切に選ぶ必要がある。プリフェッチ命令の実行が遅すぎると、ロード命令が実際にデータを参照する時に、キャッシュメモリ上にデータが間に合わない可能性がある。プリフェッチ命令の実行が早すぎると、ロード命令が実際にデータを参照する前に、プリフェッチされたデータがキャッシュメモリから追い出されてしまう可能性がある。第二に、プリフェッチ命令はメモリ参照を行うので、プログラムの実行中にプロセッサと主記憶の間のデータ転送能力に余裕がない場合は性能低下を招く可能性がある。第三に、プリフェッチされるアドレスの計算のオーバーヘッド(overhead; 余分な手間)をできるだけ軽減する必要がある。
【００１０】
従来、配列参照を対象とするプリフェッチングについては、有効なアルゴリズムが数多く開発されてきた（例：非特許文献１）。しかし、ポインタ参照を対象とするプリフェッチングは、プリフェッチされるアドレスを計算するためにポインタ参照が必要になるため、有効なアルゴリズムを開発することが困難であった（例：非特許文献２，３）。例として、リスト(list)構造を先頭から辿るループ(loop; プログラム中の繰り返し)について考える。ループの第i番目のイテレーション(iteration; ループ中の命令全体の第i回目の繰り返し)において、第i+c番目のイテレーションで参照されるリストの要素をプリフェッチするためには、c回のポインタ参照を行わなければプリフェッチされるアドレスを計算することができない。
【００１１】
これに対して近年、配列参照とポインタ参照を統一的に扱うことができるプリフェッチングアルゴリズムが提案されている（例：非特許文献４，５）。非特許文献４，５は、Javaではなく、C言語に関するものである。非特許文献４，５の著作者はユフォン・ウ（Youfeng Wu）及びその他であるので、以降、非特許文献４，５に開示されている技術内容については「Wuら」と著作者名で特定することにする。Wuらの手法は、ポインタ参照を行うロード命令によるロードデータのアドレスが、連続したイテレーションにおいてしばしば定数ストライド(stride; 幅)の増減（注：増だけでなく、減もあり得る。）をするという観測に基づく。例として、再びリストを先頭から辿るループについて考える。もし、プログラムがリストの各要素を先頭から順番にヒープメモリ上にアロケート(allocate; 場所を確保)し、各要素の大きさがほぼ同じであったとすれば、リストを辿るポインタ参照のためのロード命令によるロードデータのアドレスは、連続したイテレーションにおいて定数ストライドの増減をする可能性が高い。Wuらは、ロード命令によるロードデータのアドレスの定数ストライドを検出するため、プログラムの実行中においてロード命令によるロードデータのアドレスの前回との差分をプロファイル(profile; 値の履歴を集計)し、オフライン(off-line; プログラムの実行後。注：Wuらの技術はC言語に係るものであるので、コンパイラの作動前に、すなわちコンパイラの非作動期間としてのオフライン期間にプロファイルを解析する。)の解析で検出した定数ストライドの値を使って、プログラムの再コンパイル時にプリフェッチ命令を挿入するという手法を開発した。
【００１２】
【非特許文献１】
トッド・シー．・マウリィ、モニカ・エス．・ラム及びアヌープ・グプタ著「プリフェッチングのためのコンパイラアルゴリズムの設計及び評価」プログラミンク言語及びオペレーティングシステムのためのアーキテクチャサポートに関する第５回国際会議会議録、１９９２年１０月、ｐ．６２−７３（ Todd C. Mowry, Monica S. Lam, and Anoop Gupta, "Design and Evaluation of a Compiler Algorithm for Prefetching", in Proc. of the Fifth International Conference on Architectural Support for Programming Languages and Operating Systems, pp. 62-73, October 1992.）
【非特許文献２】
チ−クォン・ルク及びトッド・シー．・マウリィ著「再帰データ構造のためのコンパイラベースのプリフェッチング」、プログラミンク言語及びオペレーティングシステムのためのアーキテクチャサポートに関する第７回国際会議会議録、１９９６年１０月、ｐ．２２２−２３３（ Chi-Keung Luk and Todd C. Mowry, "Compiler-Based Prefetching for Recursive Data Structures", in Proc. of the 7th International Conference on Architectural Support for Programming Languages and Operating Systems, pp. 222-233, October 1996.）
【非特許文献３】
ブレンドン・カフーン及びカスリン・エス．・マンキンリィ著「Javaにおけるリンクデータ構造をプリフェッチングするソフトウェアのためのデータフロー解析」、２００１年９月（ Brendon Cahoon and Kathryn S. McKinley, "Data Flow Analysis for Software Prefetching Linked Data Structures in Java", in Proc. of the International Conference on Parallel Architectures and Compiler Techniques, September 2001.）
【非特許文献４】
ユフォン・ウ、マウリシオ・セラノ、ラケシュ・クリッシュネイヤー、ウェイ・リ及びヤッセ・ファン著「不規則的なコードのためのストライドプリフェッチングを案内する値プロファイル」コンパイラ構造に関する第１１回国際会議会議録、２００２年４月（ Youfeng Wu, Mauricio Serrano, Rakesh Krishnaiyer, Wei Li, and Jesse Fang, "Value-Profile Guided Stride Prefetching for Irregular Code", in Proc. of the 11th International Conference on Compiler Construction, pp. 307-324, April 2002, LNCS 2304.）
【非特許文献５】
ユフォン・ウ著「コンパイラプリフェッチングにおける不規則プログラム及びその使用においての規則的ストライドパターンの効率的発見」プログラミング言語設計及び実装に関するACM SIGPLANの会議録、２００２年６月、ｐ．２１０−２２１（Youfeng Wu, "Efficient Discovery of Regular Stride Patterns in Irregular Programs and Its Use in Compiler Prefetching", in Proc. of the ACM SIGPLAN Conference on Programming Language Design and Implementation, pp. 210-221, June 2002.）
【００１３】
【発明が解決しようとする課題】
Wuらの手法は従来のポインタ参照を対象とするプリフェッチングに比べて大きな性能向上を実現することが可能であるが、以下の二点において改善の余地がある。
（ａ）Wuらの手法は、同一のロード命令によるロードデータのアドレスが連続したイテレーション間において定数ストライドを示す場合にのみプリフェッチ命令を挿入する。この手法は、プリフェッチされるアドレスを、ロード命令によるロードデータのアドレスに定数を加えることで計算できるという利点があるが、このような定数ストライドが存在しないプログラムには有効ではない。
（ｂ）Wuらの手法は、まず最初に定数ストライドを検出するためにプロファイル取得用の命令を含んだプログラムを実行する必要がある。Wuらの実験では、定数ストライドの検出に必要な実行時間は、プログラム中の実行頻度を集計するプロファイリングに対して+17%増加する。このオーバーヘッドは、Wuらが適用したC原語のコンパイルの場合には、ある程度許容できるが、Javaのようにプロファイルの取得がオンライン(on-line; プログラムの実行中)で行われる環境では無視できない。
【００１４】
本発明の目的は、イテレーション間定数ストライド以外のストライドを利用して、キャッシュミスを抑制した機械語プログラムを生成するコード変換装置、コード変換方法及びプログラムを提供することである。
【００１５】
本発明の他の目的は、プロファイルの作成及び参照を省略して、ヒープメモリ内のデータ構造に基づく有効な機械語プログラムを高速生成するJITコンパイラ、JITコンパイル方法及びプログラムを提供することである。
【００１６】
【課題を解決するための手段】
変換処理対象コードを機械語コードへ変換する本発明のコード変換装置は次のものを有している。
所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目手段、
各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目手段、
ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出手段、
前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出手段、
相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算手段、
各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算手段、
相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定手段、
前記判定手段の判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定手段、
ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成手段、及び
プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成手段。
【００１７】
バイトコードを実行するJava仮想計算機からの指示を受けて指示範囲のバイトコードを機械語コードへ変換する本発明のJITコンパイラは次のものを有している。
指示範囲のバイトコードの部分を機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する情報収集手段、及び
前記情報収集手段による収集情報に基づいて指示範囲のバイトコードを機械語コードへ変換する変換手段。
【００１８】
変換処理対象コードを機械語コードへ変換する本発明のコード変換方法は次のステップを有している。
所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目ステップ、
各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目ステップ、
ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出ステップ、
前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出ステップ、
相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算ステップ、
各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算ステップ、
相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定ステップ、
前記判定ステップにおける判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定ステップ、
ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成ステップ、
プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成ステップ。
【００１９】
バイトコードを実行するJava仮想計算機からの指示を受けて指示範囲のバイトコードを機械語コードへ変換する本発明のJITコンパイル方法は次のステップを有している。
指示範囲のバイトコードの部分を機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する情報収集ステップ、及び
前記情報収集ステップにおける収集情報に基づいて指示範囲のバイトコードを機械語コードへ変換する変換ステップ。
【００２０】
本発明のコード変換用プログラムは、前述のコード変換装置の各手段としてコンピュータを機能させ、あるいは前述のコード変換方法の各ステップをコンピュータに実行させる。また、本発明のJITコンパイラ用プログラムは、前述のJITコンパイラの各手段としてコンピュータを機能させ、あるいは前述のJITコンパイル方法の各ステップをコンピュータに実行させる。
【００２１】
【発明の実施の形態】
以降、本発明をその実施の形態及び実施例について具体的に説明する。なお、本発明は実施の形態及び実施例に限定されるものではなく、その要旨を逸脱しない範囲で種々変更可能であることは言うまでもない。
【００２２】
本実施の形態が基づく基本思想は次の２つである。
（１）連続したイテレーションにおける同一のロード命令によるロードデータのアドレス間の定数ストライド(inter-iteration constant stride; 以下イテレーション間の定数ストライド)に加えて、同一のイテレーションにおける異なるロード命令によるロードデータのアドレス間の定数ストライド(intra-iteration constant stride; 以下イテレーション内の定数ストライド)を検出する。プリフェッチの対象を、1)イテレーション間の定数ストライドを持つロード命令L1、2)ロード命令L1の値をアドレスとしてメモリ参照を行うロード命令(L2)、3)ロード命令L2とイテレーション内定数ストライドを持つロード命令L3、に拡張することで、プリフェッチングの適用範囲を広げる。
（２）JITコンパイル時に、メソッドが呼び出されるときの実際の引数の値を使って、プリフェッチ命令を挿入しようとしているループを、先頭から数イテレーションだけ副作用（注：メインメモリにデータを書き込むことは状態の変更に繋がるので、「副作用」と呼んでいる。）を起こさずに部分的に評価し、イテレーション間およびイテレーション内の定数ストライドを検出する。以下では、この操作をオブジェクトインスペクション(object inspection)と呼ぶ。この方法は実際のヒープメモリ上のデータ構造を参照することができるという利点がある。またプロファイルを取得するオーバーヘッドはプログラムの実行時（注：プログラムの実行時間又は実行期間とは、JITコンパイラの処理時間に対して、Java仮想計算機がJITコンパイラの生成した機械語コード部分を実行している時間又は期間を言うものとする。）ではなくJITコンパイル時だけ必要である。JITコンパイラの時間はプログラムの実行時間に比べて小さいため、定数ストライドの検出は極めて少ない実行時間で実現できる。
【００２３】
以下において、本実施の形態の全体の手順を述べる。
【００２４】
本実施の形態は、Java JITコンパイラがバイトコードを機械語命令にJITコンパイルする際に、ロード命令によるロードデータのアドレス間の定数ストライドを利用したプリフェッチ命令を生成することを目的とする。Java JITコンパイラはJava仮想計算機がJavaメソッドを実行する直前に呼び出され、JITコンパイル対象となるメソッドを実行するために必要な引数はJava仮想計算機のスタック(メソッドの実行に必要なデータを格納するメモリ領域)上に用意されている。メソッドのJITコンパイルは、初回であっても最適化のための再コンパイルであっても構わない。
【００２５】
プリフェッチングは、入力となるJavaメソッドを表す中間コードを、プリフェッチ命令を含む中間コード(intermediate code)に変換することで実現される。与えられたJavaメソッドに対して、コンパイラはメソッド内の制御フローグラフのループを検出して、ループネスティングフォレスト(loop nesting forest; LNF; ループの入れ子関係を表現する木構造の集まり)を生成する。LNFの各頂点はループを、LNFの辺はループ間の入れ子関係を表す。本実施の形態のプリフェッチングアルゴリズムは、LNFの各木構造をメソッド内の実行順に従って探索し、木構造内の各ループをポストオーダー(post-order; 木の節点を子供から親の順に探索する順序)、すなわち内側のループから外側のループの順に探索する。
【００２６】
各ループにおいて、本実施の形態のアルゴリズムは以下の三段階の操作を行う。
（ａ）ループ内のロード命令の依存関係を表現するグラフ(load dependence graph; 以下ロード依存グラフ)を生成する。ロード依存グラフは、イテレーション内定数ストライドの存在を調べるロード命令を、データ依存があるロード命令の組に限定して、JITコンパイル時のオーバーヘッドを軽減するために使用される。
（ｂ）オブジェクトインスペクションによってループを先頭から数イテレーションだけ評価し、ロード依存グラフ上でイテレーション間およびイテレーション内の定数ストライドの有無を調べる。定数ストライドが存在する場合は、グラフの注釈として定数ストライドの値を記録する。
（ｃ）ロード依存グラフにおいて定数ストライドを持つロード命令について、プリフェッチ命令の挿入が有効かどうかを予測し、効果があると思われるロード命令に対してプリフェッチ命令を生成する。
【００２７】
繰り返し回数の少ないループに含まれるロード命令については、Wuらの手法と同様に、それらが外側のループに存在するとみなす。本実施の形態のアルゴリズムでは、ループの繰り返し回数が小さいことをオブジェクトインスペクションの間に検出する。
【００２８】
繰り返し回数の少ないループに含まれるロード命令については、Wuらの手法と同様に、それらが外側のループに存在するとみなす。本実施の形態のアルゴリズムでは、ループの繰り返し回数が小さいことをオブジェクトインスペクションの間に検出する。
【００２９】
以下で、上記（ａ）〜（ｃ）の各段階の詳細を述べる。
【００３０】
［（ａ）ロード依存グラフの生成］
ロード依存グラフは、ロード命令を頂点(vertex)とし、ロード命令間のデータ依存関係を辺(edge)とする有向グラフ(directed graph)である。ロード依存グラフは、プリフェッチングの対象となるループ内で、連続したポインタ参照を辿るロード命令を検出するために生成される。各頂点は、オブジェクトへの参照を引数として受け取りメモリ参照を行うようなロード命令である。各有向辺(L1, L2)は、ロード命令L2がロード命令L1に対して直接データ依存することを表す。中間コードとしてJavaバイトコードを用いた場合、ロード依存グラフの頂点となる命令は、getfield, getstatic, aaload, iaload, daload, arraylengthなどである。このうち、グラフの中で後継頂点を持つ可能性がある命令は、オブジェクトの参照を生成する命令、すなわちaaload（配列の要素のロード）, getfield（オブジェクトのフィールド変数のロード）, getstatic（クラスの静的変数のロード）である。与えられたループの内側にループがあって、内側のループの繰り返し回数が少ない場合は、内側のループ内のロード命令も同じロード依存グラフの頂点として扱う。ロード依存グラフはメソッド内の使用・定義連鎖など、中間コード間のデータ依存関係を表すグラフから生成することができる。
【００３１】
［（ｂ）オブジェクトインスペクション］
ロード依存グラフを生成したら、オブジェクトインスペクションによって定数ストライドを検出する。オブジェクトインスペクションでは、与えられたループの中の命令を実際のメソッドの引数の値を用いて定数回(例えば20回)だけ部分評価(partial interpretation)し、各ロード命令によるロードデータのアドレスをロード依存グラフに記録する。部分評価が終了したら、アドレスの履歴から定数ストライドの有無を計算する。ロード依存グラフの各頂点のアドレスについて、連続したイテレーション間の定数ストライドを調べ、有向辺で結ばれたロード命令によるロードデータのアドレスの組について、同じイテレーション内の定数ストライドを調べる。計算されたアドレスの差分が、大部分(例えば75%以上。注：キャッシュメモリへのプリフェッチはキャッシュラインを単位に実施されるので、ストライドに多少の誤差があっても、定数ストライドに基づくプリフェッチにより目的（target）のデータはキャッシュメモリに書き込まれる。)のイテレーション間及びイテレーション内で同じ値であれば、ロード命令が定数ストライドを持つとみなして、対応する頂点または辺に定数ストライドの値を記録する。
【００３２】
オブジェクトインスペクションは、メソッド内の中間コードをメソッドの先頭から順に部分評価する。メソッドの引数が与えられても、全ての命令の評価において引数が計算できるとは限らない。このような場合は、命令の引数は「不定値」という特別な値を取るとみなす。引数に不定値を含むような命令の評価結果はやはり不定値である。
【００３３】
オブジェクトインスペクションはJITコンパイル時の解析であり、Javaプログラムの実行に対して副作用を与えないようにする必要がある。特に、ストア命令を評価するときにメモリに書き込みを行なってはならない。このため、JITコンパイル時にJava仮想計算機のスタック(stack)の複製を用意し、Javaプログラムのローカル変数(local variable)への書き込みは複製されたスタック上で行なう。また、ヒープメモリ上のオブジェクトに対するストア命令の評価は、書き込まれるアドレスと値の組をハッシュテーブル(hash table)に記録することで実現し、オブジェクトや配列に対するロード命令を評価する際には、最初にこのハッシュテーブルの値を検索する。同様な理由で、JITコンパイル時に仮想的なヒープメモリを用意し、オブジェクトを生成する命令の評価を行なう。
【００３４】
オブジェクトインスペクションによる評価がプリフェッチの対象となるループの入り口に到達する前に、別のループに出会う可能性がある。このような別のループについては、ループ中の命令を一回だけ評価する。なぜならば、このようなループの評価の結果が目標とするループのイテレーションの初期値に影響を与えることは少ないからである。例えば、配列の要素を辿るループでは、配列の添字の変数は0に初期化されることが多いし、オブジェクトのリストを辿るループでは、リストの要素へのポインタは引数の値に初期化されることが多い。また、オブジェクトインスペクションのオーバーヘッドを低く抑えるためにも、他のループが実際に終了するまで評価するのは現実的でない。
【００３５】
他のメソッドへの呼び出しは単に無視される。メソッド呼び出しが値を返す場合は、不定値を返すとみなす。解析の精度を上げる方法として、メソッド呼び出しにおいて、さらに呼び出されるメソッド内のオブジェクトインスペクションを行なうという手続き間解析(inter-procedural analysis)の手法が考えられるが、JITコンパイル時間との兼ね合いを考慮する必要がある。
【００３６】
［（ｃ）プリフェッチ命令の生成］
オブジェクトインスペクションの後、ロード依存グラフの頂点のうち定数ストライドを持つものに対してプリフェッチ命令を生成する。最初に、各定数ストライドに対して生成するコード列について説明する。次に、効果的で冗長でないプリフェッチ命令を生成するための、プリフェッチによる効果の解析方法について説明する。最後に、本実施の形態で前提とする二種類のプリフェッチ命令の、機械語命令に対する対応について説明する。
【００３７】
（ｃ．１）コード列
ロード依存グラフの頂点Lxがイテレーション間定数ストライドdを持つとする。 頂点Lxが後継頂点(adjacents)を持たないか、または全ての後継頂点がイテレーション間定数ストライドを持つ場合、cイテレーション後におけるロード命令Lxが参照するデータを現在のイテレーションでプリフェッチするためには、A(L)を現在のイテレーションにおいてロード命令Lが参照するアドレスとすると、以下のコードを生成すればよい。なお、*は乗算を意味する。
prefetch (A(Lx) + d*c);
【００３８】
ここで、prefetchは与えられたアドレスをキャッシュメモリ内にプリフェッチする命令を表す。今度は、頂点Lxがイテレーション間定数ストライドを持たない後継頂点Lyを持つとする。ロード命令LxおよびLyがcイテレーション後に参照するデータをプリフェッチするためには、以下のコードを生成すればよい。
a = spec_load (A(Lx) + d*c);
prefetch (F[Lx,Ly] (a));
【００３９】
ここで、spec_loadは与えられたアドレスをアクセス違反を起こさずにロードする命令(speculative load; 以下投機的ロード命令)である。また、F[Lx, Ly]はLxの結果として得られるオブジェクト参照のアドレスからLyのアドレスを得る関数である。「F[Lx,Ly] (a)」の「(a)」は、Lyのアドレスを得る際のオブジェクト参照のアドレスがLx及びa = spec_load (A(Lx) + d*c)に基づくaであるこを意味している。通常、F[Lx,Ly] (a)の演算は定数値の加算で表される。さらに、Lyとの間にイテレーション内定数ストライドを持つロード命令Lzが存在する場合は、以下のコード生成によってLzが参照するアドレスも同様にプリフェッチすることができる。
【００４０】
prefetch (F[Lx,Ly] (a) + S[Ly,Lz]);
【００４１】
ここで、S[Ly, Lz]はロード命令Ly, Lzの間のイテレーション内定数ストライドの値を表す。スケジューリング距離cの実際の値は、プリフェッチ命令を挿入するループ内の計算の量やメモリ参照の数など、様々な要素に依存する。
【００４２】
（ｃ．２）プリフェッチの効果の解析
プリフェッチ命令はメモリ参照を行なうため、プロセッサのメモリ参照のための演算器及びデータ転送のためのバンド幅を消費する。従って、プリフェッチ可能なロード命令の中から、プリフェッチが効果的なものを選ぶ必要がある。理想的には、頻繁にキャッシュミスを起こすロード命令だけにプリフェッチを生成するのが望ましい。しかし、キャッシュミスの有無はキャッシュメモリの容量や、前後に実行される他のロード命令などの様々な動的な要素に影響されるため、コンパイル時に予測することは難しい。
【００４３】
代わりに、以下の簡単な解析によってプリフェッチによる効果を見積もる。すなわち、ロード命令Lが以下の三つの条件を満たす場合、Lのアドレスのプリフェッチが効果的であると判断する。
（ｃ．２．ａ）ロード命令Lに対してデータ依存する命令(ロード命令でなくともよい)が存在する。
（ｃ．２．ｂ）ロード命令Lが参照するデータが、既にプリフェッチ命令が挿入された他のロード命令と同じキャッシュライン(cache line; キャッシュメモリでメモリ内容を扱う単位)に入らない。
（ｃ．２．ｃ）ロード命令Lがイテレーション間定数ストライドを持つ場合に、定数ストライド値がキャッシュラインの大きさの半分より大きい。
【００４４】
なお、（ｃ．２．ａ）（ｃ．２．ｂ）は、後述の第２の擬似プログラムの行番号104,105に係る条件であるのに対し、（ｃ．２．ｃ）は、後述の第３の擬似プログラムの行番号133に係る条件である。ポインタ参照ロード命令ＸiがロードするデータＤiをイテレーション間定数ストライドに基づきプリフェッチすることを考える場合、ポインタ参照ロード命令Ｘiの属するイテレーションより１個前のイテレーションにおけるポインタ参照ロード命令Ｘi-1とそれがロードするデータＤi-1を考える。データＤi-1及びＤiとのアドレス間隔としてのイテレーション間定数ストライドがキャッシュラインのサイズの１／２以下であれば、データＤi-1をプリフェッチしようとするとき、通常、該データＤi-1はキャッシュメモリにすでに存在することになので、データＤi-1のプリフェッチは意味がない。
【００４５】
（ｃ．３）機械語命令との対応：
ｃ．１において使用したprefetch命令およびspec_load命令の実装では、プロセッサが提供するプリフェッチ命令または投機的ロード命令を使用するか、または通常のロード命令を、アクセス違反を調べる条件分岐命令によってガード(guard; 守る)するか、二通り考えることができる。目標とするプロセッサが専用の命令を提供している場合は、当然プロセッサが提供する命令を使用する方がオーバーヘッドが少ない。プロセッサが提供するプリフェッチ命令を使用すれば、命令数やメモリ参照のオーバーヘッドを最小に抑えることができる。通常プリフェッチ命令はプロセッサのメモリ転送のバンド幅が不足するような場合、例えばデータトランスレーションルックアサイドバッファ(data translation lookaside buffer; DTLB; 参照されるデータの論理アドレスを物理アドレスに変換するテーブル)のミスが発生する場合には実行されない。現在のところ、プリフェッチ命令は多くのプロセッサで提供されているが、投機的ロード命令を提供しているのはインテル社のIA-64アーキテクチャとスパーク社のSPARC V9アーキテクチャのみである。
【００４６】
しかし、プロセッサがプリフェッチ命令を提供している場合においても、ガードされたロード命令が有効である局面が存在する。なぜならば、ガードされたロード命令はDTLBミスが発生するページ(page; 論理／物理アドレス変換の単位)を予めDTLBに読み込むことができるからである。従って、イテレーション間定数ストライドがページの大きさの半分より大きい場合は、ガードされたロード命令の方がプロセッサが提供するプリフェッチ命令より効果的である。さらに重要な場合として、メモリ参照によってアドレスが得られる場合がある。例えば上記のA(Ly)はイテレーション間で定数ストライドを持たないので、連続したイテレーションにおいて次々と異なるページを参照する可能性が高い。従って、Lyをプリフェッチするときにはガードされたロード命令が有効である。
【００４７】
【実施例】
以下では、Java JITコンパイラにおける実施例を述べる。
例として、SPECjvm98ベンチマークの中の_202_jessベンチマークのコードの一部を考える。このプログラムはJava言語で記述されたエキスパートシステム(expert system; 与えられた知識データを基にして推論を行なうプログラム)である。以下のJavaプログラムは、_202_jessベンチマークの一部分を簡略化したものである。説明の便宜上、以下のJavaプログラムを「サンプルプログラム」と呼ぶとともに、コード列の左端には行番号を付ける。
【００４８】
10:class TokenVector {
11:  Token[] v;
12:  int ptr;
13:  void addElement (Token val) {...}
14:  void removeElement (Token val) {...}
15:  ...
16:}
【００４９】
30:class Token {
31:    ValueVector[] facts;
32:    int size = 0;
33:    Token (ValueVector firstFact) {
34:     facts = new ValueVector[5];
35:     facts[size++] = firstFact;
36:    }
37:    ...
38:}
【００５０】
50:class Node2 {
51:    Token findInMemory (TokenVector tv, Token t) {
52:    TokenLoop:
53:     for (int i = 0; i < tv.ptr; i++) {
54:      Token tmp = tv.v[i];
55:      for (int j = 0; j < t.size; j++) {
56:       if (!t.facts[j].equals (tmp.facts[j]))
57:        continue TokenLoop;
58:      return tmp;
59:     }
60:     return null;
61:    }
62:    ...
63:}
【００５１】
TokenVector型のオブジェクトtvは、その要素としてのToken型のオブジェクトvを適宜、増減される（行番号13,14）。Token型のオブジェクトtv.v及びtは、ValueVector型のオブジェクトfactsのリストを備える（行番号34）メソッドfindInMemory（行番号51〜59）の実行では、tmp.factsとt.factsとの同一番号の要素同士が対比され（行番号56）、もし一致したならば、そのときのオブジェクトtmpがメソッドfindInMemoryの返り値とされる（行番号58）。
【００５２】
メソッドfindInMemory()は_202_jessベンチマークで全体の実行時間に占める割合が多いメソッドの一つである。ここでは、メソッドfindInMemory()の外側のループ(変数iを添字とするforループ)がプリフェッチ命令を生成する目標のループであるとする。_202_jessのプロファイルから、内側のループ(変数jを添字とするforループ)はループの反復回数が少ないことがわかるので、ここでは、内側のループのロード命令もプリフェッチの対象とする。図１はサンプルプログラムにおいて外側のループで辿るTokenオブジェクトに関連したデータ構造の説明図である。
【００５３】
図２はサンプルプログラムにおいて二重ループに含まれるロード命令とそれが参照するデータの、ヒープメモリ上のアドレスとの関係を示している。図２において、演算子'&'は変数のアドレスを表す演算子である(Javaの表記ではない)。配列のlengthフィールド(field; 欄)へのロード命令はJavaプログラムには明示的に現れないが、配列の境界検査(bound check)のために生成される。
【００５４】
Wuらのプリフェッチアルゴリズムは、反復回数の多いループに含まれる、アドレスがループ内で不変(invariant)でないロード命令について、各アドレスのイテレーション間ストライドの値のプロファイルを調べる。この例ではL4, L9, L10, L11がプロファイルの対象となるロード命令である。
【００５５】
しかし、この_202_jessの上記コード部分の例では、イテレーション間定数ストライドを持つロード命令はL4だけである。この理由は、配列tv.vから参照されるTokenオブジェクトは、初期化段階で一度に生成されるのではなく、ベンチマークの実行中にメソッドaddElement()によって漸次追加されるためである。また、メソッドremoveElement()はTokenオブジェクトを配列tv.vから取り除く際に、配列の最後の要素を取り除かれた要素に代入する。従って配列tv.vのTokenオブジェクトを先頭から順に参照しても、L9, L10はイテレーション間定数ストライドを持たない。プロファイルによって得られたロード命令L4のイテレーション間定数ストライドがdバイトであったとすれば、cイテレーション先にアクセスされるデータをプリフェッチする命令を、Wuらのアルゴリズムに従って生成すると以下の擬似プログラムのように表される。説明の便宜上、以下の擬似プログラムを第１の擬似プログラムと呼ぶ。
【００５６】
80:TokenLoop:
81:  for (int i = 0; i < tv.ptr; i++) {
82:    Token tmp = tv.v[i];
83:    prefetch (&tv.v[i] + c*d);
84:    for (int j = 0; j < t.size; j++) {
85:      if (!t.facts[j].equals (tmp.facts[j]))
86:        continue TokenLoop;
87:    return tmp;
88:  }
【００５７】
第１の擬似プログラムでは、サンプルプログラムの行番号52〜59の対比から分かるように、prefetchが行番号83に追加されている。図３は第１の擬似プログラムの実行過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。プロセッサが現在実行している命令列の属するイテレーションの番号をiとする。i番のイテレーションの命令列の実行中に、アドレス&tv.v[i] + c*dのデータがキャッシュメモリにプリフェッチされる。
【００５８】
なお、図３、図５及び図９において、破線の引出し線の付いた符号はそれがアドレスであることを意味し、実線の引出し線の付いた符号はそれがデータであることを意味している。
【００５９】
これに対して、本実施例の手法を適用したときの手順は以下のようになる。まず外側のループ内のロード命令でプリフェッチの候補となるロード命令について、ロード依存グラフを生成する。図４はサンプルプログラムにおけるロード命令に対応するロード依存グラフである。
【００６０】
次に、オブジェクトインスペクションを用いて、外側のループを繰り返したときのイテレーション間およびイテレーション内の定数ストライドを検出する。上述のようにイテレーション間定数ストライドを持つロード命令はL4だけである。しかし、ロード命令L9のアドレスはL4の結果から得られるので、ポインタ参照を一回行なうことで、ロード命令L9で参照されるアドレスをプリフェッチすることができる。さらに、ロード命令L9, L10の間にイテレーション内定数ストライドが存在する。これは、Tokenオブジェクトのコンストラクタ(constructor; 初期化メソッド)の先頭で、配列オブジェクトをアロケートしてfactsフィールドに代入しているからである。すなわち、配列オブジェクトはTokenオブジェクトがアロケートされた直後にアロケートされるので、両者のヒープメモリ上の間隔は一定である可能性が高い。いま、Tokenオブジェクトの先頭からfactsフィールドへの間隔がoバイト、ロード命令L9, L10のイテレーション内定数ストライドがsバイトでキャッシュラインの大きさの半分より大きいとすると、本実施例によるプリフェッチングの結果は以下の擬似プログラムで表される。説明の便宜上、以下の擬似プログラムを第２の擬似プログラムと呼ぶことにする。
【００６１】
100:TokenLoop:
101:  for (int i = 0; i < tv.ptr; i++) {
102:    Token tmp = tv.v[i];
103:    tmp_pref = spec_load (&tv.v[i] + c*d);
104:    prefetch (tmp_pref + o);
105:    prefetch (tmp_pref + o + s);
106:    for (int j = 0; j < t.size; j++) {
107:      if (!t.facts[j].equals (tmp.facts[j]))
108:        continue TokenLoop;
109:    return tmp;
110:  }
【００６２】
第２の擬似プログラムでは、前述のサンプルプログラムに対して、行番号102〜105の命令コードが追加されている。また、第２の擬似プログラムでは、第１の擬似プログラムに対して、行番号83の内容が行番号103〜105の内容に変更されている。prefetchが行番号83に追加されている。図５は第２の擬似プログラムの実行過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。また、k=i+cとする。第２の擬似プログラムでは、プロセッサが現在実行している命令列の属するイテレーションの番号をiとする。i番のイテレーションの命令列の実行中に、アドレス&tv.v[i] + c*dのデータtmpが読み出され、tmp_prefをアドレスとするデータ、すなわちアドレスtmp_prefのデータが読み出される。そして、アドレス（tmp_pref+o）のデータ、すなわちk番目のイテレーションにおけるポインタ参照ロード命令L9がロードするデータが、行番号104においてヒープメモリからキャッシュメモリへプリフェッチされる。さらに、アドレス（tmp_pref+o+s）のデータ、すなわちk番目のイテレーションにおけるポインタ参照ロード命令L10がロードするデータが、行番号105においてヒープメモリからキャッシュメモリへプリフェッチされる。
【００６３】
なお、第２の擬似プログラムに第１の擬似プログラムの行番号83のプリフェッチを追加することもできる。下記の第３の擬似プログラムがそれである。第３の擬似プログラムでは、第１の擬似プログラムの行番号83が行番号133に現れている。
【００６４】
130:TokenLoop:
131:  for (int i = 0; i < tv.ptr; i++) {
132:    Token tmp = tv.v[i];
133:    prefetch (&tv.v[i] + c*d);
134:    tmp_pref = spec_load (&tv.v[i] + c*d);
135:    prefetch (tmp_pref + o);
136:    prefetch (tmp_pref + o + s);
137:    for (int j = 0; j < t.size; j++) {
138:      if (!t.facts[j].equals (tmp.facts[j]))
139:        continue TokenLoop;
140:    return tmp;
141:  }
【００６５】
本実施例の手法をIBM Developer Kit for Windows（Windowsは登録商標）, Java Technology Edition Version 1.3.1のIBM Java JIT Compiler Version 4.0に実装して実験を行った。プロセッサは2 GHz Intel Pentium4（Pentiumは登録商標）、メモリサイズは1 GB、OSはMicrosoft Windows 2000 Professional + Service Pack 2である。図６はSPECjvm98ベンチマーク及びJavaGrande v2.0ベンチマークSection 3のPentium 4上での速度能向上率を示す。なお、SPECjvm98ベンチマークはStandard Performance Evaluation Corporation (SPEC), JVM Client98 (SPECjvm98), available at http://www.spec.org/osg/jvm98, 1998.であり、JavaGrande v2.0ベンチマークはJava Grande Benchmarking Project, Java Grande Forum Benchmark Suite, Version 2.0, available at http://www.epcc.ed.ac.uk/javagrande, 1999.である。SPECjvm98は幾何平均で4.3%、JavaGrande v2.0 Section 3は3.2%の性能向上を実現した。
【００６６】
また、図７はSPECjvm98ベンチマーク及びJavaGrande v2.0ベンチマークSection 3のPentium 4上で実行した場合のコンパイル時間のオーバーヘッドを示す。数字はJITコンパイラの全コンパイル時間に対する割合である。コンパイル時間のオーバーヘッドは最大で3.7%である。Euler, MolDyn以外のプログラムに対しては1%以下に抑えられている。以上から、プリフェッチのためのコンパイル時間は実行時間に比べて非常に小さい。
【００６７】
図８はコード変換装置１０の機能ブロック図である。図９はコード変換装置１０が処理過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。コード変換装置１０は、変換処理対象コード１１を機械語コード１２へ変換する。コード変換装置１０は、第１の着目手段１５、第２の着目手段１６、第１の検出手段１７、第２の検出手段１８、第１の計算手段１９、第２の計算手段２０、判定手段２１、第１の機械語コード部分生成手段２３、及び第２の機械語コード部分生成手段２４を有している。第１の着目手段１５は、所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード１１上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する。第２の着目手段１６は、各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード１１上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する。第１の検出手段１７は、ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する。第２の検出手段１８は、データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する。第１の計算手段１９は、相互に隣接するイテレーションのポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する。第２の計算手段２０は、各イテレーションにおけるポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1とデータ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する。判定手段２１は、相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する。設定手段２２は、判定手段２１の判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する。第１の機械語コード部分生成手段２３は、ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーシ���ンをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する。第２の機械語コード部分生成手段２４は、プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する。
【００６８】
コード変換装置１０とは例えばJITコンパイラである。変換処理対象コード１１とは例えばJavaのバイトコードである。第１及び第２の割合は、等しくてもよく、例えば共に７５％である。なお、当然のことながら、ヒープメモリが含まれるメインメモリからキャッシュメモリへのデータ転送はキャッシュラインを単位に行われる。したがって、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチすれば、該アドレス（Ｕb,1＋Ｆｙ）を含む所定アドレス範囲のデータが、データＵb,2と共にヒープメモリからキャッシュメモリへロードされる。以降、コード変換装置１０の更なる具体的な構成について説明する。図８のコード変換装置１０は、以下に述べる種々の具体的構成を任意の組み合わせで適宜、装備され得る。
【００６９】
Javaでは、そのバイトコード上のポインタ参照ロード命令は、ソースコードにおけるオブジェクト型変数を呼び出す操作に対応している。
【００７０】
第１及び第２の機械語コード部分生成手段２４は、機械語コード部分Ｈ１，Ｈ２を、イテレーションＢaを実行する機械語コード範囲に配置する。
【００７１】
機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換装置１０では、第１の機械語コード部分生成手段２３は、機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、機械語コード部分Ｈ１を生成する。第２の機械語コード部分生成手段２４は、機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、機械語コード部分Ｈ２を生成する。
【００７２】
機械語としてプリフェッチ命令Ｊ１及びロード命令Ｊ３を装備するプロセッサ用のコード変換装置１０では、第１の機械語コード部分生成手段２３は、機械語コード部分Ｈ１が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1を検出する処理を含むように、機械語コード部分Ｈ１を生成する。第２の機械語コード部分生成手段２４は、機械語コード部分Ｈ２が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレス（Ｕb,1＋Ｆｙ）のデータＶb２をプリフェッチする処理を含むように、機械語コード部分Ｈ２を生成する。
【００７３】
なお、「ガードされたロード命令」とは所定の条件が満たされるときのみロードを実行するロード命令を言うものとする。本実施形態における「ガードされたロード命令」は、アクセス違反が無いと言う条件が満たされるときのみ、ロードを実行する。例えば、投機的に実行されるロード命令は、プログラムの本来の実行では読み出されない配列の要素や、配列の外のメモリを読み出すことがある。そのようなメモリ番地には、アドレスとして正しくない値(例えば０)が格納されている可能性がある。このような投機的なロード命令の結果をアドレス値として他のロード命令を実行する場合、そのロード命令はヒープメモリ以外のアドレス(０番地など)を読み出し、アクセス違反を起こす可能性がある。
【００７４】
図１０はコード変換装置１０の構成をさらに具体化して示したものである。図８のコード変換装置１０に対する追加点のみを説明する。グラフ生成手段２６は、ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成する。第１及び第２の着目手段１６は、ポインタ参照ロード命令及びデータ依存ロード命令をロード依存グラフに基づき検出する。アドレス記録手段２８は、ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについてバイトコードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録する。第１及び第２の検出手段１８は、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する。
【００７５】
なお、「副作用を起こさない」とは、ヒープメモリのデータ構造を変化させる操作は行わないことを意味するものとする。
【００７６】
図１１はコード変換装置１０の機能付加部を示している。予測手段３１は、データＵb,2のプリフェッチが有意義か否かを予測する。中止手段３２は、予測手段３１が有意義でないと予測した場合には、第１及び第２の機械語生成手段による機械語コード部分Ｈ１，Ｈ２の生成を中止させる。説明の便宜上、データＵb,2をロードするデータ依存ロード命令を対象データ依存ロード命令、該対象データ依存ロード命令と呼ぶことにする。予測手段３１は、データＵb,2にデータ依存する命令が存在する場合、及び／又は対象データ依存ロード命令とは別のデータ依存ロード命令がロードするデータＸに対して該データＸ用の機械語コード部分Ｈ２がすでに生成されていてデータＵb,2はデータＸとは同一のキャッシュラインには入らない場合、プリフェッチ命令の挿入が有意義と予測する。
【００７７】
前述の第３の擬似プログラムの行番号133に対応する機能を追加装備するコード変換装置１０は、式：Ｕa,0＋ｐ・Ｆｘに基づきアドレス（Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ３を生成する第３の機械語コード部分生成手段を有している。そして、該コード変換装置１０は、さらに、キャッシュラインのサイズＦｓとしてＦｓ≧が２・Ｆｘであるならば第３の機械語コード部分生成手段による機械語コード部分Ｈ３の生成は中止とする制御手段を有している。
【００７８】
図１２はコード変換方法のフローチャートである。コード変換方法では、変換処理対象コードを機械語コードへ変換する。第１の着目ステップＳ３５では、所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn１に着目する。第２の着目ステップＳ３６では、各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn２であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn１にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn２に着目する。第１の検出ステップＳ３７では、ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn１に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,0１に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0０を検出する。第２の検出ステップＳ３８では、データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する。第１の計算ステップＳ３９では、相互に隣接するイテレーションのポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する。第２の計算ステップＳ４０では、各イテレーションにおけるポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1とデータ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する。判定ステップＳ４１では、相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する。設定ステップＳ４２では、判定ステップＳ４１における判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する。第１の機械語コード部分生成ステップＳ４３では、ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する。第２の機械語コード部分生成ステップＳ４４では、プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する。
【００７９】
本実施例のコード変換方法では、図１２のフローチャートに係るコード変換方法を基本にして、以下に述べる具体的構成を任意の組み合わせで適宜追加可能である。
【００８０】
変換処理対象コードはJavaのバイトコードである。コード変換方法はＪＩＴコンパイラである。
【００８１】
第１及び第２の機械語コード部分生成ステップＳ４４では、機械語コード部分Ｈ１，Ｈ２を、イテレーションＢaを実行する機械語コード範囲に配置する。
【００８２】
機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換方法において、第１の機械語コード部分生成ステップＳ４３では、機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、機械語コード部分Ｈ１を生成する。第２の機械語コード部分生成ステップＳ４４では、機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、機械語コード部分Ｈ２を生成する。
【００８３】
機械語としてプリフェッチ命令Ｊ１及びロード命令Ｊ３を装備するプロセッサ用のコード変換方法において、第１の機械語コード部分生成ステップＳ４３では、機械語コード部分Ｈ１が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1を検出する処理を含める。第２の機械語コード部分生成ステップＳ４４では、機械語コード部分Ｈ２が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレス（Ｕb,1＋Ｆｙ）のデータＶb２をプリフェッチする処理を含むように、機械語コード部分Ｈ２を生成する。
【００８４】
図１３は図１２のフローチャートにステップを追加したフローチャートの主要部である。グラフ生成ステップＳ４５はＳ３５の前に追加される。Ｓ４５では、ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成する。第１及び第２の着目ステップＳ３５，Ｓ３６では、ポインタ参照ロード命令及びデータ依存ロード命令をロード依存グラフに基づき検出する。
【００８５】
アドレス記録ステップＳ４６はＳ３６とＳ３７との間に追加される。アドレス記録ステップＳ４６では、ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについて変換処理対象コードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録する。第１及び第２の検出ステップＳ３７，Ｓ３８では、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する。
【００８６】
図１４は図１２のフローチャートに別のステップを追加したフローチャートの主要部である。予測ステップＳ４９及び中止ステップＳ５０がＳ３９とＳ４２との間に追加されている。予測ステップＳ４９では、判定ステップＳ４１における判定に係るデータ依存ロード命令について、該データ依存ロード命令に基づくロードデータのプリフェッチが有意義か否かを予測する。予測ステップＳ４９において有意義でないと予測した場合には、すなわち、Ｓ４９の判定が「有り」の場合、Ｓ４２へ進み、「否」である場合、中止ステップＳ５０へ進む。中止ステップＳ５０では、第１及び第２の機械語生成ステップにおける機械語コード部分Ｈ１，Ｈ２の生成を中止させる。
【００８７】
図１５はJITコンパイラ５７の構成をJava仮想計算機５５と共に示している。JITコンパイラ５７は、バイトコード５６を実行するJava仮想計算機５５からの指示を受けて指示範囲のバイトコード５６を機械語コード１２へ変換する。JITコンパイラ５７は、情報収集手段５８及び変換手段５９を有している。情報収集手段５８は、指示範囲のバイトコード５６の部分を機械語コード１２へ試し実行用にコンパイルし試し実行用機械語コード１２を、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する。変換手段５９は、情報収集手段５８による収集情報に基づいて指示範囲のバイトコード５６を機械語コード１２へ変換する。
【００８８】
図１５のJITコンパイラ５７はさらに以下の具体的構成を任意の組み合わせで装備可能になっている。変換手段５９は、情報収集手段５８による収集情報に依らずに指示範囲のバイトコード５６を変換された機械語コード１２に対して情報収集手段５８による収集情報に基づく機械語コード１２部分を追加した機械語コード１２を生成するものである。収集情報は、ループＡ内の各イテレーションにおける所定ロード命令がヒープメモリから参照するデータのアドレスの規則性に係る情報を含み、変換手段５９は、収集情報に基づき所定ロード命令に基づくロードデータをヒープメモリからキャッシュメモリへプリフェッチする機械語コード１２部分を生成するものである。
【００８９】
図１６はJITコンパイル方法のフローチャートである。JITコンパイル方法では、バイトコードを実行するJava仮想計算機からの指示を受けて指示範囲のバイトコードを機械語コードへ変換する。情報収集ステップＳ６３では、指示範囲のバイトコードの部分を機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する。変換ステップＳ６４では、情報収集ステップＳ６３における収集情報に基づいて指示範囲のバイトコードを機械語コードへ変換する。
【００９０】
図１６に係るJITコンパイル方法は、さらに、以下の実施態様を任意の組み合わせで適宜追加され得る。
【００９１】
変換ステップＳ６４では、情報収集ステップＳ６３における収集情報に依らずに指示範囲のバイトコードを変換された機械語コードに対して情報収集ステップＳ６３における収集情報に基づく機械語コード部分を追加した機械語コードを生成する。
【００９２】
収集情報は、ループＡ内の各イテレーションにおける所定ロード命令がヒープメモリから参照するデータのアドレスの規則性に係る情報を含む。変換ステップＳ６４では、収集情報に基づき所定ロード命令に基づくロードデータをヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分を生成する。
【００９３】
図１７はプログラムを実行するためのハードウェア構成図である。前述したコード変換装置７０及びイテレーション５７において各手段が実施する各機能は例えば図１７のハードウェアを使用して実行される。システムバス７０には、ＣＰＵ７１、メインメモリ７２及び入出力制御装置７３が接続される。ＣＰＵ７１及びキャッシュメモリ７５は同一のチップに含まれ、ＣＰＵ７１内のプロセッサは、キャッシュメモリ７５からデータをロードする。そして、キャッシュミスが生じた場合には、該キャッシュミスに係るデータを含むキャッシュラインがメインメモリ７２からキャッシュメモリ７５へロードされる。その後、ＣＰＵ７１内のプロセッサは該データをキャッシュメモリ７５からロードする。入出力制御装置７３には、ハードディスクインターフェース及びＬＡＮインターフェース等が含まれ、ＣＰＵ７１が実行する各種プログラム（JITコンパイラを含む。）はハードディスク装置等に格納されている。プログラムは、ＣＰＵ７１において実行されるのに先立ち、メインメモリ７２に格納される。ＣＰＵ７１は、メインメモリ７２の命令行を順次、読み出して、該プログラムを実行する。
【００９４】
まとめとして本発明の構成に関して以下の事項を開示する。
（１）：変換処理対象コードを機械語コードへ変換するコード変換装置において、
所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目手段、
各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目手段、
ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出手段、
前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出手段、
相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算手段、
各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算手段、
相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定手段、
前記判定手段の判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定手段、
ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成手段、及び
プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成手段、
を有していることを特徴とするコード変換装置。
【００９５】
（２）：前記変換処理対象コードはJavaのバイトコードであることを特徴とする（１）記載のコード変換装置。
（３）：前記コード変換装置はJITコンパイラであることを特徴とする（１）又は（２）記載のコード変換装置。
（４）：前記第１及び前記第２の機械語コード部分生成手段は、前記機械語コード部分Ｈ１，Ｈ２を、前記イテレーションＢaを実行する機械語コード範囲に配置することを特徴とする（１）〜（３）のいずれかに記載のコード変換装置。
（５）：機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換装置において、
前記第１の機械語コード部分生成手段は、前記機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、前記機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成手段は、前記機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、前記機械語コード部分Ｈ２を生成する、
ことを特徴とする（１）〜（４）のいずれかに記載のコード変換装置。
（６）：機械語としてプリフェッチ命令Ｊ１及びロード命令Ｊ３を装備するプロセッサ用のコード変換装置において、
前記第１の機械語コード部分生成手段は、前記機械語コード部分Ｈ１が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1を検出する処理を含むように、機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成手段は、前記機械語コード部分Ｈ２が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレス（Ｕb,1＋Ｆｙ）のデータＶb２をプリフェッチする処理を含むように、機械語コード部分Ｈ２を生成する、
ことを特徴とする（１）〜（４）のいずれかに記載のコード変換装置。
（７）：ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成するグラフ生成手段、
を有し、
前記第１及び前記第２の着目手段は、前記ポインタ参照ロード命令及び前記データ依存ロード命令をロード依存グラフに基づき検出することを特徴とする（１）〜（６）のいずれかに記載のコード変換装置。
【００９６】
（８）：ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについてバイトコードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録するアドレス記録手段、
を有し、
前記第１及び第２の検出手段は、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する、
ことを特徴とする（７）記載のコード変換装置。
（９）：データＵb,2のプリフェッチが有意義か否かを予測する予測手段、
前記予測手段が有意義でないと予測した場合には、前記第１及び前記第２の機械語生成手段による前記機械語コード部分Ｈ１，Ｈ２の生成を中止させる中止手段、
を有していることを特徴とする（１）〜（８）のいずれかに記載のコード変換装置。
（１０）：データＵb,2をロードするデータ依存ロード命令を対象データ依存ロード命令、該対象データ依存ロード命令と呼ぶことにし、
前記予測手段は、データＵb,2にデータ依存する命令が存在する場合、及び／又は対象データ依存ロード命令とは別のデータ依存ロード命令がロードするデータＸに対して該データＸ用の機械語コード部分Ｈ２がすでに生成されていてデータＵb,2はデータＸとは同一のキャッシュラインには入らない場合、プリフェッチ命令の挿入が有意義と予測することを特徴とする（９）記載のコード変換装置。
（１１）：式：Ｕa,0＋ｐ・Ｆｘに基づきアドレス（Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ３を生成する第３の機械語コード部分生成手段、及び
キャッシュラインのサイズＦｓとしてＦｓ≧が２・Ｆｘであるならば前記第３の機械語コード部分生成手段による機械語コード部分Ｈ３の生成は中止とする制御手段、
を有していることを特徴とする（１）〜（１０）のいずれかに記載のコード変換装置。
【００９７】
（１２）：バイトコードを実行するJava仮想計算機からの指示を受けて指示範囲のバイトコードを機械語コードへ変換するJITコンパイラにおいて、
指示範囲のバイトコードの部分を機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する情報収集手段、及び
前記情報収集手段による収集情報に基づいて指示範囲のバイトコードを機械語コードへ変換する変換手段、
を有していることを特徴とするJITコンパイラ。
（１３）：前記変換手段は、前記情報収集手段による収集情報に依らずに指示範囲のバイトコードを変換された機械語コードに対して前記情報収集手段による収集情報に基づく機械語コード部分を追加した機械語コードを生成するものである、
ことを特徴とする（１２）記載のJITコンパイラ。
（１４）：前記収集情報は、ループＡ内の各イテレーションにおける所定ロード命令がヒープメモリから参照するデータのアドレスの規則性に係る情報を含み、
前記変換手段は、前記収集情報に基づき所定ロード命令に基づくロードデータをヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分を生成するものであることを特徴とする（１２）又は（１３）記載のJITコンパイラ。
【００９８】
（１５）：変換処理対象コードを機械語コードへ変換するコード変換方法において、
所定のループＡにおける複数個のイテレーションの内で連続する所定個数ｎのイテレーションＢ1，Ｂ2，〜，Ｂn（なお、Ｂ1はループＡにおける１番目のイテレーションＢであることに限定されない。）を選択しそれらイテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上のポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に着目する第１の着目ステップ、
各イテレーションＢ1，Ｂ2，〜，Ｂnにおける変換処理対象コード上の他のロード命令であってポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1にデータ依存するロード命令としてのデータ依存ロード命令Ｃ1,2，Ｃ2,2，〜，Ｃn,2に着目する第２の着目ステップ、
ポインタ参照ロード命令Ｃ1,1，Ｃ2,1，〜，Ｃn,1に基づきプロセッサがロードするデータとしての参照値Ｕ1,1，Ｕ2,1，〜，Ｕn,1に対してそれらがヒープメモリにおいて格納されているアドレスＵ1,0，Ｕ2,0，〜，Ｕn,0を検出する第１の検出ステップ、
前記データ依存ロード命令Ｃr,2〜Ｃs,2（ただし１≦ｒ＜ｓ≦ｎ）に基づきプロセッサがロードするデータＵr,2，Ｕr+1,2，〜，Ｕs,2に対してそれらがヒープメモリにおいて格納されているアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yを検出する第２の検出ステップ、
相互に隣接するイテレーションの前記ポインタ参照ロード命令のロードデータのアドレスの差分Ｕ2,0−Ｕ1,0，Ｕ3,0−Ｕ2,0，〜，Ｕn,0−Ｕn-1,0をイテレーション間ストライドＦ１として計算する第１の計算ステップ、
各イテレーションにおける前記ポインタ参照ロード命令の参照値Ｕr,1，Ｕr+1,1，〜，Ｕs,1と前記データ依存ロード命令のロードデータのアドレスＵr,y，Ｕr+1,y，〜，Ｕs,yとの差分Ｕr,y−Ｕr,1，Ｕr+1,y−Ｕr+1,1，Ｕs,y−Ｕs,1をイテレーション内ストライドＦ２として計算する第２の計算ステップ、
相互に同一となっているイテレーション間ストライドＦ１がイテレーション間ストライドＦ１の総数に対して第１の割合以上存在しかつ相互に同一となっているイテレーション内ストライドＦ２がイテレーション内ストライドＦ２の総数に対して第２の割合以上存在すると言う条件が満たされるか否かを判定する判定ステップ、
前記判定ステップにおける判定が「正」である場合には該同一のイテレーション間ストライドＦ１及び該同一のイテレーション内ストライドＦ２に基づいてそれぞれイテレーション間定数ストライドＦｘ及びイテレーション内定数ストライドＦｙを設定する設定ステップ、
ループＡのイテレーションＢaにおけるポインタ参照ロード命令Ｃa,1に基づいてプロセッサがロードするデータＵa,1がヒープメモリにおいて格納されているアドレスＵa,0及び自然数ｐ（ただし、イテレーションＢaよりｐ個、後のイテレーションをイテレーションＢbとすると、イテレーションＢbはループＡの最後のイテレーションを越えない。）に対してヒープメモリ上のアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）にアクセスして該アドレスＵb,0のデータＵb,1を検出する機械語コード部分Ｈ１を生成する第１の機械語コード部分生成ステップ、及び
プロセッサがループＡのイテレーションＢbを実行するのに先立ち、ヒープメモリ上のアドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ２を生成する第２の機械語コード部分生成ステップ、
を有していることを特徴とするコード変換方法。
【００９９】
（１６）：前記変換処理対象コードはJavaのバイトコードであることを特徴とする（１５）記載のコード変換方法。
（１７）：前記コード変換方法はJITコンパイラであることを特徴とする（１５）又は（１６）に記載のコード変換方法。
（１８）：前記第１及び前記第２の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ１，Ｈ２を、前記イテレーションＢaを実行する機械語コード範囲に配置することを特徴とする（１５）〜（１７）のいずれかに記載のコード変換方法。
（１９）：機械語としてプリフェッチ命令Ｊ１及び投機的ロード命令Ｊ２を装備するプロセッサ用のコード変換方法において、
前記第１の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ１が、アドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をロードする投機的ロード命令Ｊ２を含むように、前記機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ２が、アドレス（Ｕb,1＋Ｆｙ）のデータＵb,2をプリフェッチするプリフェッチ命令Ｊ１を含むように、前記機械語コード部分Ｈ２を生成する、
ことを特徴とする（１５）〜（１８）のいずれかに記載のコード変換方法。
（２０）：機械語としてプリフェッチ命令Ｊ１及びロード命令Ｊ３を装備するプロセッサ用のコード変換方法において、
前記第１の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ１が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレスＵb,0（＝Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1を検出する処理を含むように、機械語コード部分Ｈ１を生成し、
前記第２の機械語コード部分生成ステップでは、前記機械語コード部分Ｈ２が、アクセス違反を調べる条件用分岐命令によりガードされたロード命令Ｊ３によりアドレス（Ｕb,1＋Ｆｙ）のデータＶb２をプリフェッチする処理を含むように、機械語コード部分Ｈ２を生成する、
ことを特徴とする（１５）〜（１８）のいずれかに記載のコード変換方法。
（２１）：ループＡ内のロード命令の依存関係を表現するグラフとしてのロード依存グラフを生成するグラフ生成ステップ、
を有し、
前記第１及び前記第２の着目ステップでは、前記ポインタ参照ロード命令及び前記データ依存ロード命令をロード依存グラフに基づき検出することを特徴とする（１５）〜（２０）のいずれかに記載のコード変換方法。
【０１００】
（２２）：ループＡにおけるイテレーションＢ1，Ｂ2，〜，Ｂnについてバイトコードを機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行して、各イテレーションのロード命令によるロードデータのアドレスをロード依存グラフに記録するアドレス記録ステップ、
を有し、
前記第１及び第２の検出ステップでは、ロード依存グラフに記録されたアドレスに基づきアドレスＵ1,0〜アドレスＵn,0及びアドレスＵr,1〜アドレスＵs,1を検出する、
ことを特徴とする（２１）記載のコード変換方法。
（２３）：データＵb,2のプリフェッチが有意義か否かを予測する予測ステップ、
前記予測ステップにおいて有意義でないと予測した場合には、前記第１及び前記第２の機械語生成ステップにおける前記機械語コード部分Ｈ１，Ｈ２の生成を中止させる中止ステップ、
を有していることを特徴とする（１５）〜（２２）のいずれかに記載のコード変換装置。
（２４）：データＵb,2をロードするデータ依存ロード命令を対象データ依存ロード命令、該対象データ依存ロード命令と呼ぶことにし、
前記予測ステップでは、データＵb,2にデータ依存する命令が存在する場合、及び／又は対象データ依存ロード命令とは別のデータ依存ロード命令がロードするデータＸに対して該データＸ用の機械語コード部分Ｈ２がすでに生成されていてデータＵb,2はデータＸとは同一のキャッシュラインには入らない場合、プリフェッチ命令の挿入が有意義と予測することを特徴とする（２３）記載のコード変換装置。
（２５）：式：Ｕa,0＋ｐ・Ｆｘに基づきアドレス（Ｕa,0＋ｐ・Ｆｘ）のデータＵb,1をヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分Ｈ３を生成する第３の機械語コード部分生成ステップ、及び
キャッシュラインのサイズＦｓとしてＦｓ≧が２・Ｆｘであるならば前記第３の機械語コード部分生成ステップにおける機械語コード部分Ｈ３の生成は中止とする制御ステップ、
を有していることを特徴とする（１５）〜（２４）のいずれかに記載のコード変換装置。
【０１０１】
（２６）：バイトコードを実行するJava仮想計算機からの指示を受けて指示範囲のバイトコードを機械語コードへ変換するJITコンパイル方法において、
指示範囲のバイトコードの部分を機械語コードへ試し実行用にコンパイルし試し実行用機械語コードを、副作用を起こさずに試し実行してヒープメモリにおけるデータ構造についての情報を収集する情報収集ステップ、及び
前記情報収集ステップにおける収集情報に基づいて指示範囲のバイトコードを機械語コードへ変換する変換ステップ、
を有していることを特徴とするJITコンパイル方法。
（２７）：前記変換ステップでは、前記情報収集ステップにおける収集情報に依らずに指示範囲のバイトコードを変換された機械語コードに対して前記情報収集ステップにおける収集情報に基づく機械語コード部分を追加した機械語コードを生成する、
ことを特徴とする（２６）記載のJITコンパイル方法。
（２８）：前記収集情報は、ループＡ内の各イテレーションにおける所定ロード命令がヒープメモリから参照するデータのアドレスの規則性に係る情報を含み、
前記変換ステップでは、前記収集情報に基づき所定ロード命令に基づくロードデータをヒープメモリからキャッシュメモリへプリフェッチする機械語コード部分を生成する、
ことを特徴とする（２６）又は（２７）に記載のJITコンパイル方法。
（２９）：（１）〜（１１）のいずれかに記載のコード変換装置の各手段としてコンピュータを機能させるためのコード変換用プログラム。
（３０）：（１２）〜（１４）のいずれかに記載のJITコンパイラの各手段としてコンピュータを機能させるためのJITコンパイラ用プログラム。
【０１０２】
【発明の効果】
本発明では、ループの各イテレーションにおけるポインタ参照ロード命令についてイテレーション間定数ストライドを検出するとともに、イテレーション間定数ストライドをもつポインタ参照ロード命令に基づいてロードされるデータとしての参照アドレスに対してイテレーション内定数ストライド関係にあるデータをプリフェッチする機械語コード部分を生成する。結果、機械語コードの実行では、キャッシュミスを抑制して、プログラムの実行速度を増大できる。
【図面の簡単な説明】
【図１】サンプルプログラムにおいて外側のループで辿るTokenオブジェクトに関連したデータ構造の説明図である。
【図２】サンプルプログラムにおいて二重ループに含まれるロード命令とそれが参照するデータの、ヒープメモリ上のアドレスとの関係を示す図である。
【図３】第１の擬似プログラムの実行過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。
【図４】サンプルプログラムにおけるロード命令に対応するロード依存グラフである。
【図５】第２の擬似プログラムの実行過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。
【図６】SPECjvm98ベンチマーク及びJavaGrande v2.0ベンチマークSection 3のPentium 4上での速度能向上率を示す図である。
【図７】SPECjvm98ベンチマーク及びJavaGrande v2.0ベンチマークSection 3のPentium 4上で実行した場合のコンパイル時間のオーバーヘッドを示す図である。
【図８】コード変換装置の機能ブロック図である。
【図９】コード変換装置が処理過程において関わるデータ及びアドレスを図１のデータ構造上に表示した図である。
【図１０】コード変換装置の構成をさらに具体化して示したものである。
【図１１】コード変換装置の機能付加部を示す図である。
【図１２】コード変換方法のフローチャートである。
【図１３】図１２のフローチャートにステップを追加したフローチャートの主要部である。
【図１４】図１２のフローチャートに別のステップを追加したフローチャートの主要部である。
【図１５】JITコンパイラの構成をJava仮想計算機と共に示す図である。
【図１６】JITコンパイル方法のフローチャートである。
【図１７】プログラムを実行するためのハードウェア構成図である。
【符号の説明】
１０：コード変換装置、１１：変換処理対象コード、１２：機械語コード、１５：第１の着目手段、１６：第２の着目手段、１７：第１の検出手段、１８：第２の検出手段、１９：第１の計算手段、２０：第２の計算手段、２１：判定手段、２３：第１の機械語コード部分生成手段、２４：第２の機械語コード部分生成手段、２６：グラフ生成手段、２８：アドレス記録手段２８、３１：予測手段、５５：Java仮想計算機、５７：JITコンパイラ、５８：情報収集手段、５９：変換手段。
【図１】
0004064869.tif 000002
【図２】
0004064869.tif 000003
【図３】
0004064869.tif 000004
【図４】
0004064869.tif 000005
【図５】
0004064869.tif 000006
【図６】
0004064869.tif 000007
【図７】
0004064869.tif 000008
【図８】
0004064869.tif 000009
【図９】
0004064869.tif 000010
【図１０】
0004064869.tif 000011
【図１１】
0004064869.tif 000012
【図１２】
0004064869.tif 000013
【図１３】
0004064869.tif 000014
【図１４】
0004064869.tif 000015
【図１５】
0004064869.tif 000016
【図１６】
0004064869.tif 000017
【図１７】
0004064869.tif 000018