(57)【特許請求の範囲】
【請求項１】
コンピュータに、
第１のコードに含まれる一の分岐命令をコピーして複数の分岐命令に変換し、
分岐予測に用いられる情報を記憶する記憶領域を共用する複数のスレッドを実行可能なプロセッサにおいて、使用するスレッドに応じて前記複数の分岐命令の中から異なる分岐命令が実行されるよう制御する制御命令を生成し、
前記複数の分岐命令と前記制御命令とを含む第２のコードを生成する、
処理を実行させるコンパイルプログラム。
【請求項２】
前記プロセッサに前記第１のコードに応じた処理を実行させたときの前記第１のコードに含まれる各分岐命令の実行状況を示す実行時情報を取得し、
前記実行時情報に基づいて、前記第１のコードの中から前記一の分岐命令を選択する、
請求項１記載のコンパイルプログラム。
【請求項３】
前記実行時情報は、前記第１のコードに含まれる各分岐命令について、前記プロセッサによる分岐予測の失敗状況を示す予測ミス情報を含み、
前記予測ミス情報に基づいて前記一の分岐命令を選択する、
請求項２記載のコンパイルプログラム。
【請求項４】
前記プロセッサに前記第１のコードに応じた処理を実行させたときの前記第１のコードに含まれる命令の実行状況を示す実行時情報を取得し、
前記実行時情報に基づいて、前記第１のコードの中から前記一の分岐命令を含む命令群の範囲を選択し、前記選択した範囲の命令群をコピーする、
請求項１記載のコンパイルプログラム。
【請求項５】
コンピュータが実行するコンパイル方法であって、
第１のコードに含まれる一の分岐命令をコピーして複数の分岐命令に変換し、
分岐予測に用いられる情報を記憶する記憶領域を共用する複数のスレッドを実行可能なプロセッサにおいて、使用するスレッドに応じて前記複数の分岐命令の中から異なる分岐命令が実行されるよう制御する制御命令を生成し、
前記複数の分岐命令と前記制御命令とを含む第２のコードを生成する、
コンパイル方法。
【請求項６】
分岐命令を含む第１のコードを記憶する記憶部と、
前記第１のコードに含まれる前記分岐命令をコピーして複数の分岐命令に変換し、
分岐予測に用いられる情報を記憶する記憶領域を共用する複数のスレッドを実行可能なプロセッサにおいて、使用するスレッドに応じて前記複数の分岐命令の中から異なる分岐命令が実行されるよう制御する制御命令を生成し、
前記複数の分岐命令と前記制御命令とを含む第２のコードを生成する、変換部と、
を有するコンパイラ装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はコンパイルプログラム、コンパイル方法およびコンパイラ装置に関する。
【背景技術】
【０００２】
コンピュータのプロセッサの処理能力を向上させる技術の１つに、パイプライン処理がある。パイプライン処理では、各命令の処理をフェッチ・デコード・実行・メモリアクセスなどの複数のステージに分割し、異なるステージの処理を並列に実行可能にする。あるステージ（例えば、フェッチステージ）である命令の処理が行われているとき、これと並列に、他のステージ（例えば、デコードステージ）で他の命令の処理が行われる。
【０００３】
理想的には、処理を行っていない空きステージが生じないように、パイプラインに命令を詰め込むことが好ましい。しかし、様々な理由により、空きステージが生じてパイプラインの利用率が下がることがある。その理由の１つとして、プログラムの中に条件分岐を示す分岐命令が含まれていることが挙げられる。分岐命令が実行されると、その実行結果に応じて、ジャンプせずに次のアドレスの命令が選択されるか（ｎｏｔ−ｔａｋｅｎ）、ジャンプして離れたアドレスの命令が選択される（ｔａｋｅｎ）。分岐命令の次に実行されるべき命令は、当該分岐命令が実行ステージを通過するまで確定しないことから、実行結果を待って次の命令をパイプラインに投入すると空きステージが生じてしまう。
【０００４】
この問題に対し、プロセッサが分岐予測を行う方法が考えられる。プロセッサに含まれるハードウェアとしての分岐予測回路は、分岐命令が過去に実行されたときの分岐方向を示す履歴情報を保持しておく。例えば、分岐予測回路は、分岐命令毎に、過去数回〜数十回の分岐方向（ｔａｋｅｎまたはｎｏｔ−ｔａｋｅｎ）を示すビット列を保持しておく。
【０００５】
そして、分岐予測回路は、分岐命令がパイプラインに投入されると、履歴情報に基づいて今回の分岐方向を予測する。例えば、同じ分岐方向が連続して選択される確率が高い場合、分岐予測回路は、直近数回の分岐方向と同じ分岐方向が選択されると予測し得る。また、例えば、ｔａｋｅｎとｎｏｔ−ｔａｋｅｎが規則性をもって交互に選択されている場合、分岐予測回路は、その規則性に基づいて今回の分岐方向を予測し得る。
【０００６】
分岐方向が予測されると、予測された方向の命令が分岐命令の次にパイプラインに投入される（投機的実行）。分岐方向の予測が実際の分岐方向と合っていた場合、プロセッサは、そのままパイプライン処理を続ければよい。一方、分岐方向の予測が間違っていた場合、プロセッサは、予測に基づいて投入した命令をパイプラインから削除して正しい命令を投入し直すことになる。すなわち、予測ミスのペナルティが発生する。よって、パイプライン処理の効率は、分岐予測の精度に依存すると言うことができる。
【０００７】
また、プロセッサの処理能力を向上させる技術の１つに、ハードウェアマルチスレッディングがある。１つのスレッドの命令列を実行していると、上記の条件分岐の他にも、メモリアクセスなどの様々な要因により断片的な小さな待ち時間が発生し得る。この断片的な小さな待ち時間は、レジスタデータの入れ替えなどのコンテキストスイッチを伴う、ＯＳ（Operating System）レベルのマルチスレッディングでは削減することが難しい。よって、１つのプロセッサまたはプロセッサコアで同時に１つのスレッドのみ実行する場合、パイプラインステージなどのリソースの利用率を向上させるには限界がある。
【０００８】
そこで、ハードウェアマルチスレッディングでは、１つのプロセッサまたはプロセッサコア内において、複数のスレッドがプロセッサのリソースを同時に共有する。このプロセッサから見たスレッドを、「ハードウェアスレッド」と呼ぶことがある。プロセッサは、複数のハードウェアスレッド分のデータを、当該プロセッサのレジスタに格納しておく。そして、例えば、プロセッサは、あるハードウェアスレッドで待ち時間が発生すると、その待ち時間の間に他のハードウェアスレッドの命令をパイプラインに投入して、パイプラインのステージを埋める。この場合、パイプライン上では、あるハードウェアスレッドの命令と他のハードウェアスレッドの命令とが混在して並列に実行されることになる。コンテキストスイッチを伴わないため、ハードウェアスレッドの切替は高速に行える。
【０００９】
ＯＳからこのプロセッサまたはプロセッサコアを見ると、複数のスレッドが物理的に並列に実行されていると認識される。このため、ＯＳは論理的には、複数のハードウェアスレッドを実行するプロセッサまたはプロセッサコアを、ハードウェアスレッドの数分のプロセッサまたはプロセッサコアであると認識することがある。
【００１０】
ところで、ハードウェアマルチスレッディングと分岐予測の両方の技術を採用したプロセッサも考えられる。そのようなプロセッサでは、複数のハードウェアスレッドが、プロセッサまたはプロセッサコアが備えるリソースの１つとして、分岐命令の履歴情報を保持する分岐予測回路を共用することになる。履歴情報は、テーブル形式で保存しておくことが考えられる。例えば、分岐予測回路は、複数のハードウェアスレッドの何れかで分岐命令が実行されると、ハッシュ関数など所定の式に従って分岐命令のアドレスをテーブルのインデックスに変換し、インデックスが示すエントリを更新する。
【００１１】
スレッド間での分岐予測回路の共用に関しては、次のような技術が提案されている。プロセッサは、２つのスレッドで同じコードが実行されるとき、テーブルのインデックス範囲全体を共用する「統一モード」で動作する。一方、プロセッサは、２つのスレッドで異なるコードが実行されるとき、１つのテーブルを２分割して半分のインデックス範囲を一方のスレッドに割り当て、他の半分のインデックス範囲を他のスレッドに割り当てる「分割モード」で動作する。分割モードでは、最上位ビットがスレッド識別子に対応するように、分岐命令のアドレスからテーブルのインデックスを算出することで、テーブルを２分割する。このテーブルの使用方法は、プロセッサ内でハードウェア的に実装される。
【先行技術文献】
【特許文献】
【００１２】
【特許文献１】特開２００４−３２６７８５号公報
【発明の概要】
【発明が解決しようとする課題】
【００１３】
複数のスレッドを実行可能なプロセッサでは、同じプログラムに基づいて複数のスレッドが起動されることもあり得る。その場合、分岐予測に用いられる情報を記憶する記憶領域（例えば、テーブルの記憶領域）の共有方法が問題となる。
【００１４】
１つのスレッドで一の分岐命令が実行されると、その分岐命令のアドレスなどに応じた領域上に、分岐命令の実行結果（例えば、ｔａｋｅｎまたはｎｏｔ−ｔａｋｅｎを示すビット）が書き込まれる。また、他の１つのスレッドで分岐命令が実行されると、その分岐命令のアドレスなどに応じた領域上に、分岐命令の実行結果が書き込まれる。このとき、２つのスレッドは同じプログラムの命令を実行していることから、この２つの分岐命令が同じ命令（命令アドレスが同じ）である可能性がある。すると、２つのスレッドにより同じ情報が更新され、この情報の中に２つのスレッド分の実行結果が混在することになる。
【００１５】
複数のスレッド分の実行結果が混在する情報に基づいて分岐予測を行うと、分岐予測の精度が低下するという問題がある。例えば、１つのスレッドでは一の分岐命令の分岐方向が過去数回ｔａｋｅｎで連続しているとすると、そのスレッドにおける次の分岐方向はｔａｋｅｎであると予測し得る。また、他の１つのスレッドでは同じ分岐命令の分岐方向が過去数回ｎｏｔ−ｔａｋｅｎで連続しているとすると、そのスレッドにおける次の分岐方向はｎｏｔ−ｔａｋｅｎであると予測し得る。しかし、この２つのスレッドのｔａｋｅｎ／ｎｏｔ−ｔａｋｅｎの情報が混在していると、このような分岐予測が困難になる。
【００１６】
これに対し、ハードウェア的に分岐予測回路を改良して、同じプログラムに基づいて起動される２つのスレッドに対して、異なる記憶領域を割り当てる方法も考えられる。しかし、この方法では、既存のプロセッサの分岐予測の精度が改善されない。
【００１７】
１つの側面では、本発明は、複数のスレッドを実行可能なプロセッサにおける分岐予測の精度を向上させるコンパイルプログラム、コンパイル方法およびコンパイラ装置を提供することを目的とする。
【課題を解決するための手段】
【００１８】
１つの態様では、コンピュータに以下の処理を実行させるコンパイルプログラムが提供される。第１のコードに含まれる一の分岐命令をコピーして複数の分岐命令に変換する。分岐予測に用いられる情報を記憶する記憶領域を共用する複数のスレッドを実行可能なプロセッサにおいて、使用するスレッドに応じて複数の分岐命令の中から異なる分岐命令が実行されるよう制御する制御命令を生成する。複数の分岐命令と制御命令とを含む第２のコードを生成する。
【００１９】
また、１つの態様では、コンピュータが実行するコンパイル方法が提供される。
また、１つの態様では、記憶部と変換部とを有するコンパイラ装置が提供される。記憶部は、分岐命令を含む第１のコードを記憶する。変換部は、第１のコードに含まれる分岐命令をコピーして複数の分岐命令に変換する。変換部は、分岐予測に用いられる情報を記憶する記憶領域を共用する複数のスレッドを実行可能なプロセッサにおいて、使用するスレッドに応じて複数の分岐命令の中から異なる分岐命令が実行されるよう制御する制御命令を生成する。変換部は、複数の分岐命令と制御命令とを含む第２のコードを生成する。
【発明の効果】
【００２０】
１つの側面では、複数のスレッドを実行可能なプロセッサにおける分岐予測の精度が向上する。
【図面の簡単な説明】
【００２１】
【図１】第１の実施の形態のコンパイラ装置の例を示す図である。
【図２】コンパイラ装置のハードウェア例を示すブロック図である。
【図３】プロセッサの構造例を示すブロック図である。
【図４】履歴テーブルのエントリの競合例を示す図である。
【図５】予測精度向上の手順例を示すフローチャートである。
【図６】履歴テーブルのエントリの競合解消例を示す図である。
【図７】コンパイラ装置の機能例を示すブロック図である。
【図８】ソースコードの例を示す図である。
【図９】ソースコードの他の例を示す図である。
【図１０】ソースコードの構造例を示す図である。
【図１１】コンパイルコマンドの例を示す図である。
【図１２】収集した実行時情報の例を示す図である。
【図１３】コンパイルの手順例を示すフローチャートである。
【図１４】分岐予測最適化の手順例を示すフローチャートである。
【図１５】分岐予測最適化の手順例を示すフローチャート（続き１）である。
【図１６】分岐予測最適化の手順例を示すフローチャート（続き２）である。
【図１７】最適化コードの第１の例を示す図である。
【図１８】最適化コードの第２の例を示す図である。
【図１９】最適化コードの第３の例を示す図である。
【発明を実施するための形態】
【００２２】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
図１は、第１の実施の形態のコンパイラ装置の例を示す図である。
【００２３】
第１の実施の形態のコンパイラ装置１０は、プロセッサ２０またはこれと同等のアーキテクチャをもつプロセッサで実行されることを想定して、コードの最適化を行う。コンパイラ装置１０は、コード１３をコード１４に変換する。コード１３，１４は、命令の集合を含んでいる。コード１３は、例えば、高級言語で記述されたソースコードまたはソースコードから変換された中間コードである。コード１４は、例えば、最適化された中間コード、アセンブリコード、機械可読なオブジェクトコードなどである。
【００２４】
コンパイラ装置１０は、ユーザが操作する端末装置でもよいし、端末装置からアクセスされるサーバ装置でもよい。また、コンパイラ装置１０は、コンピュータまたは情報処理装置を用いて実装してもよい。プロセッサ２０は、コンパイラ装置１０が備えていてもよいし、コンパイラ装置１０と異なるコンピュータなどが備えていてもよい。すなわち、コンパイラ装置１０が生成するオブジェクトコードは、コンパイラ装置１０で実行されてもよいし、コンパイラ装置１０と異なるコンピュータなどで実行されてもよい。
【００２５】
コンパイラ装置１０は、記憶部１１および変換部１２を有する。記憶部１１は、コード１３を記憶する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の記憶装置でもよいし、ＨＤＤ（Hard Disk Drive）などの不揮発性の記憶装置でもよい。変換部１２は、記憶部１１に記憶されたコード１３をコード１４に変換する。変換部１２は、ＣＰＵ（Central Processing Unit）やＤＳＰ（Digital Signal Processor）などのプロセッサでもよいし、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。プロセッサは、例えば、記憶部１１または他の記憶装置に記憶されたプログラムを実行する。なお、複数のプロセッサの集合（マルチプロセッサ）を「プロセッサ」と呼んでもよい。
【００２６】
プロセッサ２０は、ハードウェアマルチスレッディングおよび分岐予測の技術を採用したプロセッサである。プロセッサ２０は、スレッド２１（スレッド＃０）、スレッド２２（スレッド＃１）および記憶領域２３を有する。プロセッサ２０がマルチコアプロセッサの場合、スレッド２１，２２および記憶領域２３は同一のコアに属し得る。
【００２７】
スレッド２１，２２は、ハードウェアスレッドと呼ばれ得る。スレッド２１，２２は、プロセッサ２０が備えるパイプラインステージや演算器などのリソースを共用する。スレッド２１，２２は、一方のスレッドのみ実行した場合に生じる空きリソースを活用することで、並列に実行され得る。例えば、プロセッサ２０は、スレッド２１，２２両方にレジスタを割り当てておき、スレッド２１に待ち時間が生じると、パイプラインにスレッド２２の命令を投入して空きステージを埋める。また、例えば、並列に動作可能な整数演算器と浮動小数点演算器とをプロセッサ２０が備えている場合、プロセッサ２０は、スレッド２１の整数演算が実行されている間、スレッド２２の浮動小数点演算を実行し得る。
【００２８】
記憶領域２３は、分岐予測に用いられる情報を記憶する。記憶領域２３は、分岐予測回路が備える半導体メモリの記憶領域でもよい。例えば、記憶領域２３は、分岐命令のアドレスまたは分岐命令のアドレスから算出されるインデックスと対応付けて、過去所定回分の分岐方向（ｔａｋｅｎまたはｎｏｔ−ｔａｋｅｎ）を示す履歴情報を記憶する。分岐予測に用いられる情報は、テーブル形式で記憶されてもよい。
【００２９】
ここで、変換部１２は、次のようにしてコード１３からコード１４を生成する。
変換部１２は、コード１３に含まれる条件分岐を示す分岐命令１５について、分岐予測の最適化を行う場合、分岐命令１５をコピーする。これにより、分岐命令１５に対応する（通常は、分岐命令１５と同じ）条件分岐を示す複数の分岐命令が得られる。図１では、分岐命令１５，１６が得られる。コピー後の分岐命令の数は、プロセッサ２０で実行されるスレッドの数と同じでもよいし、異なっていてもよい。
【００３０】
また、変換部１２は、コード１４またはコード１４から変換されたオブジェクトコードをプロセッサ２０に実行させた場合に、使用するスレッドに応じて分岐命令１５，１６の中から異なる分岐命令が実行されるよう制御する制御命令１７を生成する。制御命令１７は、例えば、スレッドＩＤを確認し、スレッド＃０のときは分岐命令１５または分岐命令１５を包含する命令群を選択し、スレッド＃１のときは分岐命令１６または分岐命令１６を包含する命令群を選択するものである。この場合、コードがスレッド２１で起動されると、分岐命令１５が実行されて分岐命令１６は実行されない。一方、スレッド２２で起動されると、分岐命令１６が実行されて分岐命令１５は選択されない。
【００３１】
そして、変換部１２は、分岐命令１５，１６と制御命令１７とを含むコード１４を生成する。コード１４が中間コードまたはアセンブリコードである場合、コード１４はプロセッサ２０で実行可能なオブジェクトコードに変換される。
【００３２】
コード１４またはコード１４から変換されたオブジェクトコードがスレッド２１，２２の両方で実行されるとき、スレッド２１では、分岐命令１５，１６のうち分岐命令１５のみが実行される。そして、例えば、記憶領域２３内の分岐命令１５の命令アドレスに応じた領域に、分岐命令１５の実行結果が書き込まれる。一方、スレッド２２では、分岐命令１５，１６のうち分岐命令１６のみが実行される。そして、例えば、記憶領域２３内の分岐命令１６の命令アドレスに応じた領域に、分岐命令１６の実行結果が書き込まれる。
【００３３】
第１の実施の形態のコンパイラ装置１０によれば、分岐予測の最適化において、コード１３に含まれる分岐命令１５がコピーされ、スレッドに応じて分岐命令１５，１６の中から異なる分岐命令を実行させるコード１４が生成される。これにより、スレッド２１，２２で同じオブジェクトコードが実行される場合であっても、各スレッドで実行される分岐命令のアドレスがずれることになる。よって、分岐予測回路を変更しなくても、スレッド２１の分岐予測に用いられる情報とスレッド２２の分岐予測に用いられる情報とが記憶領域２３内の異なる領域に書き込まれる可能性が高くなる。その結果、スレッド２１，２２に対する分岐予測の処理を分離でき、分岐予測の精度を向上させることができる。
【００３４】
［第２の実施の形態］
第２の実施の形態のコンパイラ装置１００は、高級言語で記述されたソースコードをコンパイルし、機械可読なオブジェクトコードを生成する。コンパイラ装置１００は、ユーザが操作する端末装置でもよいし、端末装置からアクセスされるサーバ装置でもよい。コンパイラ装置１００は、例えば、コンピュータを用いて実装される。その場合、コンパイラ装置１００は、ソフトウェアとしてのコンパイラを実行する。
【００３５】
図２は、コンパイラ装置のハードウェア例を示すブロック図である。
コンパイラ装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、媒体リーダ１０６および通信インタフェース１０７を有する。上記ユニットはバス１０８に接続される。ＣＰＵ１０１は第１の実施の形態の変換部１２の一例であり、ＲＡＭ１０２は第１の実施の形態の記憶部１１の一例である。
【００３６】
ＣＰＵ１０１は、プログラムの命令を実行する演算回路を含むプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを備えてもよく、コンパイラ装置１００は複数のプロセッサを備えてもよく、以下で説明する処理を複数のプロセッサまたはプロセッサコアを用いて並列に実行してもよい。また、複数のプロセッサの集合（マルチプロセッサ）を「プロセッサ」と呼んでもよい。
【００３７】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に用いるデータを一時的に記憶する揮発性の半導体メモリである。なお、コンパイラ装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数個のメモリを備えてもよい。
【００３８】
ＨＤＤ１０３は、ＯＳやミドルウェアやアプリケーションソフトウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性の記憶装置である。ＨＤＤ１０３に記憶されるプログラムには、コンパイルプログラムが含まれる。なお、コンパイラ装置１００は、フラッシュメモリやＳＳＤ（Solid State Drive）などの他の種類の記憶装置を備えてもよく、複数の不揮発性の記憶装置を備えてもよい。
【００３９】
画像信号処理部１０４は、ＣＰＵ１０１からの命令に従って、コンパイラ装置１００に接続されたディスプレイ１１１に画像を出力する。ディスプレイ１１１としては、ＣＲＴ（Cathode Ray Tube）ディスプレイ、液晶ディスプレイ（ＬＣＤ：Liquid Crystal Display）、プラズマディスプレイパネル（ＰＤＰ：Plasma Display Panel）、有機ＥＬ（ＯＥＬ：Organic Electro-Luminescence）ディスプレイなどを用いることができる。
【００４０】
入力信号処理部１０５は、コンパイラ装置１００に接続された入力デバイス１１２から入力信号を取得し、ＣＰＵ１０１に出力する。入力デバイス１１２としては、マウスやタッチパネルやタッチパッドやトラックボールなどのポインティングデバイス、キーボード、リモートコントローラ、ボタンスイッチなどを用いることができる。また、コンパイラ装置１００に、複数の種類の入力デバイスが接続されていてもよい。
【００４１】
媒体リーダ１０６は、記録媒体１１３に記録されたプログラムやデータを読み取る読み取り装置である。記録媒体１１３として、例えば、フレキシブルディスク（ＦＤ：Flexible Disk）やＨＤＤなどの磁気ディスク、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）などの光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）、半導体メモリなどを使用できる。媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータをＲＡＭ１０２またはＨＤＤ１０３に格納する。
【００４２】
通信インタフェース１０７は、ネットワーク１１４に接続され、ネットワーク１１４を介して他のコンピュータと通信を行うインタフェースである。通信インタフェース１０７は、スイッチなどの通信装置とケーブルで接続される有線通信インタフェースでもよいし、基地局と無線リンクで接続される無線通信インタフェースでもよい。
【００４３】
なお、コンパイラ装置１００は、媒体リーダ１０６を備えていなくてもよく、ユーザが操作する端末装置から制御可能である場合には画像信号処理部１０４や入力信号処理部１０５を備えていなくてもよい。また、ディスプレイ１１１や入力デバイス１１２が、コンパイラ装置１００の筐体と一体に形成されていてもよい。
【００４４】
図３は、プロセッサの構造例を示すブロック図である。
コンパイラ装置１００が生成するオブジェクトコードは、上記のＣＰＵ１０１が実行してもよいし、他のＣＰＵが実行してもよい。他のＣＰＵは、コンパイラ装置１００が備えるものでもよいし、他のコンピュータが備えるものでもよい。第２の実施の形態では、オブジェクトコードを実行するターゲットのＣＰＵとして、ＣＰＵ２００を想定する。
【００４５】
ＣＰＵ２００は、コア２１０，２２０，２３０，２４０を備える。コア２１０は、キャッシュメモリ２１１、ハードウェアスレッド２１２，２１２ａおよび分岐予測部２１６を有する。コア２２０，２３０，２４０も、コア２１０と同様のユニットを含む。なお、コアの数や各コアに含まれるハードウェアスレッドの数は、一例である。
【００４６】
キャッシュメモリ２１１は、コア２１０外にある二次キャッシュメモリまたはメインメモリに記憶された命令やデータを一時的に記憶する高速な半導体メモリである。キャッシュメモリ２１１は、一次キャッシュメモリと呼ばれることがある。キャッシュメモリ２１１は、ハードウェアスレッド２１２，２１２ａから共通に利用される。すなわち、キャッシュメモリ２１１には、ハードウェアスレッド２１２の命令やデータと、ハードウェアスレッド２１２ａの命令やデータとが混在して記憶され得る。
【００４７】
ハードウェアスレッド２１２，２１２ａは、ハードウェアマルチスレッディングによって実現されるスレッドであり、並列に実行可能な処理単位である。ＯＳからは、コア２１０は論理的に複数のコアであるように見える。ハードウェアスレッド２１２，２１２ａにはそれぞれ、スレッドＩＤが付与されている。例えば、ハードウェアスレッド２１２はスレッド＃０、ハードウェアスレッド２１２ａはスレッド＃１である。ハードウェアスレッド２１２，２１２ａは、レジスタ部２１３，２１３ａを有する。また、ハードウェアスレッド２１２，２１２ａは、演算部２１４および命令制御部２１５を共有する。
【００４８】
レジスタ部２１３，２１３ａは、演算部２１４によって用いられるデータを一次的に記憶するレジスタの集合である。レジスタ部２１３，２１３ａとキャッシュメモリ２１１の間でデータが転送される。レジスタ部２１３はハードウェアスレッド２１２のデータを記憶し、レジスタ部２１３ａはハードウェアスレッド２１２ａのデータを記憶する。ただし、１つのレジスタの集合の中から、ハードウェアスレッド２１２に割り当てるレジスタとハードウェアスレッド２１２ａに割り当てるレジスタとが動的に決定されてもよい。
【００４９】
演算部２１４は、１または２以上のパイプラインを含む。パイプラインには、命令制御部２１５によって、キャッシュメモリ２１１に記憶されたハードウェアスレッド２１２の命令またはハードウェアスレッド２１２ａの命令が投入される。演算部２１４は、ハードウェアスレッド２１２の命令の実行にレジスタ部２１３を使用し、ハードウェアスレッド２１２ａの命令の実行にレジスタ部２１３ａを使用する。演算部２１４は、パイプライン上で、ハードウェアスレッド２１２，２１２ａの命令を並列に実行することができる。
【００５０】
また、演算部２１４は、整数加減算器や浮動小数点加減算器のように、独立に動作可能な複数の種類の演算器を備えていてもよい。その場合、演算部２１４は、ハードウェアスレッド２１２，２１２ａで行われる異なる種類の演算を、並列に実行することもできる。ここで、演算部２１４のリソースは、ハードウェアスレッド２１２，２１２ａに対して固定的に割り当てられるのではなく、動的に割り当てられる。ハードウェアスレッド２１２，２１２ａは、リソースの集合を共有していると言うこともできる。これにより、１つのハードウェアスレッドのみ実行した場合に生じる不使用リソースを削減できる。
【００５１】
命令制御部２１５は、不使用リソースが少なくなるように（例えば、パイプライン上にできる限り命令が隙間なく詰め込まれるように）、演算部２１４に対するハードウェアスレッド２１２，２１２ａの命令の投入をスケジューリングする。例えば、命令制御部２１５は、ハードウェアスレッド２１２の命令を連続的に投入していき、次の命令をすぐに投入できない待ち状態になると、ハードウェアスレッド２１２ａの命令を投入する。パイプライン上には、ハードウェアスレッド２１２，２１２ａの命令を混在させることができる。命令制御部２１５は、投入した命令が何れのハードウェアスレッドのものであるか区別できるように、各命令のスレッドＩＤを管理する。
【００５２】
分岐予測部２１６は、条件分岐を示す分岐命令がキャッシュメモリ２１１から読み込まれたとき、その分岐命令の過去の分岐方向に基づいて、今回の分岐方向を予測する。分岐命令の後は、ジャンプせずに分岐命令の次の命令に進むか（ｎｏｔ−ｔａｋｅｎ）、または、ジャンプして分岐命令から離れた命令に進む（ｔａｋｅｎ）。分岐予測部２１６は、ハードウェアスレッド２１２，２１２ａによって共有される。命令制御部２１５は、分岐予測部２１６が予測した分岐方向に基づいて、分岐命令の実行結果を待たずに、分岐命令の次に演算部２１４に投入する命令を決定する（投機的実行）。
【００５３】
例えば、分岐予測部２１６は、過去の分岐方向から、ｔａｋｅｎやｎｏｔ−ｔａｋｅｎのバースト性（連続性）を判定する。バースト性がある場合、ｔａｋｅｎが数回連続していると、今回の分岐方向もｔａｋｅｎである可能性が高いと判断し得る。ｎｏｔ−ｔａｋｅｎが数回連続していると、今回の分岐方向もｎｏｔ−ｔａｋｅｎである可能性が高いと判断し得る。また、例えば、分岐予測部２１６は、過去の分岐方向から、ｔａｋｅｎとｎｏｔ−ｔａｋｅｎの変化の規則性を判定する。ｔａｋｅｎとｎｏｔ−ｔａｋｅｎが交互に現れる傾向にある場合、今回の分岐方向は前回の逆である可能性が高いと判断し得る。
【００５４】
分岐命令の履歴情報の蓄積にあたって、分岐予測部２１６は、履歴メモリ２１７を有する。履歴メモリ２１７は、後述する履歴テーブルを記憶する揮発性の半導体メモリである。分岐予測部２１６は、演算部２１４から、実行された分岐命令の命令アドレスとその実行結果を取得する。すると、分岐予測部２１６は、命令アドレスのハッシュ値を算出して履歴テーブルのインデックスを算出し、インデックスが指し示すエントリに、実行結果の情報（例えば、ｔａｋｅｎを示す「１」またはｎｏｔ−ｔａｋｅｎを示す「０」）を書き込む。１つのエントリには、直近数回から数十回分の実行結果の情報が列挙される。
【００５５】
ところで、コア２１０は、ハードウェアスレッド２１２，２１２ａを用いて、同じプログラムを並列に実行することが可能である。以下、同じプログラムが並列に実行されるときの分岐予測の問題点と、第２の実施の形態におけるその解決例について説明する。
【００５６】
図４は、履歴テーブルのエントリの競合例を示す図である。
ハードウェアスレッド２１２，２１２ａでは、同一のプログラムＡが実行されているとする。また、分岐予測部２１６の履歴メモリ２１７には、命令アドレスに対してエントリが対応付けられる履歴テーブル２１８が記憶されているとする。
【００５７】
ハードウェアスレッド２１２において、プログラムＡに含まれる一の分岐命令が実行される。すると、分岐予測部２１６は、この分岐命令の命令アドレスを、ハッシュ関数を用いて履歴テーブル２１８のインデックスに変換し、インデックスが示すエントリに分岐方向の情報を書き込む。また、ハードウェアスレッド２１２ａにおいて、ハードウェアスレッド２１２と同じ分岐命令が実行される。分岐命令が同じであり命令アドレスが同じであることから、分岐予測部２１６は、ハードウェアスレッド２１２のときと同じエントリに、ハードウェアスレッド２１２ａの分岐方向の情報を書き込む。
【００５８】
このように、履歴テーブル２１８のあるエントリの中には、ハードウェアスレッド２１２，２１２ａの分岐命令の実行結果が混在することになる。例えば、ハードウェアスレッド２１２の分岐方向が連続してｔａｋｅｎ（「１」）であり、ハードウェアスレッド２１２ａの分岐方向が連続してｎｏｔ−ｔａｋｅｎ（「０」）であっても、そのエントリの中にはｔａｋｅｎとｎｏｔ−ｔａｋｅｎとが混在することになる。
【００５９】
そして、ハードウェアスレッド２１２で上記の分岐命令が再び読み込まれると、分岐予測部２１６は、分岐命令の命令アドレスを履歴テーブル２１８のインデックスに変換し、インデックスが示す上記のエントリを参照する。分岐予測部２１６は、ハードウェアスレッド２１２，２１２ａの直近の実行結果が混在した履歴情報に基づいて、ハードウェアスレッド２１２の今回の分岐方向を予測することになる。同様に、ハードウェアスレッド２１２ａで上記の分岐命令が再び読み込まれると、分岐予測部２１６は、ハードウェアスレッド２１２，２１２ａの直近の実行結果が混在した上記の履歴情報に基づいて、ハードウェアスレッド２１２ａの今回の分岐方向を予測することになる。
【００６０】
その結果、分岐予測部２１６の予測精度が低くなり、分岐予測に失敗する（予測ミスが発生する）確率が高くなるおそれがあるという問題がある。この問題は特に、長期間で平均化すると各分岐方向の選択確率が５０％に近い分岐命令について顕著に表れる。分岐方向に長期的な偏りがなくても局所的な偏りや規則性がある場合、本来、分岐予測部２１６は、そのような偏りや規則性を判定して予測精度を向上させることができる。しかし、ハードウェアスレッド２１２，２１２ａの実行結果が混在して平均化されてしまうと、局所的な偏りや規則性を利用した分岐予測ができなくなり、予測精度が低下し得る。
【００６１】
一方で、分岐予測部２１６をハードウェア的に変更することは容易でない。そこで、第２の実施の形態では、コンパイラ装置１００がオブジェクトコードを生成するときに行う最適化処理の中に、分岐予測の精度を向上させる最適化を追加する。
【００６２】
図５は、予測精度向上の手順例を示すフローチャートである。
（Ｓ１）コンパイラ装置１００は、一次コンパイルとして、ソースコードをオブジェクトコードに変換する。このとき、コンパイラ装置１００は、オブジェクトコードの中に、このオブジェクトコードをＣＰＵ２００に実行させたときに実行状況を示す実行時情報が収集されるように命令を挿入しておく。収集する実行時情報には、各命令の実行回数、各命令の実行時間、各分岐命令の予測ミス回数などが含まれる。
【００６３】
（Ｓ２）ＣＰＵ２００は、ユーザから入力されたコマンドに応じて、ステップＳ１で生成された収集用のオブジェクトコードを実行する。このとき、ＣＰＵ２００は、オブジェクトコードに含まれる命令を受けて、各命令の実行回数や実行時間、各分岐命令の予測ミス回数などを監視し、指定されたファイルに実行時情報を継続的に書き出していく。
【００６４】
（Ｓ３）コンパイラ装置１００は、二次コンパイルとして、ソースコードをオブジェクトコードに変換するコンパイルを開始する。このとき、コンパイラ装置１００は、ユーザから入力されたコマンドに応じて、ステップＳ２で収集された実行時情報を用いて分岐予測の最適化を行う。コンパイラ装置１００は、実行時情報を参照して、分岐命令を含んでおり予測ミスの影響の大きい命令群を選択する。予測ミスの影響の大きい命令群は、予測ミスの確率が高く、且つ、相対的な実行時間（実行コスト）が大きい命令群である。
【００６５】
（Ｓ４）コンパイラ装置１００は、ステップＳ３で選択した命令群をコピーし、ハードウェアスレッド２１２，２１２ａに応じて異なる命令群を選択させる命令を付加する（多重化）。そして、コンパイラ装置１００は、二次コンパイルの結果として、分岐命令を含む命令群が多重化されたオブジェクトコードを生成する。
【００６６】
（Ｓ５）ＣＰＵ２００は、ユーザから入力されるコマンドに応じて、ステップＳ４で生成された最適化後のオブジェクトコードを実行する。このとき、多重化された範囲について、ハードウェアスレッド２１２，２１２ａは、命令アドレスの異なる命令群を実行することになる。すなわち、命令アドレスの異なる分岐命令が実行される。
【００６７】
図６は、履歴テーブルのエントリの競合解消例を示す図である。
上記の最適化が行われたプログラムＢは、スレッドＩＤがスレッド＃０であるハードウェアスレッドでのみ実行される分岐命令ｂ１と、スレッドＩＤがスレッド＃１であるハードウェアスレッドでのみ実行される分岐命令ｂ２とを含む。この２つの分岐命令は、最適化前の１つの分岐命令をコピーして得られたものであり、同一の処理内容を示している。
【００６８】
ハードウェアスレッド２１２，２１２ａの両方でプログラムＢが起動されると、ハードウェアスレッド２１２では、スレッド＃０用の分岐命令ｂ１が実行される。すると、分岐予測部２１６は、分岐命令ｂ１の命令アドレスを履歴テーブル２１８のインデックスに変換し、インデックスが示すエントリに分岐方向の情報を書き込む。一方、ハードウェアスレッド２１２ａでは、スレッド＃１用の分岐命令ｂ２が実行される。すると、分岐予測部２１６は、分岐命令ｂ２の命令アドレスを履歴テーブル２１８のインデックスに変換し、インデックスが示すエントリに分岐方向の情報を書き込む。
【００６９】
分岐命令ｂ１の命令アドレスと分岐命令ｂ２の命令アドレスは異なるため、ハードウェアスレッド２１２，２１２ａの分岐方向の情報は、履歴テーブル２１８の異なるエントリに書き込まれる可能性が高い。よって、予測ミスの影響が大きい分岐命令については、ハードウェアスレッド２１２，２１２ａの実行結果が同じエントリに混在してしまう確率を低減できる。その結果、分岐予測部２１６の予測精度を向上させることができる。
【００７０】
次に、コンパイラ装置１００が備える機能について説明する。
図７は、コンパイラ装置の機能例を示すブロック図である。
コンパイラ装置１００は、ソースコード記憶部１２１、中間コード記憶部１２２、オブジェクトコード記憶部１２３および実行時情報記憶部１２４を有する。これらのユニットは、例えば、ＲＡＭ１０２またはＨＤＤ１０３に確保した記憶領域として実現できる。また、コンパイラ装置１００は、ソースコード解析部１３１、最適化部１３２およびコード生成部１３４を有する。これらのユニットは、例えば、ＣＰＵ１０１に実行させるコンパイルプログラムのモジュールとして実装することができる。
【００７１】
ソースコード記憶部１２１は、ユーザにより高級言語を用いて記述されたソースコードを記憶する。高級言語の例としては、後で例示するＣ言語などが挙げられる。ソースコードは、コンパイラ装置１００で作成されてもよいし、他の装置で作成されてもよい。
【００７２】
中間コード記憶部１２２は、ソースコードから変換された中間コードを記憶する。中間コードは、コンパイル途中で内部的に用いられるコードであり、コンパイラ装置１００がその表現形式を任意に決定してもよい。最適化部１３２による最適化は、中間コードに対して行われる。オブジェクトコードは、中間コードから生成される。
【００７３】
オブジェクトコード記憶部１２３は、機械語で記述されたオブジェクトコードを記憶する。機械語では、命令やオペランドがビット列（数値）で表現される。ＣＰＵアーキテクチャによって使用可能な命令セットが異なるため、生成されるオブジェクトコードはターゲットのＣＰＵに依存する。第２の実施の形態で生成されるオブジェクトコードは、図３に示したＣＰＵ２００で実行されることを想定している。
【００７４】
実行時情報記憶部１２４は、オブジェクトコードの実行状況を示す実行時情報を記憶する。実行時情報は、収集機能が付加されたオブジェクトコードをＣＰＵ２００に実行させることで、ＣＰＵ２００によって生成される。実行時情報には、関数の呼び出し回数などソフトウェアレベルの実行状況を示すソフトウェア情報と、分岐予測部２１６の予測ミス回数などハードウェアレベルの実行状況を示すハードウェア情報とが含まれ得る。
【００７５】
ソースコード解析部１３１は、ソースコードが記述されたソースファイルの名称などを含むコンパイルコマンドを受け付ける。すると、ソースコード解析部１３１は、ソースコード記憶部１２１から指定されたソースファイルを読み出し、字句解析、構文解析、意味解析などのフロントエンド処理を行う。そして、ソースコード解析部１３１は、ソースコードに対応する中間コードを生成して中間コード記憶部１２２に格納する。
【００７６】
また、ソースコード解析部１３１は、コンパイルコマンドに含まれているコンパイルオプションを解析し、コンパイルオプションの内容を示すオプション情報を中間コード記憶部１２２に格納する。コンパイルオプションには、実行時情報の収集機能をもつオブジェクトコードを生成することを指示するオプションや、収集された実行時情報を用いて最適化処理を行うことを指示するオプションが含まれる。なお、実行時情報の収集や使用は、ソフトウェア情報とハードウェア情報とに分けて指示することができる。
【００７７】
最適化部１３２は、実行時間の短い効率的なオブジェクトコードが生成されるように、中間コード記憶部１２２に記憶された中間コードを書き換えることで、各種の最適化を実現する。最適化処理には、命令数の削減、命令順序の入れ替え、依存関係の命令の並列化、メモリアクセスの局所化などが含まれる。これらの最適化処理の中には、実行時情報の中のソフトウェア情報を参照して行われるものもある。また、最適化処理には、分岐予測の最適化も含まれる。最適化部１３２は、分岐命令多重化部１３３を有する。
【００７８】
分岐命令多重化部１３３は、実行時情報の中のハードウェア情報の使用を示すコンパイルオプションが指定されたとき、ハードウェア情報を用いて分岐予測の最適化を行う。分岐命令多重化部１３３は、実行時情報記憶部１２４からハードウェア情報を読み出し、ハードウェア情報に基づいて、分岐命令を含む命令範囲について予測ミスの影響度を算出する。分岐命令の予測ミス率が高いほど影響度が大きいと判断され、命令範囲の実行時間が長い（サイクル数が多い）ほど影響度が大きいと判断される。そして、分岐命令多重化部１３３は、影響度の大きい範囲の命令群を多重化する。すなわち、分岐命令多重化部１３３は、分岐命令を含む命令群をコピーし、スレッドＩＤに応じて異なる命令群が実行されるように、中間コード記憶部１２２に記憶された中間コードを書き換える。
【００７９】
コード生成部１３４は、中間コード記憶部１２２に記憶された最適化後の中間コードをオブジェクトコードに変換し、オブジェクトコード記憶部１２３に格納する。中間コードからオブジェクトコードへの変換は、アセンブリコードを経由して行われてもよい。コード生成部１３４は、収集機能付加部１３５を有する。
【００８０】
収集機能付加部１３５は、ソフトウェア情報の収集を示すコンパイルオプションが指定された場合、ソフトウェア情報を収集する命令をオブジェクトコードに挿入する。例えば、実行開始時にソフトウェア情報の継続的な出力を示すフラグをＯＮに設定し、実行終了時に当該フラグをＯＦＦに設定する命令を、オブジェクトコードに挿入しておく。また、収集機能付加部１３５は、ハードウェア情報の収集を示すコンパイルオプションが指定された場合、ハードウェア情報を収集する命令をオブジェクトコードに挿入する。例えば、実行開始時にハードウェア情報の継続的な出力を示すフラグをＯＮに設定し、実行終了時に当該フラグをＯＦＦに設定する命令を、オブジェクトコードに挿入しておく。
【００８１】
図８は、ソースコードの例を示す図である。
ソースコード１４１は、ソースコード記憶部１２１に記憶される。ソースコード１４１には、関数ｓｕｂ＿ｐａｒｅｎｔと関数ｓｕｂ＿ｃｈｉｌｄが定義されている。
【００８２】
関数ｓｕｂ＿ｐａｒｅｎｔには、ループ変数ｋを用いたループ（以下ではループｋと呼ぶことがある）が含まれる。ループｋの中で、関数ｓｕｂ＿ｃｈｉｌｄが繰り返し呼び出される。関数ｓｕｂ＿ｃｈｉｌｄには、ループ変数ｉを用いたループ（以下ではループｉと呼ぶことがある）が含まれる。ループｉには、ループ変数ｊを用いたループ（以下ではループｊと呼ぶことがある）が含まれる。すなわち、ループｉは二重ループの外側ループであり、ループｊは二重ループの内側ループである。
【００８３】
ループｊには、ｉｆ−ｅｌｓｅ文が含まれる。このｉｆ−ｅｌｓｅ文では、変数ｃｈの値がＡのときは「処理１」が実行され、変数ｃｈの値がＡでなくＢのときは「処理２」が実行され、変数ｃｈの値がＡでもＢでもないときは「処理３」が実行される。このｉｆ−ｅｌｓｅ文は、二重ループ（ループｉとループｊ）の中で繰り返し実行される。ただし、ｉｆ−ｅｌｓｅ文と同様の処理を、ｓｗｉｔｃｈ−ｃａｓｅ文を用いて表現することもできる。
【００８４】
図９は、ソースコードの他の例を示す図である。
ソースコード１４２は、ソースコード１４１と同様の処理を記述したものである。ただし、二重ループの中で、ｉｆ−ｅｌｓｅ文に代えてｓｗｉｔｃｈ−ｃａｓｅ文が用いられている。このｓｗｉｔｃｈ−ｃａｓｅ文では、変数ｃｈの値が判定され、値がＡのときは「処理１」が実行され、値がＢのときは「処理２」が実行され、それ以外のときは既定の処理として「処理３」が実行される。ｓｗｉｔｃｈ−ｃａｓｅ文は、内部的には、中間コードに変換されるときにソースコード１４１のようなｉｆ−ｅｌｓｅ文に置き換えられる。よって、ｉｆ−ｅｌｓｅ文とｓｗｉｔｃｈ−ｃａｓｅ文からは、同じ条件分岐を示す中間コードが生成されることになる。
【００８５】
図１０は、ソースコードの構造例を示す図である。
ソースコード１４１は、ソースコード解析部１３１による構文解析を通じて、図１０に示すような構造をもつプログラムとして認識される。プログラムは、１または２以上の処理単位を含む。１つの処理単位は、１つの関数や１つのループなど、ソースコード上で区切ることができる１つの纏まった命令範囲である。処理単位は、１または２以上の基本ブロックを含む。１つの基本ブロックは、開始点の命令が１つのみであり、終了点の命令以外では他の基本ブロックへ分岐することのない最小の命令列である。
【００８６】
ソースコード１４１からは、処理単位３１０，３２０，３３０，３４０，３５０が抽出される。処理単位３１０は関数ｓｕｂ＿ｐａｒｅｎｔに対応し、処理単位３２０はループｋに対応する。処理単位３３０は関数ｓｕｂ＿ｃｈｉｌｄに対応し、処理単位３４０はループｉに対応し、処理単位３５０はループｊに対応する。処理単位３１０は処理単位３２０を包含する親単位である。処理単位３４０は処理単位３５０を包含する親単位であり、処理単位３３０は処理単位３４０を包含する親単位である。
【００８７】
処理単位３２０は、基本ブロック３２１，３２２，３２３，３２４を含む。基本ブロック３２１は、ループ変数ｋの初期化やループ終了の判定を示す。基本ブロック３２１からは、基本ブロック３２２と基本ブロック３２４へと分岐する。基本ブロック３２２は、処理単位３３０の呼び出しを示す。基本ブロック３２３は、ループの繰り返しの判定を示す。基本ブロック３２３からは、基本ブロック３２２と基本ブロック３２４へと分岐する。基本ブロック３２４は、ループの終了処理を示す。
【００８８】
処理単位３４０は、基本ブロック３４１，３４２，３４３，３４４を含む。基本ブロック３４１，３４２，３４３，３４４によって表されるループ構造は、処理単位３２０と同様である。ただし、基本ブロック３４２は、処理単位３５０の呼び出しを示す。処理単位３５０は、基本ブロック３５１，３５２，３５３，３５４を含む。基本ブロック３５１，３５２，３５３，３５４によって表されるループ構造は、処理単位３２０，３４０と同様である。ただし、基本ブロック３５２は、ｉｆ−ｅｌｓｅ文による条件分岐を示す。
【００８９】
なお、ｉｆ文による条件分岐を示す基本ブロックは、ＩＦブロックと呼ぶことがある。ｉｆ−ｅｌｓｅ文による条件分岐を示す基本ブロックは、ＩＦ−ＥＬＳＥブロックと呼ぶことがある。以下では、両者を合わせてＩＦブロック群と呼ぶことがある。
【００９０】
ここで、基本ブロックのＢａｃｋ−Ｄｏｍｉｎａｔｏｒについて説明する。Ｂａｃｋ−Ｄｏｍｉｎａｔｏｒは、基本ブロック群のグラフ上で、基本ブロック毎に特定される所定の条件を満たす他の基本ブロックである。具体的には、Ｂａｃｋ−Ｄｏｍｉｎａｔｏｒは、ある基本ブロックに到達する全てのパスが共通して通過する他の基本ブロックのうち、当該基本ブロックからの距離が最小のものである。
【００９１】
例えば、処理単位３５０の中で、基本ブロック３５２のＢａｃｋ−Ｄｏｍｉｎａｔｏｒは基本ブロック３５１であり、基本ブロック３５３のＢａｃｋ−Ｄｏｍｉｎａｔｏｒは基本ブロック３５２である。基本ブロック３５４については、基本ブロック３５１から基本ブロック３５２，３５３を経由して到達するパスと、基本ブロック３５１から基本ブロック３５２，３５３を迂回して到達するパスとが存在する。よって、基本ブロック３５４のＢａｃｋ−Ｄｏｍｉｎａｔｏｒは、基本ブロック３５１になる。
【００９２】
図１１は、コンパイルコマンドの例を示す図である。
コンパイルコマンド１４３は、一次コンパイル時、すなわち、実行時情報の収集機能をもつオブジェクトコードを生成するときに入力されるコンパイルコマンドの例である。コンパイルコマンド１４４は、二次コンパイル時、すなわち、実行時情報を用いて最適化されたオブジェクトコードを生成するときに入力されるコンパイルコマンドの例である。
【００９３】
コンパイルコマンド１４３，１４４は、ソースファイル名と実行ファイル名を含む。ソースファイル名は、ソースコードが記述されたファイルのパスを示す。実行ファイル名は、生成したオブジェクトコードを格納するファイルのパスを示す。
【００９４】
コンパイルコマンド１４３は、ＯＰＴｐｒｏｆｉｌｅ：ｃｏｌｌｅｃｔオプションとＯＰＴｈｗ−ｃｏｕｎｔｅｒ：ｃｏｌｌｅｃｔオプションを含む。前者はソフトウェア情報の収集を示し、ソフトウェア情報の出力先のファイルの指定を含む。後者はハードウェア情報の収集を示し、ハードウェア情報の出力先のファイルの指定を含む。ただし、出力先のファイルは省略可能であり、省略された場合は既定のディレクトリ（例えば、実行ファイルと同じディレクトリ）の既定の名前のファイルが指定されたものとみなされる。
【００９５】
コンパイルコマンド１４４は、ＯＰＴｐｒｏｆｉｌｅ：ｕｓｅオプションとＯＰＴｈｗ−ｃｏｕｎｔｅｒ：ｕｓｅオプションを含む。前者はソフトウェア情報を用いた最適化を示し、ソフトウェア情報を記載したファイルの指定を含む。後者はハードウェア情報を用いた最適化を示し、ハードウェア情報を記載したファイルの指定を含む。ただし、入力元のファイルは省略可能であり、省略された場合は既定のディレクトリ（例えば、実行ファイルと同じディレクトリ）の既定の名称のファイルが指定されたものとみなされる。
【００９６】
また、コンパイルコマンド１４４は、コスト閾値と予測ミス閾値を含む。コスト閾値と予測ミス閾値は、後述するように、分岐予測の最適化において分岐命令を含む命令群をコピーするか否か判定するときに用いる閾値である。コスト閾値は省略可能であり、省略された場合は所定値（例えば、７）が用いられる。また、予測ミス閾値も省略可能であり、省略された場合は所定値（例えば、８）が用いられる。
【００９７】
図１２は、収集した実行時情報の例を示す図である。
実行時情報記憶部１２４には、例えば、ソフトウェア情報１４５，１４６とハードウェア情報１４７，１４８が格納される。ソフトウェア情報１４５はハードウェアスレッド２１２が出力したソフトウェア情報であり、ソフトウェア情報１４６はハードウェアスレッド２１２ａが出力したソフトウェア情報である。ハードウェア情報１４７はハードウェアスレッド２１２が出力したハードウェア情報であり、ハードウェア情報１４８はハードウェアスレッド２１２ａが出力したハードウェア情報である。
【００９８】
ソフトウェア情報１４５には、ソースコード１４１の各行について、ハードウェアスレッド２１２におけるその行の処理の実行回数が含まれる。また、ソフトウェア情報１４５には、ソースコード１４１の各処理単位（関数やループなど）について、ハードウェアスレッド２１２におけるその処理単位の実行回数が含まれる。同様に、ソフトウェア情報１４６には、ハードウェアスレッド２１２ａにおけるソースコード１４１の各行の実行回数と各処理単位の実行回数とが含まれる。なお、収集機能をもつオブジェクトコードには、各命令がソースコード１４１の何れの行や処理単位に対応するかの情報が含まれる。
【００９９】
ハードウェア情報１４７には、オブジェクトコードの各命令について、ハードウェアスレッド２１２におけるその命令の実行回数や、その命令の実行に要したサイクル数が含まれる。また、ハードウェア情報１４７には、ハードウェアスレッド２１２で実行された各分岐命令について、分岐予測部２１６の予測ミス数が含まれる。同様に、ハードウェア情報１４８には、ハードウェアスレッド２１２ａにおける各命令の実行回数やサイクル数が含まれる。また、ハードウェア情報１４８には、ハードウェアスレッド２１２ａで実行された各分岐命令について、分岐予測部２１６の予測ミス数が含まれる。なお、オブジェクトコードに含まれる命令は、命令アドレスによって識別される。
【０１００】
次に、コンパイラ装置１００が実行するコンパイルの手順について説明する。
図１３は、コンパイルの手順例を示すフローチャートである。
（Ｓ１０）ソースコード解析部１３１は、コンパイルコマンドで指定されたソースファイルからソースコードを読み出し、字句解析、構文解析、意味解析などのフロントエンド処理を行う。そして、ソースコード解析部１３１は、ソースコードを中間コードに変換し、中間コードを中間コード記憶部１２２に格納する。
【０１０１】
（Ｓ１１）ソースコード解析部１３１は、コンパイルコマンドに含まれるコンパイルオプションを解析し、コンパイルオプションの内容を中間コード記憶部１２２に格納する。コンパイルオプションには、ソフトウェア情報の収集、ハードウェア情報の収集、ソフトウェア情報を用いた最適化、ハードウェア情報を用いた最適化などを示すものがある。
【０１０２】
（Ｓ１２）最適化部１３２は、中間コード記憶部１２２に記憶された中間コードに対して、ＣＰＵアーキテクチャに依存しない汎用的な最適化を実行する。汎用的な最適化には、例えば、最終結果に影響を与えない不要な演算の削除や不要な変数の削除、依存関係のない命令の順序入れ替えや並列処理化などが含まれる。
【０１０３】
（Ｓ１３）最適化部１３２は、中間コード記憶部１２２を参照して、ソフトウェア情報を用いた最適化を示すコンパイルオプションが指定されたか判断する。当該コンパイルオプションが指定されている場合はステップＳ１４に処理が進み、当該コンパイルオプションが指定されていない場合はステップＳ１５に処理が進む。
【０１０４】
（Ｓ１４）最適化部１３２は、実行時情報記憶部１２４からコンパイルオプションで指定されたソフトウェア情報を読み出し、中間コード記憶部１２２に記憶された中間コードに対して、ソフトウェア情報を用いた最適化を実行する。ソフトウェア情報を用いた最適化には、例えば、実行頻度の高い命令列がジャンプなしで実行されるようにｉｆ−ｅｌｓｅ文の分岐方向を入れ替えることや、アクセス頻度の高いメモリ領域が局所化されるように変数の順序を入れ替えることなどが含まれる。なお、行や処理単位の実行頻度を算出するにあたり、ハードウェアスレッド２１２，２１２ａそれぞれに対応する実行頻度を算出して大きい方を採用してもよい。また、ハードウェアスレッド２１２，２１２ａの実行回数を平均化し、平均化した実行回数を用いて実行頻度を算出してもよい。
【０１０５】
（Ｓ１５）最適化部１３２は、中間コード記憶部１２２を参照して、ハードウェア情報を用いた最適化を示すコンパイルオプションが指定されたか判断する。当該コンパイルオプションが指定されている場合はステップＳ１６に処理が進み、当該コンパイルオプションが指定されていない場合はステップＳ１７に処理が進む。
【０１０６】
（Ｓ１６）最適化部１３２は、実行時情報記憶部１２４からコンパイルオプションで指定されたハードウェア情報を読み出し、中間コード記憶部１２２に記憶された中間コードに対して、ハードウェア情報を用いて後述する分岐予測の最適化を実行する。
【０１０７】
（Ｓ１７）コード生成部１３４は、中間コード記憶部１２２を参照して、ソフトウェア情報を収集するコンパイルオプションが指定されたか判断する。当該コンパイルオプションが指定されている場合はステップＳ１８に処理が進み、当該コンパイルオプションが指定されていない場合はステップＳ１９に処理が進む。
【０１０８】
（Ｓ１８）コード生成部１３４は、オブジェクトコードの先頭に、オブジェクトコードの実行中にソフトウェア情報を継続的に出力するよう指示する命令を挿入する。このとき、コード生成部１３４は、ソフトウェア情報の出力先のファイル名をオブジェクトコードに埋め込んでおく。また、コード生成部１３４は、オブジェクトコードの末尾に、ソフトウェア情報の出力を停止するよう指示する命令を挿入する。
【０１０９】
（Ｓ１９）コード生成部１３４は、中間コード記憶部１２２を参照して、ハードウェア情報を収集するコンパイルオプションが指定されたか判断する。当該コンパイルオプションが指定されている場合はステップＳ２０に処理が進み、当該コンパイルオプションが指定されていない場合はステップＳ２１に処理が進む。
【０１１０】
（Ｓ２０）コード生成部１３４は、オブジェクトコードの先頭に、オブジェクトコードの実行中にハードウェア情報を継続的に出力するよう指示する命令を挿入する。このとき、コード生成部１３４は、ハードウェア情報の出力先のファイル名をオブジェクトコードに埋め込んでおく。また、コード生成部１３４は、オブジェクトコードの末尾に、ハードウェア情報の出力を停止するよう指示する命令を挿入する。
【０１１１】
（Ｓ２１）コード生成部１３４は、中間コード記憶部１２２に記憶された中間コードをオブジェクトコードに変換し、コンパイルコマンドで指定された実行ファイルに書き込む。このオブジェクトコードには、ステップＳ１８のソフトウェア情報を収集する命令や、ステップＳ２０のハードウェア情報を収集する命令が含まれていることがある。
【０１１２】
図１４は、分岐予測最適化の手順例を示すフローチャートである。
この分岐予測最適化は、上記のステップＳ１６において実行される。
（Ｓ３０）最適化部１３２は、全ての処理単位の中で最後に実行される基本ブロックを選択する。ここで選択した基本ブロックをｃｕｒｒ＿ｂｌｋとおく。
【０１１３】
（Ｓ３１）最適化部１３２は、ｃｕｒｒ＿ｂｌｋのＢａｃｋ−Ｄｏｍｉｎａｔｏｒを検索する。すなわち、最適化部１３２は、基本ブロック群のグラフ上で、ｃｕｒｒ＿ｂｌｋに到達する全てのパスが共通して通過する基本ブロックのうち、ｃｕｒｒ＿ｂｌｋからの距離が最小のものを検索する。ここで検索された基本ブロックをｐｒｅ＿ｂｌｋとおく。
【０１１４】
（Ｓ３２）最適化部１３２は、更にｐｒｅ＿ｂｌｋのＢａｃｋ−Ｄｏｍｉｎａｔｏｒを検索し、該当する基本ブロックがあるか判断する。該当する基本ブロックがある場合、ステップＳ３３に処理が進む。その場合、ここで検索された基本ブロックをｐｒｅ２＿ｂｌｋとおく。該当する基本ブロックがない場合、ステップＳ３５に処理が進む。
【０１１５】
（Ｓ３３）最適化部１３２は、ｐｒｅ２＿ｂｌｋとｐｒｅ＿ｂｌｋの間のパスを確認し、ｐｒｅ２＿ｂｌｋの次に実行される基本ブロックがｐｒｅ＿ｂｌｋのみであるか判断する。ｐｒｅ２＿ｂｌｋとｐｒｅ＿ｂｌｋの間のパスがこの条件を満たす場合はステップＳ３５に処理が進み、条件を満たさない場合はステップＳ３４に処理が進む。
【０１１６】
（Ｓ３４）最適化部１３２は、現在のｐｒｅ２＿ｂｌｋをｐｒｅ＿ｂｌｋと読み替える。そして、ステップＳ３２に処理が進む。
（Ｓ３５）最適化部１３２は、ｐｒｅ＿ｂｌｋからｃｕｒｒ＿ｂｌｋの間に、ＩＦブロック群（ＩＦブロックまたはＩＦ−ＥＬＳＥブロック）に含まれる分岐命令が存在するか判断する。この分岐命令は、条件分岐を示す命令である。該当する分岐命令が存在する場合はステップＳ３６に処理が進み、存在しない場合はステップＳ３９に処理が進む。
【０１１７】
（Ｓ３６）最適化部１３２は、ハードウェア情報に基づいて、分岐命令を実行したときの各分岐方向（ｔａｋｅｎおよびｎｏｔ−ｔａｋｅｎ）の選択率を算出する。各分岐方向の選択率は、例えば、ハードウェア情報が示す分岐命令の実行回数および分岐命令の次に実行される命令それぞれの実行回数から算出できる。なお、選択率を算出するにあたり、ハードウェアスレッド２１２，２１２ａそれぞれに対応する選択率を算出して大きい方を採用してもよい。また、ハードウェアスレッド２１２，２１２ａの実行回数を平均化し、平均化した実行回数を用いて選択率を算出してもよい。
【０１１８】
そして、最適化部１３２は、各分岐方向の選択率が５０％に近いか判断する。選択率が５０％に近い分岐命令は、予測ミスが発生しやすいと推定できる。例えば、最適化部１３２は、選択率が５０％を中心とする所定の範囲（例えば、４０％〜６０％）に入っているか判断する。算出した選択率がこの条件を満たす場合はステップＳ３７に処理が進み、この条件を満たさない場合はステップＳ３９に処理が進む。
【０１１９】
（Ｓ３７）最適化部１３２は、現在のｐｒｅ＿ｂｌｋからｃｕｒｒ＿ｂｌｋの範囲に属する命令群を、多重化範囲の候補として抽出する。
（Ｓ３８）最適化部１３２は、ハードウェア情報に基づいて、ステップＳ３７で抽出した多重化範囲の候補の予測ミスポイントと実行コストポイントを算出する。予測ミスポイントは、その範囲に含まれる分岐命令の予測ミスの発生頻度を示す値であり、例えば、予測ミス数÷分岐命令の実行回数×１００と算出できる。実行コストポイントは、その範囲に含まれる命令の実行頻度を示す値であり、例えば、その範囲の命令の合計サイクル数÷オブジェクトコード全体の合計サイクル数×１００と算出できる。
【０１２０】
なお、予測ミスポイントや実行コストポイントを算出するにあたり、ハードウェアスレッド２１２，２１２ａそれぞれに対応する予測ミスポイントや実行コストポイントを算出して大きい方を採用してもよい。また、ハードウェアスレッド２１２，２１２ａの実行回数やサイクル数を平均化し、平均化した実行回数とサイクル数を用いて、予測ミスポイントや実行コストポイントを算出してもよい。
【０１２１】
（Ｓ３９）最適化部１３２は、ｐｒｅ＿ｂｌｋをｃｕｒｒ＿ｂｌｋと読み替える。
（Ｓ４０）最適化部１３２は、全ての処理単位の中で残りの基本ブロックが存在するか判断する。残りの基本ブロックがある場合はステップＳ３１に処理が進み、残りの基本ブロックがない場合はステップＳ４１に処理が進む。
【０１２２】
図１５は、分岐予測最適化の手順例を示すフローチャート（続き１）である。
（Ｓ４１）最適化部１３２は、多重化範囲の候補を１つ選択する。ここで選択した多重化範囲の候補をｃｕｒｒ＿ｒｅｇｉｏｎとおく。
【０１２３】
（Ｓ４２）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎを包含する親階層の処理単位があるか判断する。親階層の処理単位としては、例えば、ループを包含する外側ループや、ループを包含する関数などが挙げられる。親階層の処理単位がある場合、ステップＳ４３に処理が進む。この場合、１つ上の階層の処理単位をｐａｒ＿ｒｅｇｉｏｎとおく。親階層の処理単位がない場合、ステップＳ４６に処理が進む。
【０１２４】
（Ｓ４３）最適化部１３２は、ｐａｒ＿ｒｅｇｉｏｎの実行コストポイントを算出する。例えば、実行コストポイントとして、ｐａｒ＿ｒｅｇｉｏｎに含まれる命令の合計サイクル数÷オブジェクトコード全体の合計サイクル数×１００を算出する。ｐａｒ＿ｒｅｇｉｏｎはｃｕｒｒ＿ｒｅｇｉｏｎの命令も含むため、ｐａｒ＿ｒｅｇｉｏｎの実行コストポイントはｃｕｒｒ＿ｒｅｇｉｏｎの実行コストポイント以上である。
【０１２５】
そして、最適化部１３２は、ｐａｒ＿ｒｅｇｉｏｎの実行コストポイントとｃｕｒｒ＿ｒｅｇｉｏｎの実行コストポイントの違いが小さいか判断する。例えば、最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎの実行コストポイントが、ｐａｒ＿ｒｅｇｉｏｎの実行コストポイントの８０％以上を占めるか判断する。すなわち、ｐａｒ＿ｒｅｇｉｏｎの実行コストの多くがｃｕｒｒ＿ｒｅｇｉｏｎによって発生しているか判断する。条件を満たす場合はステップＳ４４に処理が進み、満たさない場合はステップＳ４６に処理が進む。
【０１２６】
（Ｓ４４）最適化部１３２は、ステップＳ４１で選択した多重化範囲の候補（ｃｕｒｒ＿ｒｅｇｉｏｎ）を、親階層の処理単位（ｐａｒ＿ｒｅｇｉｏｎ）まで拡大する。
（Ｓ４５）最適化部１３２は、拡大したｃｕｒｒ＿ｒｅｇｉｏｎ、すなわち、ｐａｒ＿ｒｅｇｉｏｎの予測ミスポイントを算出する。例えば、最適化部１３２は、ｐａｒ＿ｒｅｇｉｏｎに含まれる分岐命令について、予測ミス数÷分岐命令の実行回数×１００を算出する。最適化部１３２は、拡大したｃｕｒｒ＿ｒｅｇｉｏｎの予測ミスポイントおよび実行コストポイントを、ｐａｒ＿ｒｅｇｉｏｎの予測ミスポイントおよび実行コストポイントに更新する。そして、ステップＳ４２に処理が進む。
【０１２７】
（Ｓ４６）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎの予測ミスポイントが閾値以上であるか判断する。このとき、最適化部１３２は、中間コード記憶部１２２に記憶されたコンパイルオプションの内容を参照し、ユーザから予測ミス閾値が指定されている場合はその予測ミス閾値を使用する。指定されていない場合、最適化部１３２は、所定の値（例えば、８）を閾値として使用する。予測ミスポイントが閾値以上の場合はステップＳ４８に処理が進み、閾値未満の場合はステップＳ４７に処理が進む。
【０１２８】
（Ｓ４７）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎの予測ミスポイントを０に更新する。これは、予測ミス率が小さい分岐命令を最適化から除外することを意味する。
（Ｓ４８）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎの実行コストポイントが閾値以上であるか判断する。このとき、最適化部１３２は、中間コード記憶部１２２に記憶されたコンパイルオプションの内容を参照し、ユーザからコスト閾値が指定されている場合はそのコスト閾値を使用する。指定されていない場合、最適化部１３２は、所定の値（例えば、７）を閾値として使用する。実行コストポイントが閾値以上の場合はステップＳ５０に処理が進み、閾値未満の場合はステップＳ４９に処理が進む。
【０１２９】
（Ｓ４９）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎの実行コストポイントを０に更新する。これは、実行頻度が小さい分岐命令を最適化から除外することを意味する。
（Ｓ５０）最適化部１３２は、ステップＳ４１で選択されていない残りの多重化範囲の候補があるか判断する。残りの多重化範囲の候補がある場合はステップＳ４１に処理が進み、全ての多重化範囲の候補が選択された場合はステップＳ５１に処理が進む。
【０１３０】
図１６は、分岐予測最適化の手順例を示すフローチャート（続き２）である。
（Ｓ５１）最適化部１３２は、多重化範囲の候補を１つ選択する。ここで選択した多重化範囲の候補をｃｕｒｒ＿ｒｅｇｉｏｎとおく。
【０１３１】
（Ｓ５２）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎ実行コストポイント×予測ミスポイントを、ｃｕｒｒ＿ｒｅｇｉｏｎの影響度として算出する。
（Ｓ５３）最適化部１３２は、ステップＳ５２で算出した影響度が閾値以上であるか判断する。影響度の閾値は、コスト閾値×予測ミス閾値である。ユーザからコスト閾値および予測ミス閾値が指定された場合、最適化部１３２は、この２つの閾値から影響度の閾値を算出する。ユーザからコスト閾値および予測ミス閾値が指定されなかった場合、所定の値を影響度の閾値として使用する。例えば、コスト閾値の既定値が８であり、予測ミス閾値の既定値が７である場合、影響度の閾値の既定値は５６になる。影響度が閾値以上の場合はステップＳ５４に処理が進み、閾値未満の場合はステップＳ５６に処理が進む。
【０１３２】
（Ｓ５４）最適化部１３２は、ｃｕｒｒ＿ｒｅｇｉｏｎに含まれる命令群（分岐命令を含む）を、命令群のセット数がＣＰＵ２００の各コアが備えるハードウェアスレッドの数と一致するようにコピーする。ハードウェアスレッド数が２の場合、例えば、ｃｕｒｒ＿ｒｅｇｉｏｎに含まれる命令群を１回コピーして２セットの命令群を用意する。
【０１３３】
（Ｓ５５）最適化部１３２は、オブジェクトコードを実行しているハードウェアスレッドのスレッドＩＤに応じて、ステップＳ５４で得られた複数の命令群の中から１つの命令群を選択する制御構造をもつ制御命令を生成する。例えば、最適化部１３２は、複数の命令群それぞれの先頭に異なるスレッドＩＤを含むラベルを付与し、自ハードウェアスレッドのスレッドＩＤを確認して何れかのラベルにジャンプする制御命令を、複数の命令群の前に挿入する。また、コピーされた処理単位が関数である場合、例えば、最適化部１３２は、複数の関数それぞれの関数名に異なるスレッドＩＤを付加し、自ハードウェアスレッドのスレッドＩＤを確認して何れかの関数を呼び出す制御命令を生成する。
【０１３４】
（Ｓ５６）最適化部１３２は、ステップＳ５１で選択されていない残りの多重化範囲の候補があるか判断する。残りの多重化範囲の候補がある場合はステップＳ５１に処理が進み、全ての多重化範囲の候補が選択された場合は分岐予測の最適化が終了する。
【０１３５】
図１７は、最適化コードの第１の例を示す図である。
最適化コード１５１は、図８に示したソースコード１４１に対して分岐予測の最適化を行ったものである。分岐予測の最適化は中間コードに対して行われるものであるが、ここでは理解を容易にするためソースコード形式で最適化結果を示している。
【０１３６】
最適化コード１５１には、関数ｓｕｂ＿ｐａｒｅｎｔと関数ｓｕｂ＿ｃｈｉｌｄが定義されている。関数ｓｕｂ＿ｐａｒｅｎｔには、ループｋが含まれる。関数ｓｕｂ＿ｃｈｉｌｄには、ループｉが含まれる。ループｉには、ループｊが含まれる。以上の処理単位の構造は、ソースコード１４１と同じである。ただし、最適化コード１５１では、ループｊの中のＩＦ−ＥＬＳＥブロックが多重化範囲として選択されている。ループｊは、多重化結果としてコード部分１５１ａ，１５１ｂ，１５１ｃを含む。
【０１３７】
コード部分１５１ａでは、自ハードウェアスレッドのスレッドＩＤを確認し、スレッドＩＤを含むラベル（コード部分１５１ｂの先頭またはコード部分１５１ｃの先頭）にジャンプする。例えば、最適化コード１５１がハードウェアスレッド２１２で実行された場合はコード部分１５１ｂの先頭にジャンプし、最適化コード１５１がハードウェアスレッド２１２ａで実行された場合はコード部分１５１ｃの先頭にジャンプする。
【０１３８】
コード部分１５１ｂは、ソースコード１４１と同様のｉｆ−ｅｌｓｅ文を含む。コード部分１５１ｂには、条件分岐を示す分岐命令が含まれている。また、コード部分１５１ｃは、ソースコード１４１と同様のｉｆ−ｅｌｓｅ文、すなわち、コード部分１５１ｂと同じｉｆ−ｅｌｓｅ文を含む。コード部分１５１ｃには、条件分岐を示す分岐命令が含まれている。よって、最適化コード１５１がハードウェアスレッド２１２，２１２ａで実行された場合、ハードウェアスレッドに応じて異なる命令アドレスの分岐命令が選択的に実行されるものの、何れのハードウェアスレッドでも分岐命令の内容は同じになる。
【０１３９】
図１８は、最適化コードの第２の例を示す図である。
最適化コード１５２には、関数ｓｕｂ＿ｐａｒｅｎｔと関数ｓｕｂ＿ｃｈｉｌｄが定義されている。関数ｓｕｂ＿ｐａｒｅｎｔには、ループｋが含まれる。関数ｓｕｂ＿ｃｈｉｌｄには、ループｉが含まれる。以上の処理単位の構造は、ソースコード１４１と同じである。ただし、最適化コード１５２では、ループｊが多重化範囲として選択されている。ループｉには、コピーされた複数のループｊが含まれる。ループｉは、多重化結果としてコード部分１５２ａ，１５２ｂ，１５２ｃを含む。
【０１４０】
コード部分１５２ａでは、自ハードウェアスレッドのスレッドＩＤを確認し、スレッドＩＤを含むラベル（コード部分１５２ｂの先頭またはコード部分１５２ｃの先頭）にジャンプする。例えば、最適化コード１５２がハードウェアスレッド２１２で実行された場合はコード部分１５２ｂの先頭にジャンプし、最適化コード１５２がハードウェアスレッド２１２ａで実行された場合はコード部分１５２ｃの先頭にジャンプする。
【０１４１】
コード部分１５２ｂは、ソースコード１４１と同様のループｊを含む。コード部分１５２ｂには、条件分岐を示す分岐命令が含まれている。また、コード部分１５２ｃは、ソースコード１４１と同様のループｊ、すなわち、コード部分１５２ｂと同じループｊを含む。コード部分１５２ｃには、条件分岐を示す分岐命令が含まれている。よって、最適化コード１５２がハードウェアスレッド２１２，２１２ａで実行された場合、ハードウェアスレッドに応じて異なる命令アドレスの分岐命令が選択的に実行されるものの、何れのハードウェアスレッドでも分岐命令の内容は同じになる。
【０１４２】
最適化コード１５１と比較した場合、最適化コード１５２では、自ハードウェアスレッドのスレッドＩＤに応じてジャンプ先を判定するコード部分１５２ａが、ループｊの外に出ている。このため、スレッドＩＤに応じてジャンプ先を判定する回数が少なくなる。ｉｆ−ｅｌｓｅ文の実行コストがループｊの実行コストの大部分を占めている場合、このように多重化範囲を拡大することで、多重化のオーバヘッドを抑制でき、オブジェクトコードの実行効率を向上させることができる。
【０１４３】
図１９は、最適化コードの第３の例を示す図である。
最適化コード１５３では、ソースコード１４１の関数ｓｕｂ＿ｃｈｉｌｄが多重化範囲として選択されている。最適化コード１５３は、関数ｓｕｂ＿ｃｈｉｌｄ［０］（コード部分１５３ｂ）と関数ｓｕｂ＿ｃｈｉｌｄ［１］（コード部分１５３ｃ）を含む。また、最適化コード１５３には、関数ｓｕｂ＿ｐａｒｅｎｔが定義されている。関数ｓｕｂ＿ｐａｒｅｎｔには、ループｋが含まれる。ループｋは、コード部分１５３ａを含む。
【０１４４】
コード部分１５３ａでは、自ハードウェアスレッドのスレッドＩＤを確認し、スレッドＩＤを含む関数名の関数（コード部分１５３ｂまたはコード部分１５３ｃ）を呼び出す。例えば、最適化コード１５３がハードウェアスレッド２１２で実行された場合はコード部分１５３ｂの関数が呼び出され、最適化コード１５３がハードウェアスレッド２１２ａで実行された場合はコード部分１５３ｃの関数が呼び出される。
【０１４５】
コード部分１５３ｂは、元の関数ｓｕｂ＿ｃｈｉｌｄと同等の関数を含む。コード部分１５３ｂには、条件分岐を示す分岐命令が含まれている。また、コード部分１５３ｃは、元の関数ｓｕｂ＿ｃｈｉｌｄと同等の関数、すなわち、コード部分１５３ｂと同等の関数を含む。コード部分１５３ｃには、条件分岐を示す分岐命令が含まれている。よって、最適化コード１５３がハードウェアスレッド２１２，２１２ａで実行された場合、ハードウェアスレッドに応じて異なる命令アドレスの分岐命令が選択的に実行されるものの、何れのハードウェアスレッドでも分岐命令の内容は同じになる。
【０１４６】
最適化コード１５１，１５２と比較した場合、最適化コード１５３では、自ハードウェアスレッドのスレッドＩＤに応じて呼び出し先を判定するコード部分１５３ａが、ループｉの外に出ている。このため、スレッドＩＤに応じて呼び出し先を判定する回数が更に少なくなる。ｉｆ−ｅｌｓｅ文の実行コストが関数ｓｕｂ＿ｃｈｉｌｄの実行コストの大部分を占めている場合、このように多重化範囲を拡大することで、多重化のオーバヘッドを抑制でき、オブジェクトコードの実行効率を向上させることができる。
【０１４７】
第２の実施の形態のコンパイラ装置１００によれば、分岐予測の最適化において、分岐命令を含む命令群がコピーされ、スレッドＩＤに応じて異なる命令群を選択的に実行するオブジェクトコードが生成される。このため、分岐予測部２１６を共用するハードウェアスレッド２１２，２１２ａで同じオブジェクトコードが並列に実行されても、各ハードウェアスレッドで実行される分岐命令の命令アドレスがずれる。よって、分岐予測部２１６を交換しなくても、ハードウェアスレッド２１２，２１２ａの分岐方向の履歴が履歴テーブル２１８の同じエントリに書き込まれる確率を低減できる。その結果、ハードウェアスレッド２１２，２１２ａに対する分岐予測を分離でき、予測精度を向上できる。
【０１４８】
また、分岐予測の最適化を行う前のオブジェクトコードを実行したときの実行時情報が収集され、実行時情報に基づいて、最適化対象の分岐命令が絞り込まれる。よって、全ての分岐命令について当該分岐命令を含む命令群をコピーする場合よりも、オブジェクトコードのサイズを削減することができる。また、収集された実行時情報に基づいて、コピーする１セットの命令群の範囲が適宜拡大される。これにより、ハードウェアスレッドに応じて複数の命令群の中から１つの命令群を選択するオーバヘッドを削減でき、生成するオブジェクトコードの実行効率を向上させることができる。
【０１４９】
なお、前述のように、第１の実施の形態の情報処理は、コンパイラ装置１０にプログラムを実行させることで実現することができる。第２の実施の形態の情報処理は、コンパイラ装置１００にプログラムを実行させることで実現することができる。
【０１５０】
プログラムは、コンピュータ読み取り可能な記録媒体（例えば、記録媒体１１３）に記録しておくことができる。記録媒体としては、例えば、磁気ディスク、光ディスク、光磁気ディスク、半導体メモリなどを使用できる。磁気ディスクには、ＦＤおよびＨＤＤが含まれる。光ディスクには、ＣＤ、ＣＤ−Ｒ（Recordable）／ＲＷ（Rewritable）、ＤＶＤおよびＤＶＤ−Ｒ／ＲＷが含まれる。プログラムは、可搬型の記録媒体に記録されて配布されることがある。その場合、可搬型の記録媒体からＨＤＤなどの他の記録媒体（例えば、ＨＤＤ１０３）にプログラムをコピーして（インストールして）実行してもよい。
【符号の説明】
【０１５１】
１０  コンパイラ装置
１１  記憶部
１２  変換部
１３，１４  コード
１５，１６  分岐命令
１７  制御命令
２０  プロセッサ
２１，２２  スレッド
２３  記憶領域
【図１】
0006398725.tif 000002
【図２】
0006398725.tif 000003
【図３】
0006398725.tif 000004
【図４】
0006398725.tif 000005
【図５】
0006398725.tif 000006
【図６】
0006398725.tif 000007
【図７】
0006398725.tif 000008
【図８】
0006398725.tif 000009
【図９】
0006398725.tif 000010
【図１０】
0006398725.tif 000011
【図１１】
0006398725.tif 000012
【図１２】
0006398725.tif 000013
【図１３】
0006398725.tif 000014
【図１４】
0006398725.tif 000015
【図１５】
0006398725.tif 000016
【図１６】
0006398725.tif 000017
【図１７】
0006398725.tif 000018
【図１８】
0006398725.tif 000019
【図１９】
0006398725.tif 000020