(57)【要約】【課題】リフィル処理を適正なリフィルサイズ及び適正なリフィルタイミングで行う。【解決手段】キャッシュメモリへの転送を行うリフィル範囲を対象プログラムにおいて検出し、検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記対象プログラム中に埋め込む。前記リフィル範囲は、例えば、関数部分、ループ部分等である。【選択図】  図１
2005018614.tif 000002
【特許請求の範囲】
【請求項１】
キャッシュメモリへの転送を行うリフィル範囲を対象プログラムにおいて検出するリフィル範囲検出ステップと、
検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記対象プログラム中に埋め込むリフィル命令埋込みステップと、を備えることを特徴とするコード生成プログラム。
【請求項２】
前記リフィル範囲検出ステップは、前記リフィル範囲として、前記対象プログラム中における関数部分を検出することを特徴とする請求項１に記載のコード生成プログラム。
【請求項３】
前記関数部分は、他の関数を呼び出すコール命令を有しており、
前記リフィル範囲検出ステップは、前記関数部分において前記コール命令の次の命令以降の命令列を前記リフィル範囲として検出することを特徴とする請求項２に記載のコード生成プログラム。
【請求項４】
前記リフィル範囲検出ステップは、前記リフィル範囲として、前記対象プログラム中におけるループ部分を検出することを特徴とする請求項１に記載のコード生成プログラム。
【請求項５】
入力プログラムを変換して目的プログラムを生成するコンパイラであって、
前記入力プログラムを中間言語コードに変換する入力プログラム変換ステップと、
キャッシュメモリへの転送を行うリフィル範囲を前記中間言語コードにおいて検出するリフィル範囲検出ステップと、
検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記中間言語コード中に埋め込むリフィル命令埋込みステップと、
前記リフィル命令が埋め込まれた前記中間言語コードを変換して前記目的プログラムを生成する目的プログラム生成ステップと、を備えることを特徴とするコンパイラ。
【請求項６】
キャッシュメモリへの転送を行うリフィル範囲を対象プログラムにおいて検出し、検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記対象プログラム中に埋め込むことを特徴とするコード生成方法。
【請求項７】
メモリ上にロードされた特定の命令列をキャッシュメモリに転送することを指示するリフィル命令に対応した命令を命令セットの一部として備えたプロセッサ。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、コード生成プログラム、コンパイラ、コード生成方法及びプロセッサに関する。
【０００２】
【従来の技術】
一般に、キャッシュメモリのリフィル処理は、プロセッサからキャッシュメモリへのアクセスがミスヒットした場合に、ハードウェアで自動的に行われる。即ち、あらかじめ決められたサイズ（例えば４ワード、８ワード等）の命令あるいはデータがメインメモリからキャッシュメモリにバースト転送される。
【０００３】
【非特許文献１】
株式会社  東芝  セミコンダクター社、“３２ビット  ＴＸ  Ｓｙｓｔｅｍ  ＲＩＳＣ  ＴＸ３９／Ｈ３  コア  アーキテクチャ”（第８章キャッシュ  ８．１命令キャッシュ）
【０００４】
【発明が解決しようとする課題】
上述のようにリフィル処理ではあらかじめ決められたサイズ分の命令等が転送される。つまり、ハードウェアでは最適なリフィルサイズがわからない。このため、メインメモリ上で連続した領域に格納された命令列が、複数回のリフィル処理により転送されることもある。この場合、リフィル処理ごとに発生するオーバーヘッドがかさみ、転送速度が低下するという問題がある。
【０００５】
本発明は、上記問題点に鑑みてなされたものであり、その目的は、適正なリフィルサイズでリフィル処理を行うことを可能にするコード生成プログラム、コンパイラ、コード生成方法及びプロセッサを提供することにある。
【０００６】
【課題を解決するための手段】
本発明のコード生成プログラムは、キャッシュメモリへの転送を行うリフィル範囲を対象プログラムにおいて検出するリフィル範囲検出ステップと、検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記対象プログラム中に埋め込むリフィル命令埋込みステップと、を備えることを特徴とする。
【０００７】
ここで、前記リフィル範囲検出ステップは、前記リフィル範囲として、前記対象プログラム中における関数部分を検出する。
【０００８】
また、前記関数部分は、他の関数を呼び出すコール命令を有しており、前記リフィル範囲検出ステップは、前記関数部分において前記コール命令の次の命令以降の命令列（例えば次のコール命令までの命令列）を前記リフィル範囲として検出する。
【０００９】
また、前記リフィル範囲検出ステップは、前記リフィル範囲として、前記対象プログラム中におけるループ部分を検出する。
【００１０】
本発明のコンパイラは、入力プログラムを変換して目的プログラムを生成するコンパイラであって、前記入力プログラムを中間言語コードに変換する入力プログラム変換ステップと、キャッシュメモリへの転送を行うリフィル範囲を前記中間言語コードにおいて検出するリフィル範囲検出ステップと、検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記中間言語コード中に埋め込むリフィル命令埋込みステップと、前記リフィル命令が埋め込まれた前記中間言語コードを変換して前記目的プログラムを生成する目的プログラム生成ステップと、を備えることを特徴とする。
【００１１】
本発明のコード生成方法は、キャッシュメモリへの転送を行うリフィル範囲を対象プログラムにおいて検出し、検出された前記リフィル範囲を前記キャッシュメモリに転送することを指示するリフィル命令を前記対象プログラム中に埋め込むことを特徴とする。
【００１２】
本発明のプロセッサは、メモリ上にロードされた特定の命令列をキャッシュメモリに転送することを指示するリフィル命令に対応した命令を命令セットの一部として備えることを特徴とする。
【００１３】
【発明の実施の形態】
先ず、本発明の実施の形態の特徴について簡単に説明する。
【００１４】
本発明の実施の形態では、対象プログラム中の所定の範囲（例えば関数やループ）をキャッシュメモリに転送することを指示するリフィル命令を用意する。本実施の形態では、このリフィル命令を、対象プログラム中の関数やループ等の入口に埋め込む。これにより、対象プログラムの実行時には、関数やループ等の実行に先だってリフィル命令が実行されて、これら関数やループ等は一度にキャッシュメモリに転送される。この後、これら関数やループはキャッシュミスを生じさせることなく実行され、従って、高速なプログラムの実行が可能となる。以下、本発明の実施の形態について詳しく述べる。
【００１５】
（第１の実施の形態）
図３は、本実施の形態にかかるコンパイラを実行する装置を示す概略構成図である。
【００１６】
この装置は、コンピュータが一般的に備える、プロセッサ１、キャッシュメモリ２，メインメモリ３、補助記憶装置４を有する。プロセッサ１は、本実施の形態の特徴であるリフィル命令に対応した命令を命令セットの一部として有する。
【００１７】
補助記憶装置４には、本実施の形態にかかるコンパイラと、このコンパイラによって呼び出されるコード生成プログラムと、このコンパイラへの入力となる、高級言語によるソース・プログラムがあらかじめ格納されている。また、補助記憶装置４には、リンク処理の際に用いるライブラリ・ファイルがあらかじめ格納されている。
【００１８】
一方、この補助記憶装置４には、後述するように、コンパイラの実行中に生成される、第１の中間コード、第２の中間コード及びアセンブリ・コード、リフィル命令追加後アセンブリ・コードが格納される。また、この補助記憶装置４には、コンパイラの結果生成されるオブジェクト・プログラム、このオブジェクト・プログラムがリンク処理されることにより生成される実行可能プログラムも格納される。
【００１９】
プロセッサ１は、補助記憶装置４内のコンパイラをメモリ３上にロードした後、キャッシュメモリ２を介して読み出し、以下のコンパイル処理を実行する。
【００２０】
図１は、コンパイルの処理手順を示すフローチャートである。
【００２１】
まず、図１に示すように、字句解析処理（ステップＳ１）においては、プロセッサ１は、補助記憶装置４に格納されたソース・プログラムを読み出し、このソース・プログラムに記述された文字列を各字句（トークン）に分割処理する。プロセッサ１は、この分割処理により、各字句を含む解析結果を取得する。ここで、ソース・プログラムの一例を図４に示す。このソース・プログラムは、連続して配置された関数Ａ及び関数Ｂを含む。関数Ａは複数の命令ＩＮＳＴＡ１〜ＩＮＳＴＡｎからなり、関数Ｂは複数の命令ＩＮＳＴＢ１〜ＩＮＳＴＢｎからなる。
【００２２】
次の構文解析処理（ステップＳ２）では、プロセッサ１は、字句解析処理（ステップＳ１）で得られた解析結果（各字句）を高級言語の文法に照らし合わせて、ソース・プログラムの構文を解析する。つまり、ソース・プログラム中のどの部分が高級言語のどの規則に対応するかを解析する。解析の結果として、プロセッサ１は、所定の中間語で記述された第１の中間コードを出力する。
【００２３】
次の最適化処理（ステップＳ３）では、プロセッサ１は、最終的に生成されるオブジェクト・プログラムが対象プロセッサで高速に実行されるように、上述の構文解析処理（ステップＳ２）で取得された第１の中間コードを最適化する。具体的には、この第１の中間コードにおけるコードの順序を入れ替えたり、無駄なコードを削除したりする。最適化の結果として、プロセッサ１は、第１の中間コードを最適化した第２の中間コードを出力する。
【００２４】
次のアセンブリ・コード生成処理（ステップＳ４）では、プロセッサ１は、最適化処理（ステップ３）で取得された第２の中間コードをアセンブリ・コードに変換する。図５に、図４のソース・プログラムから上述のステップＳ１〜Ｓ４を経て生成されたアセンブリ・コードを示す。
【００２５】
次のリフィル命令追加処理（ステップＳ５）では、プロセッサ１は、上述のアセンブリ・コードを解析して、アセンブリ・コード中に記述された関数を検出し、検出された関数の入口に、関数内の全命令列をキャッシュメモリに転送することを指示するリフィル命令を挿入する。本処理は、コンパイラが、補助記憶装置４内のコード生成プログラムを呼び出すことによって実行される。本処理の詳細な処理ステップ（第１のリフィル命令追加処理）を図２に示す。また、本処理により生成された、リフィル命令追加後のアセンブリ・コードを図６に示す。
【００２６】
図２に示すように、まず、プロセッサ１は、アセンブリ・コード（図５参照）中に関数が存在するかどうかを判断する（ステップＳ１１）。関数が存在するかどうかは、例えば“ｆｕｎｃｔｉｏｎ〜”で始まるタグ（図５の“ｆｕｎｃｔｉｏｎＡ”“ｆｕｎｃｔｉｏｎＢ”参照）が存在するかどうかで判断する。関数の終了位置は、例えば“ＲＥＴ’”（図５参照）により判断する。プロセッサ１は、関数が存在しないと判断すれば（ステップＳ１１のＮｏ）、本処理を終了する。
【００２７】
一方、プロセッサ１は、アセンブリ・コード中に関数（図５の“ｆｕｎｃｔｉｏｎＡ”参照）が存在すると判断すれば（ステップＳ１１のＹｅｓ）、その関数の末尾にラベル（図６の“ＬａｂｅｌＡ”参照）を付与するとともに、関数の先頭命令（図６のＩＮＳＴＡ’１参照）から最後の命令（図６のＲＥＴ’参照）までをキャッシュメモリに転送することを指示するリフィル命令（図６のｒｅｆｉｌｌ［ＬａｂｅｌＡ］参照）を、関数の入口（関数タグの直後）に挿入する（ステップＳ１２）。なお、上述のラベルの付与は、アセンブリ・コードの生成時（図１のステップＳ４）において行ってもよい。
【００２８】
この後、プロセッサ１は、アセンブリ・コード中に他の関数があるかどうかを判断し（ステップＳ１３）し、他の関数があると判断した場合は（ステップＳ１３のＹｅｓ）、上と同様にして、ラベル名及びリフィル命令を追加する（ステップＳ１２）（図６のＬａｂｅｌＢ、ｒｅｆｉｌｌ［ＬａｂｅｌＢ］参照）。
【００２９】
以上のようにして、アセンブリ・コード内にラベル及びリフィル命令を挿入したら、図１のオブジェクト・プログラム生成処理（ステップＳ６）に示すように、プロセッサ１は、このリフィル命令追加後のアセンブリ・コード（図６参照）をアセンブルして、対象プロセッサにより解釈可能なオブジェクト・プログラムを生成する。この後、プロセッサ１は、このオブジェクト・プログラムを、補助記憶装置４（図３参照）内におけるライブラリ・ファイル等とリンクして、対象プロセッサにより実行可能な実行可能プログラムを生成する。このリンクの際、リフィル命令におけるタグ名（例えば、図６のｒｅｆｉｌｌ［ＬａｂｅｌＡ］の“ＬａｂｅｌＡ”）は、関数の末尾アドレス（タグの直前に配置された命令のアドレス）（図７のＲＥＴ”参照）に変換される。
【００３０】
次に、上述の実行可能プログラムをプロセッサ１が実行して、リフィル命令が行われる例を説明する。
【００３１】
図７は、リフィル命令の実行例を説明するための図である。
【００３２】
図７に示すように、メインメモリ３上には、上述のソース・プログラム等から作成された実行可能プログラムがロードされている。但し、図中には、実行可能プログラムのうち、関数Ａ（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）と、関数Ａの入口に挿入されたリフィル命令（ｒｅｆｉｌｌ［ＲＥＴ”のアドレス］）とが示されている。
【００３３】
一方、キャッシュメモリ２は、複数のブロック０，１，２・・・からなり、各ブロックには、例えば４ワード（１ワードは３２ビット）分の命令が格納される。図中のブロック０には、メインメモリ３内のリフィル命令（ｒｅｆｉｌｌ［ＲＥＴ”のアドレス］）及びこのリフィル命令の上位に格納された図示しない３ワード分の命令が、キャッシュミス時のリフィル処理により格納されている。一方、ブロック１〜ブロック７には現時点では何ら命令は格納されていないものとする。
【００３４】
以上の状態の下、プロセッサ１が図示しないプログラム・カウンタに従って、ブロック０に格納されたリフィル命令（ｒｅｆｉｌｌ［ＲＥＴ”のアドレス］）を読み取ると、キャッシュメモリ２への命令列の転送が開始される。即ち、プロセッサ１は、リフィル命令の次の命令「ＩＮＳＴＡ１」から、リフィル命令に指示されたアドレスの命令「ＲＥＴ”」までの、３２×２８ビット（ＲＥＴ”のアドレスのＰＣ相対オフセット）分の命令列（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）をメインメモリ３からキャッシュメモリ２に転送する指示を、図示しないメモリ制御回路に送出する。メモリ制御回路は、プロセッサ１からの指示に従い、メインメモリ３内の命令列（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）をキャッシュメモリ２に転送する。キャッシュメモリ２は、受け取った命令列（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）を、各ブロック１〜ブロック７に４ワードずつ分けて格納する。この後、プロセッサ１は、キャッシュメモリ２内の各命令列（ＩＮＳＴＡ”１〜ＩＮＳＴ”２７及びＲＥＴ”）を順次読み出して、実行する。即ち、プロセッサ１は、これらの命令列を、キャッシュミスを生じさせることなく、実行する。
【００３５】
次に、リフィル命令を用いて上述の各命令（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）をキャッシュメモリ２に転送するのに要する時間（本実施形態の場合）と、キャッシュミスにより各命令をキャッシュメモリ２に転送するのに要する時間（従来の場合）と比較して説明する。
【００３６】
但し、１回のリフィル処理のオーバーヘッドを４クロックとし、１ワード（本例では３２ビット）の転送には１クロック、必要とするものとする。また、キャッシュミス時にはワード数（バーストサイズ）４のリフィル処理が実行されるものとする。
【００３７】
図８は、上述の各命令（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）をキャッシュメモリ２に転送するのに要する時間を、本実施の形態と従来の場合とを比較して示す図である。
【００３８】
従来の場合では、キャッシュミス時にのみキャッシュメモリ２への転送（リフィル処理）が行われる。１回のリフィル処理では、上の設定条件に従い４ワードのみ転送されるため、全ての命令（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）（２８ワード）がリフィル処理されるには、計７（＝２８／４）回のリフィル処理（７回のキャッシュミス）が必要となる。１回のリフィル処理には、上述からも分かるように、オーバーヘッドの４クロックと、４ワードの転送に必要な４クロック（計８クロック）が必要である。従って、計７回のリフィル処理を行うには、図８（ａ）に示すように、８クロック×７＝５６クロック必要となる。
【００３９】
これに対し、本実施の形態の場合では、命令列（ＩＮＳＴＡ”１〜ＩＮＳＴＡ”２７及びＲＥＴ”）をキャッシュメモリ２に一度に転送することができる。従って、キャッシュメモリ２への転送に要する時間は、図８（ｂ）に示すように、オーバーヘッドの４クロックと、２８ワード分の転送に必要な２８クロックとの計３２クロックである。よって、本例の場合では、従来よりもキャッシュメモリ２への転送に必要な時間を５６−３２＝２４クロックだけ短縮することができる。
【００４０】
以上のように、本実施の形態によれば、リフィル命令を対象プログラム中に挿入するようにしたので、任意のタイミング及び任意のリフィルサイズでリフィル処理することができる。従って、リフィル処理に要する時間を短縮化することができるとともに、不要な命令転送を消滅させることができ、これにより、プログラムの実行速度を向上させることができる。
【００４１】
（第２の実施の形態）
第１の実施の形態では、関数の入口にのみリフィル命令を挿入したが、本実施の形態では、ある関数の中で別の関数が呼び出される場合、別の関数からの戻り先にもリフィル命令を挿入する。以下、本実施の形態について詳しく述べる。
【００４２】
図９は、ある関数の中で別の関数が呼び出されるソース・プログラム例を示す図である。
【００４３】
図９に示すように、このソース・プログラムには関数Ｄ及び関数Ｅが記述されている。関数Ｄの中で、命令ＩＮＳＴＤ１（１）〜ＩＮＳＴＤｎ（１）が実行された後、関数Ｅが呼び出される。関数Ｅ内の命令ＩＮＳＴＥ１〜ＩＮＳＴＥｎが実行されると、再び関数Ｄに戻り、関数Ｄ内の続きの命令ＩＮＳＴＤ１（２）〜ＩＮＳＴＤｎ（２）が実行される。
【００４４】
図１０は、図９のソース・プログラムに対して上述した字句解析処理〜アセンブリ・コード生成処理（図１のステップＳ１〜ステップＳ４参照）を行うことにより生成されたアセンブリ・コードである。図１０に示すように、関数Ｄ及び関数Ｅの入口にタグ“ｆｕｎｃｔｉｏｎＤ”及び“ｆｕｎｃｔｉｏｎＥ”が記述されている。
【００４５】
図１１は、このアセンブリ・コードに対して本実施の形態によるリフィル命令追加処理（第２のリフィル命令追加処理）を行うことにより生成された、リフィル命令追加後アセンブリ・コードを示す図である。
【００４６】
図１１に示すように、関数Ｄの末尾にタグ“ＬａｂｅｌＤ”が付され、タグ“ｆｕｎｃｔｉｏｎＤ”の直後、及びコール命令“ＣＡＬＬ  ｆｕｎｃｔｉｏｎＥ”の直後に、リフィル命令“ｒｅｆｉｌｌ［ＬａｂｅｌＤ］”が挿入されている。つまり、本実施の形態では、関数の入口の他に、呼び出し先関数（図１１の“ｆｕｎｃｔｉｏｎＥ”参照）からの戻り先にもリフィル命令が追加されている。
【００４７】
以下、上述の第２のリフィル命令追加処理について詳しく説明する。
【００４８】
図１２は、第２のリフィル命令追加処理のステップを示すフローチャートである。
【００４９】
まず、プロセッサ１は、アセンブリ・コード（図１０参照）中に関数が存在するかどうかを判断する（ステップＳ２１）。プロセッサ１は、関数が存在しないと判断した場合は（ステップＳ２１のＮｏ）、本処理を終了する。
【００５０】
一方、プロセッサ１は、アセンブリ・コード中に関数が存在すると判断した場合は（ステップＳ２１のＹｅｓ）（図１０の“ｆｕｎｃｔｉｏｎＤ”参照）、図１１に示すように、その関数の末尾にタグ（“ＬａｂｅｌＤ”参照）を付した後、関数の入口にリフィル命令（“ｒｅｆｉｌｌ［ＬａｂｅｌＤ］”参照）を挿入する（ステップＳ２２）。
【００５１】
次に、プロセッサ１は、その関数の中にコール命令が存在するかどうかを判断する（ステップＳ２３）。
【００５２】
プロセッサ１は、コール命令が存在すると判断した場合は（ステップＳ２３のＹｅｓ）（“ＣＡＬＬ  ｆｕｎｃｔｉｏｎＥ”参照）、そのコール命令の次の命令から、関数内の最後の命令までをリフィル処理することを指示するリフィル命令を、コール命令の直後に挿入する（ステップＳ２４）（”ＣＡＬＬ  ｆｕｎｃｔｉｏｎＥ”の直後の“ｒｅｆｉｌｌ［ＬａｂｅｌＤ］”参照）。
【００５３】
プロセッサ１は、他にコール命令が存在するかどうかを判断し（ステップＳ２５）、存在すると判断した場合は（ステップＳ２５のＹｅｓ）、上のステップＳ２４を再度行い、リフィル命令を挿入する。
【００５４】
一方、プロセッサ１は、他にコール命令が存在しないと判断した場合は（ステップＳ２５のＮｏ）、アセンブリ・コード（図１０参照）中に他の関数が存在するかどうかを判断し（ステップＳ２６）、他に関数が存在すると判断した場合は（ステップＳ２６のＹｅｓ）（“ｆｕｎｃｔｉｏｎＥ”参照）ステップＳ２２に戻る。
【００５５】
一方、プロセッサ１は、他に関数が存在しないと判断した場合は（ステップＳ２６のＮｏ）、本処理を終了する。
【００５６】
以上のように、本実施の形態によれば、関数の入口のみならず、呼び出し先関数からの戻り先においてもリフィル命令を挿入するようにしたので、関数の中で別の関数が呼び出されるようなプログラムにおいても、プログラムの実行速度を向上させることができる。即ち、第１の実施の形態のように関数の入口にのみリフィル命令を挿入すると、呼び出し先の関数におけるリフィル処理において、呼び出し元の関数においてなされたリフィル処理が上書きされてしまう可能性がある。このような場合、呼び出し先関数から呼び出し元関数に処理が戻され、呼び出し元関数内の続きの命令を実行しようとすると、キャッシュミスが発生し、プログラムの実行速度が遅くなってしまう。この点、本実施の形態によれば、戻り先においても別途、リフィル命令によるリフィル処理を行うようにしたので、このようなキャッシュミスが発生することを防ぐことができる。
【００５７】
（第３の実施の形態）
第１及び第２の実施の形態では、関数の入口や関数の戻り先にリフィル命令を挿入したが、本実施の形態では、アセンブリ・コード中のループ部分を検出し、そのループ部分の入口にリフィル命令を挿入する。以下、本実施の形態について詳しく述べる。
【００５８】
図１３は、ループを含むソース・プログラム例を示す図である。
【００５９】
図１３に示すように、このソース・プログラムにはループ“ＤＯ〜ＥＮＤ”が記述されており、ループ内には、命令ＩＮＳＴＦ１〜ＩＮＳＴＦｎが記述されている。
【００６０】
図１４は、図１３のソース・プログラムに対して上述した字句解析処理〜アセンブリ・コード生成処理（図１のステップＳ１〜ステップＳ４参照）を行うことにより得られたアセンブリ・コードを示す図である。
【００６１】
図１５は、図１４のアセンブリ・コードに対して本実施の形態によるリフィル命令追加処理（第３のリフィル命令追加処理）を行うことにより得られたリフィル命令追加後のアセンブリ・コードを示す図である。
【００６２】
図１５に示すように、本実施の形態では、ループの末尾にタグ“ＬａｂｅｌＦ”が付されるとともに、ループの入口には、ループ内の全命令列をリフィル処理することを指示するリフィル命令“ｒｅｆｉｌｌ［ＬａｂｅｌＦ］”が挿入される。
【００６３】
以下、より詳しく、第３のリフィル命令追加処理について説明する。
【００６４】
図１６は、第３のリフィル命令追加処理のステップを示すフローチャートである。
【００６５】
まず、プロセッサ１は、アセンブリ・コード（図１４参照）中にループが存在するかどうかを判断する（ステップＳ４１）。プロセッサ１は、ループが存在しないと判断した場合は（ステップＳ４１のＮｏ）、本処理を終了する。
【００６６】
一方、プロセッサ１は、アセンブリ・コード中にループが存在すると判断した場合は（ステップＳ４１のＹｅｓ）、図１５に示すように、そのループの末尾にタグ（“ＬａｂｅｌＦ”参照）を付するとともに、ループの入口に、ループ内の命令列をリフィル処理することを指示するリフィル命令（“ｒｅｆｉｌｌ［ＬａｂｅｌＦ］”参照）を挿入する（ステップＳ４２）。
【００６７】
プロセッサ１は、アセンブリ・コード（図１４参照）中に他のループがあるかどうかを判断し（ステップＳ４３）、他のループがあると判断した場合は（ステップＳ４３のＹｅｓ）、上のステップＳ４２を再度行って、タグ及びリフィル命令を挿入する。
【００６８】
一方、プロセッサ１は、他のループがないと判断した場合は（ステップＳ４３のＮｏ）、本処理を終了する。
【００６９】
ここで、以上により生成されたリフィル命令追加後のアセンブリ・コード（図１５参照）においては、ループ内にリフィル命令が挿入されたため、ループの度に、リフィル処理が行われることとなる。この問題を回避するには、例えば、図１５に示すように、リフィル命令の直後の命令“ＩＮＳＴＦ’１”にタグ名（例えばＬＯＯＰ−１）を新たに設定し、ループの戻り先（ジャンプ先）をこのタグ名に合わせるようにすればよい（例えば“ＪＵＭＰ  ＬＯＯＰ”を“ＪＵＭＰ  ＬＯＯＰ−１”とする）。
【００７０】
以上のように、本実施の形態によれば、ループの入口にリフィル命令を挿入するようにしたので、ループの実行速度を、１度目のループ処理から、高速に行うことができる。即ち、従来であれば、１度目のループ処理はキャッシュミス及びリフィル処理が繰り返し発生し、このためにプログラムの実行速度が遅くなるが、本実施の形態によれば、１度目のループ処理の開始の際に、あらかじめループ内の全ての命令をリフィル命令によりキャッシュメモリに転送するようにしたので、１度目のループ処理から高速に実行することができる。
【００７１】
以上に説明した第１〜第３の実施の形態において、リフィル命令は、アセンブリ・コード（中間語コード）に対して挿入されたが、このリフィル命令は、オブジェクトコードが生成されるまでの途中段階において生成される他の中間語コード（例えば構文解析や最適化後のコード）に対して挿入するようにしてもよい。
また、リフィル命令は、ソース・プログラム自体に、あるいはオブジェクト・プログラムに直接に、挿入するようにしてもよい。ソース・プログラムにリフィル命令を追加することは、例えば、ソース・プログラムを逐次解釈して実行するタイプの言語プログラムの場合に特に有効である。また、オブジェクト・プログラムにリフィル命令を追加することは、再コンパイルの手間を省く観点から有効である。
【００７２】
また、第１〜第３の実施の形態においては、コンパイラへの入力として高級言語によるソース・プログラムを用いたが、入力プログラムとしてアセンブリ・プログラムを用いることもできる。この場合、例えば、図１におけるステップＳ１〜ステップＳ４を省略することができる。
【００７３】
また、第１〜第３の実施の形態においては、オブジェクト・プログラムをプロセッサ１により解釈可能な機械語によるプログラムとして説明したが、オブジェクト・プログラムは、インタープリタにより解釈される、中間言語によるプログラムであってもよい。
【００７４】
また、上述した第１〜第３の実施の形態はそれぞれ別個のものとして説明したが、これら第１〜第３の実施の形態は互いに組み合わせることも可能である。
【００７５】
【発明の効果】
本発明によれば、リフィル命令を対象プログラム中に挿入するようにしたので、ソフトウェアレベルでのリフィル処理が可能となる。
【図面の簡単な説明】
【図１】第１の実施の形態にかかるコンパイラにより実現される処理手順を示すフローチャートである。
【図２】第１のリフィル命令追加処理のステップを示すフローチャートである。
【図３】本実施の形態にかかるコンパイラの実行装置を示す概略構成図である。
【図４】ソース・プログラムの一例を示す図である。
【図５】図４のソース・プログラムから生成されたアセンブリ・コードを示す。
【図６】図５のアセンブリ・コード中にリフィル命令を挿入した状態を示す図である。
【図７】リフィル処理の例を示す図である。
【図８】関数Ａにおける命令をリフィル処理するときの処理時間を従来の場合と比較して示す図である。
【図９】ある関数の中で別の関数が呼び出されるソース・プログラム例を示す図である。
【図１０】図９のソース・プログラムから生成されたアセンブリ・コードを示す図である。
【図１１】図１０のアセンブリ・コードに対して第２のリフィル命令追加処理を行うことにより生成されたリフィル命令追加後アセンブリ・コードを示す図である。
【図１２】第２のリフィル命令追加処理のステップを示すフローチャートである。
【図１３】ループを含むソース・プログラム例を示す図である。
【図１４】図１３のソース・プログラムから生成されたアセンブリ・コードを示す図である。
【図１５】図１４のアセンブリ・コードに対して第３のリフィル命令追加処理を行うことにより生成されたリフィル命令追加後アセンブリ・コードを示す図である。
【図１６】第３のリフィル命令追加処理のステップを示すフローチャートである。
【符号の説明】
１  プロセッサ
２  キャッシュメモリ
３  メインメモリ
４  補助記憶装置
【図１】
2005018614.tif 000003
【図２】
2005018614.tif 000004
【図３】
2005018614.tif 000005
【図４】
2005018614.tif 000006
【図５】
2005018614.tif 000007
【図６】
2005018614.tif 000008
【図７】
2005018614.tif 000009
【図８】
2005018614.tif 000010
【図９】
2005018614.tif 000011
【図１０】
2005018614.tif 000012
【図１１】
2005018614.tif 000013
【図１２】
2005018614.tif 000014
【図１３】
2005018614.tif 000015
【図１４】
2005018614.tif 000016
【図１５】
2005018614.tif 000017
【図１６】
2005018614.tif 000018