(57)【要約】【課題】プロセッサにおける分岐処理の実行効率を向上させる。【解決手段】コンパイル装置１０は、コード１３の中から、それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を検出する。コンパイル装置１０は、複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が上記の複数の分岐命令よりも少ない変換命令群に変換する。コンパイル装置１０は、変換命令群に基づく処理のサイクル数が、複数の分岐命令に基づく処理のサイクル数より少ないとき、変換命令群を用いたコード１４を生成する。【選択図】図１
2015201119.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータに、
第１のコードの中から、それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を検出し、
前記複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が前記複数の分岐命令よりも少ない変換命令群に変換し、
前記変換命令群に基づく処理のサイクル数が、前記複数の分岐命令に基づく処理のサイクル数より少ないとき、前記変換命令群を用いた第２のコードを生成する、
処理を実行させるコンパイルプログラム。
【請求項２】
前記論理演算命令および前記算術演算命令の少なくとも１つは、ステータスレジスタに記憶されたフラグを参照するプロセッサ依存の命令である、
請求項１記載のコンパイルプログラム。
【請求項３】
前記複数の分岐命令は、入力値と第１の整数との比較の結果に基づいて前記ジャンプ先にジャンプするか判断する第１の分岐命令と、前記入力値と第２の整数との比較の結果に基づいて前記ジャンプ先にジャンプするか判断する第２の分岐命令とを含み、
前記変換命令群は、前記入力値と前記第１の整数と前記第２の整数とから算出される判定値に基づいて前記ジャンプ先にジャンプするか判断する第３の分岐命令を含む、
請求項１または２記載のコンパイルプログラム。
【請求項４】
コンピュータが実行するコンパイル方法であって、
第１のコードの中から、それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を検出し、
前記複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が前記複数の分岐命令よりも少ない変換命令群に変換し、
前記変換命令群に基づく処理のサイクル数が、前記複数の分岐命令に基づく処理のサイクル数より少ないとき、前記変換命令群を用いた第２のコードを生成する、
コンパイル方法。
【請求項５】
それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を含む第１のコードを記憶する記憶部と、
前記複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が前記複数の分岐命令よりも少ない変換命令群に変換し、前記変換命令群に基づく処理のサイクル数が前記複数の分岐命令に基づく処理のサイクル数より少ないとき、前記変換命令群を用いた第２のコードを生成する変換部と、
を有するコンパイル装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はコンパイルプログラム、コンパイル方法およびコンパイル装置に関する。
【背景技術】
【０００２】
現在、コンピュータのプロセッサの多くは、パイプライン処理技術を採用している。パイプライン処理技術は、各命令の処理をフェッチ・デコード・実行・メモリアクセスなどの複数のステージに分割し、異なるステージの処理を並列に実行可能にする。あるステージ（例えば、フェッチステージ）である命令の処理が行われているとき、これと並列に、他のステージ（例えば、デコードステージ）で他の命令の処理が行われる。
【０００３】
理想的には、処理を行っていない空きステージが生じないように、パイプラインに命令を詰め込むことが好ましい。しかし、様々な理由により、空きステージが生じてパイプラインの利用率が下がることがある。その理由の１つとして、プログラムの中に条件分岐を示す分岐命令が含まれていることが挙げられる。分岐命令が実行されると、その実行結果に応じて、ジャンプせずに次のアドレスの命令が選択されるか（ｎｏｔ−ｔａｋｅｎ）、ジャンプして離れたアドレスの命令が選択される（ｔａｋｅｎ）。分岐命令の次に実行されるべき命令は、当該分岐命令が実行ステージを通過するまで確定しない。分岐命令の実行結果を待って次の命令をパイプラインに投入すると、空きステージが生じてしまう。
【０００４】
また、プロセッサの中には、分岐予測技術を採用しているものもある。分岐予測では、プロセッサに含まれるハードウェアとしての分岐予測回路が、分岐命令の過去の実行結果を示す履歴情報を収集する。分岐予測回路は、次にその分岐命令が実行されるとき、履歴情報に基づいて今回の分岐方向（ｔａｋｅｎまたはｎｏｔ−ｔａｋｅｎ）を予測する。プロセッサは、分岐予測回路の予測に従って、パイプラインに投入した分岐命令の実行結果を待たずに、次の命令を選択してパイプラインに投入する（投機的実行）。
【０００５】
分岐予測に成功すれば、プロセッサはそのままパイプライン処理を続ければよいため、空きステージの発生を抑制できる。しかし、分岐予測に失敗すると、プロセッサは、予測に従って投入した命令およびそれ以降の命令をパイプラインから削除し、正しい命令を投入し直すことになる。すなわち、予測ミスのペナルティが発生する。よって、分岐予測技術を採用しても、分岐命令を多く含むプログラムを実行するときはパイプラインの利用率が低下し、プログラムの実行効率が低下するおそれがある。
【０００６】
そこで、コンパイラ最適化の中で、分岐命令が少なくなるようにプログラムを変換する技術が提案されている。ｃが真のときは変数ｖに値ｔを代入し、ｃが偽のときは変数ｖに値ｆを代入するｉｆ−ｅｌｓｅ文が、ソースコードに記載されているとする。このとき、１つの提案に係るコンパイラは、このｉｆ−ｅｌｓｅ文を次のような代入文に変換する：ｖ＝（ｔ  ａｎｄ  ｃ）ｏｒ（ｆ  ａｎｄ  ｎｏｔ  ｃ）。
【０００７】
また、マスクビット列ｍａｓｋに応じて、ｒｅｓｕｌｔ＝５＊ｄａｔａまたはｒｅｓｕｌｔ＝７＊ｄａｔａを実行するｉｆ−ｅｌｓｅ文が、ソースコードに記載されているとする。他の１つの提案に係るコンパイラは、このｉｆ−ｅｌｓｅ文を次のような代入文に変換する：ｒｅｓｕｌｔ＝（５＊ｄａｔａ  ａｎｄ  ｍａｓｋ）ｏｒ（７＊ｄａｔａ  ａｎｄｃ  ｍａｓｋ）。すなわち、ｉｆ節の命令とｅｌｓｅ節の命令を両方実行し、ｉｆ節の実行結果とマスクビット列のＡＮＤおよびｅｌｓｅ節の実行結果とマスクビット列のＡＮＤＣをそれぞれ計算し、両者の計算結果をＯＲで結合するプログラムが生成される。
【先行技術文献】
【特許文献】
【０００８】
【特許文献１】特開２００３−２０２９９１号公報
【特許文献２】特開２０１０−１８６４６７号公報
【発明の概要】
【発明が解決しようとする課題】
【０００９】
プログラムに含まれる分岐構造の１つの形態として、ジャンプ先が同一であり、それぞれが整数を対象とした比較演算の結果に応じて分岐方向を判断する複数の分岐命令が連続している形態が考えられる。上記の複数の分岐命令が連続している形態の一例として、変数ｃの値が定数ｃ１，ｃ２，…の何れかに該当するときに、ある処理が実行されるようなプログラムが挙げられる。コンピュータ内では文字は整数の文字コードとして表現されるため、文字変数ｓの値が定数ｓ１，ｓ２，…の何れかに該当するときにある処理が実行されるようなプログラムも、同様に整数の比較の問題として扱うことができる。
【００１０】
このような分岐命令群についても、コンパイラ最適化の中で、分岐命令の少ない命令群に変換することが考えられる。しかし、分岐命令群から変換される命令群は、命令数が変換前よりも顕著に多くなるおそれがある。そのため、従来のコンパイラ最適化では、上記の分岐命令群に対して分岐命令が少なくなるような変換は活用されていなかった。また、分岐命令群を実効効率の高い命令群に変換できるか否かは、プログラムを実行させるプロセッサ（ターゲットとするプロセッサ）のアーキテクチャにも依存し得る。
【００１１】
１つの側面では、本発明は、プロセッサにおける分岐処理の実行効率を向上させるコンパイルプログラム、コンパイル方法およびコンパイル装置を提供することを目的とする。
【課題を解決するための手段】
【００１２】
１つの態様では、コンピュータに以下の処理を実行させるコンパイルプログラムが提供される。第１のコードの中から、それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を検出する。複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が複数の分岐命令よりも少ない変換命令群に変換する。変換命令群に基づく処理のサイクル数が、複数の分岐命令に基づく処理のサイクル数より少ないとき、変換命令群を用いた第２のコードを生成する。
【００１３】
また、１つの態様では、コンピュータが実行するコンパイル方法が提供される。
また、１つの態様では、記憶部と変換部とを有するコンパイル装置が提供される。記憶部は、それぞれ整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一である複数の分岐命令を含む第１のコードを記憶する。変換部は、複数の分岐命令を、論理演算命令および算術演算命令を用いて分岐命令の数が複数の分岐命令よりも少ない変換命令群に変換し、変換命令群に基づく処理のサイクル数が複数の分岐命令に基づく処理のサイクル数より少ないとき、変換命令群を用いた第２のコードを生成する。
【発明の効果】
【００１４】
１つの側面では、プロセッサにおける分岐処理の実行効率が向上する。
【図面の簡単な説明】
【００１５】
【図１】第１の実施の形態のコンパイル装置を示す図である。
【図２】コンパイル装置のハードウェア例を示すブロック図である。
【図３】コンパイル装置の機能例を示すブロック図である。
【図４】プロセッサのレジスタ構成の例を示す図である。
【図５】プロセッサ情報の例を示す図である。
【図６】連続する分岐命令を含むコードの例を示す図である。
【図７】コードのパターンと変換規則の例を示す図である。
【図８】変換後のコードに基づく条件分岐の計算例を示す図である。
【図９】連続する分岐命令を含むコードの変換例を示す図である。
【図１０】変換前後の条件分岐の制御構造例を示す図である。
【図１１】コンパイルの手順例を示すフローチャートである。
【図１２】分岐命令削減の手順例を示すフローチャートである。
【図１３】分岐命令削減の手順例を示すフローチャート（続き１）である。
【図１４】分岐命令削減の手順例を示すフローチャート（続き２）である。
【図１５】比較値配列の例を示す図である。
【図１６】実行時情報の例を示す図である。
【図１７】連続する分岐命令を含むコードの他の変換例を示す図である。
【発明を実施するための形態】
【００１６】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
図１は、第１の実施の形態のコンパイル装置を示す図である。
【００１７】
第１の実施の形態のコンパイル装置１０は、最適化処理として、コード１３から分岐命令が削減されたコード１４に変換することがある。コード１３，１４は、プロセッサに実行させる命令を記述したものと言うことができ、プログラムと言うこともできる。コード１３は、高級言語で記述されたソースコードでもよいし、ソースコードから変換された中間コードでもよい。コード１４は、最適化された中間コードでもよいし、アセンブリコードや機械可読なオブジェクトコードでもよい。また、コンパイル装置１０は、ユーザが操作する端末装置でもよいし、端末装置からアクセスされるサーバ装置でもよい。コンパイル装置１０は、コンピュータまたは情報処理装置を用いて実装してもよい。
【００１８】
コンパイル装置１０は、記憶部１１および変換部１２を有する。記憶部１１は、コード１３を記憶する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の記憶装置でもよいし、ＨＤＤ（Hard Disk Drive）などの不揮発性の記憶装置でもよい。変換部１２は、記憶部１１に記憶されたコード１３をコード１４に変換することがある。変換部１２は、ＣＰＵ（Central Processing Unit）やＤＳＰ（Digital Signal Processor）などのプロセッサでもよいし、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。プロセッサは、例えば、記憶部１１または他の記憶装置に記憶されたコンパイルプログラムを実行する。なお、複数のプロセッサの集合（マルチプロセッサ）を「プロセッサ」と呼んでもよい。
【００１９】
変換部１２は、記憶部１１に記憶されたコード１３の中から、所定の条件を満たす複数の分岐命令を検出する。所定の条件には、複数の分岐命令が同一のジャンプ先を指定していることが含まれる。また、所定の条件には、各分岐命令が、整数を対象とした比較演算の結果に応じて分岐処理を行う条件分岐命令であることが含まれる。
【００２０】
整数を対象とした比較演算は、例えば、変数の値などの入力値が固定の整数と一致するか否か判定する演算である。その場合、比較演算の結果に応じた分岐処理は、例えば、入力値が固定の整数と一致するときまたは一致しないときにジャンプすることである。入力値は複数の分岐命令の間で共通であってもよく、比較される固定の整数は分岐命令毎に異なってもよい。また、変数は、文字変数であってもよい。すなわち、入力値および固定の整数は、文字を表す文字コードであってもよい。
【００２１】
図１の例では、コード１３には、変数ｃの値と固定の整数「１００」との比較に応じてｌａｂｅｌＡにジャンプするか判断する分岐命令１３ａと、変数ｃの値と固定の整数「２００」との比較に応じてｌａｂｅｌＡにジャンプするか判断する分岐命令１３ｂとが含まれる。よって、変換部１２は、コード１３から分岐命令１３ａ，１３ｂを検出する。
【００２２】
変換部１２は、検出した複数の分岐命令を、論理演算命令および算術演算命令を用いて、検出した複数の分岐命令よりも分岐命令の数が少ない変換命令群に変換する。変換命令群に使用する論理演算命令には、論理和（ＯＲ）命令、論理積（ＡＮＤ）命令、排他的論理和（ＸＯＲ）命令などが含まれ得る。変換命令群に使用する算術演算命令には、加算（ＡＤＤ）命令、減算（ＳＵＢ）命令などが含まれ得る。また、変換命令群に使用する論理演算命令や算術演算命令には、キャリーフラグやゼロフラグのようなステータスレジスタのフラグを用いた演算を行う、プロセッサアーキテクチャ依存の命令が含まれてもよい。
【００２３】
図１の例では、コード１３から、論理演算命令１４ａ，１４ｂ、算術演算命令１４ｃ，１４ｄおよび分岐命令１４ｅを含む変換命令群が生成される。この変換命令群では、論理演算命令１４ａを用いて、変数ｃの値が固定の整数「１００」と一致するか否かを反映した値を算出し、論理演算命令１４ｂを用いて、変数ｃの値が固定の整数「２００」と一致するか否かを反映した値を算出している。また、算術演算命令１４ｃ，１４ｄなどを用いて、論理演算命令１４ａ，１４ｂの演算結果から、変数ｃの値が「１００」「２００」の何れかと一致するか否かを反映した判定値を算出している。そして、分岐命令１４ｅにおいて、判定値に基づいてｌａｂｅｌＡにジャンプするか否か判断している。すなわち、ジャンプするか否かの２回分の判断が１回に纏められ、分岐命令の数が削減されている。
【００２４】
変換部１２は、変換命令群に基づく処理のサイクル数が、元の複数の分岐命令に基づく処理のサイクル数より少ないとき、変換命令群を用いたコード１４を生成する。例えば、変換部１２は、ターゲットのプロセッサにおける各命令の実行サイクル数を示すプロセッサ情報を参照して、変換後の変換命令群に従って分岐処理を行ったときのサイクル数を予測する。同様に、変換部１２は、プロセッサ情報を参照して、変換前の複数の分岐命令に従って分岐処理を行ったときのサイクル数を予測する。そして、例えば、変換部１２は、変換前のサイクル数と変換後のサイクル数とを比較し、後者が前者より小さい（変換によってサイクル数が減少すると予測される）場合に、変換命令群を採用する。
【００２５】
第１の実施の形態のコンパイル装置１０によれば、コード１３の中から、整数を対象とした比較演算の結果に応じて分岐処理を行う、ジャンプ先が同一の分岐命令１３ａ，１３ｂが検出される。検出された分岐命令１３ａ，１３ｂが、論理演算命令および算術演算命令を用いて変換前よりも分岐命令の数が削減された変換命令群に変換される。そして、変換命令群に基づく処理のサイクル数が、分岐命令１３ａ，１３ｂに基づく処理のサイクル数より少ないとき、変換命令群を用いたコード１４が生成される。
【００２６】
これにより、オブジェクトコードに含まれる分岐命令が削減される。よって、実行時のパイプラインの待ち時間を削減することができ、オブジェクトコードの実行効率を向上させることができる。特に、分岐予測の精度が高くないプロセッサでは、分岐命令の削減によって実行効率を大きく向上できる。また、ジャンプ先が同一である連続する分岐命令が変換対象になるため、命令投入待ちや分岐予測ミスの影響が大きくなりやすい箇所の実行効率を改善できる。また、変換前よりサイクル数が減少するか確認することで、変換により命令数が増加する場合やプロセッサによってサイクル数の異なる命令を使用する場合であっても、実行効率が高くなるようにオブジェクトコードを生成できる。
【００２７】
［第２の実施の形態］
第２の実施の形態のコンパイル装置１００は、高級言語で記述されたソースコードをコンパイルし、機械可読なオブジェクトコードを生成する。コンパイル装置１００は、ユーザが操作する端末装置でもよいし、端末装置からアクセスされるサーバ装置でもよい。コンパイル装置１００は、例えば、コンピュータを用いて実装される。その場合、コンパイル装置１００は、ソフトウェアとしてのコンパイラおよびリンカを実行する。
【００２８】
図２は、コンパイル装置のハードウェア例を示すブロック図である。
コンパイル装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、媒体リーダ１０６および通信インタフェース１０７を有する。上記ユニットはバス１０８に接続される。ＣＰＵ１０１は第１の実施の形態の変換部１２の一例であり、ＲＡＭ１０２は第１の実施の形態の記憶部１１の一例である。
【００２９】
ＣＰＵ１０１は、プログラムの命令を実行する演算回路を含むプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを備えてもよく、コンパイル装置１００は複数のプロセッサを備えてもよく、以下で説明する処理を複数のプロセッサまたはプロセッサコアを用いて並列に実行してもよい。また、複数のプロセッサの集合（マルチプロセッサ）を「プロセッサ」と呼んでもよい。
【００３０】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に用いるデータを一時的に記憶する揮発性の半導体メモリである。なお、コンパイル装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数個のメモリを備えてもよい。
【００３１】
ＨＤＤ１０３は、ＯＳ（Operating System）やミドルウェアやアプリケーションソフトウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性の記憶装置である。プログラムには、コンパイルプログラムやリンクプログラムが含まれる。なお、コンパイル装置１００は、フラッシュメモリやＳＳＤ（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）、半導体メモリなどを使用できる。媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータをＲＡＭ１０２またはＨＤＤ１０３に格納する。
【００３５】
通信インタフェース１０７は、ネットワーク１１４に接続され、ネットワーク１１４を介して他のコンピュータと通信を行うインタフェースである。通信インタフェース１０７は、スイッチなどの通信装置とケーブルで接続される有線通信インタフェースでもよいし、基地局と無線リンクで接続される無線通信インタフェースでもよい。
【００３６】
なお、コンパイル装置１００は、媒体リーダ１０６を備えていなくてもよく、ユーザが操作する端末装置から制御可能である場合には画像信号処理部１０４や入力信号処理部１０５を備えていなくてもよい。また、ディスプレイ１１１や入力デバイス１１２が、コンパイル装置１００の筐体と一体に形成されていてもよい。
【００３７】
図３は、コンパイル装置の機能例を示すブロック図である。
コンパイル装置１００は、ファイル記憶部１２０、コンパイラ１３０およびリンカ１５０を有する。ファイル記憶部１２０は、例えば、ＲＡＭ１０２またはＨＤＤ１０３に確保した記憶領域として実現される。コンパイラ１３０およびリンカ１５０は、例えば、ＣＰＵ１０１が実行するプログラムのモジュール（コンパイルプログラムおよびリンクプログラム）として実現できる。ただし、コンパイラ１３０およびリンカ１５０の機能の一部または全部を、ソフトウェアでなく電子回路として実現することも可能である。
【００３８】
ファイル記憶部１２０は、ソースファイル１２１、オブジェクトファイル１２２および実行ファイル１２３を記憶する。ソースファイル１２１は、高級言語で記述されたソースコードを含む。オブジェクトファイル１２２は、機械可読なオブジェクトコードを含む。実行ファイル１２３は、ターゲットのプロセッサが実行できる形式のファイルであり、生成されたオブジェクトコードとライブラリなどへのリンクとを含む。なお、実行ファイル１２３は、ＣＰＵ１０１が実行してもよいし、コンパイル装置１００が備える他のＣＰＵまたはコンパイル装置１００以外のコンピュータのＣＰＵが実行してもよい。
【００３９】
コンパイラ１３０は、ファイル記憶部１２０からソースファイル１２１を読み出し、ソースコードをオブジェクトコードに変換して、オブジェクトファイル１２２をファイル記憶部１２０に格納する。コンパイラ１３０は、入出力制御部１３１、ファイル入力部１３２、中間コード生成部１３３、中間コード記憶部１３４、アセンブリコード生成部１３５、ファイル出力部１３６、最適化部１４０および制御情報記憶部１４３を有する。
【００４０】
入出力制御部１３１は、ファイルの種類に応じた入出力方法を選択し、ファイル入力部１３２およびファイル出力部１３６を制御する。ファイル入力部１３２は、入出力制御部１３１からの指示に応じて、ソースファイル１２１をオープンし、ソースファイル１２１からソースコードを読み出す。中間コード生成部１３３は、ファイル入力部１３２が読み出したソースコードを解析して、コンパイラ１３０の内部で利用される中間言語で記述された中間コードに変換し、中間コードを中間コード記憶部１３４に格納する。ソースコードの解析には、字句解析、構文解析、意味解析などが含まれる。中間コード記憶部１３４は、ＲＡＭ１０２に確保された記憶領域であり、中間コードを記憶する。
【００４１】
アセンブリコード生成部１３５は、最適化部１４０によって最適化された中間コードを、低級言語であるアセンブリ言語で記述されたアセンブリコードに変換する。ファイル出力部１３６は、入出力制御部１３１からの指示に応じて、オブジェクトファイル１２２を生成し、アセンブリコード生成部１３５が生成したアセンブリコードをオブジェクトコードに変換し、オブジェクトファイル１２２に書き込む。
【００４２】
最適化部１４０は、中間コード記憶部１３４に記憶された中間コードを、実行速度が向上するように最適化する。最適化部１４０は、解析部１４１および最適化実行部１４２を有する。解析部１４１は、中間コードを解析して最適化方法を決定する。解析部１４１が行う最適化方法の決定には、分岐命令の削減を決定すること、すなわち、所定の条件を満たす分岐命令の集合を分岐命令の数が少ない命令群に変換することの決定が含まれる。最適化実行部１４２は、解析部１４１が決定した最適化方法に従って中間コードを最適化する。最適化実行部１４２が行う最適化には、分岐命令の削減が含まれる。
【００４３】
制御情報記憶部１４３は、ＲＡＭ１０２またはＨＤＤ１０３に確保された記憶領域であり、最適化部１４０が最適化処理において参照する制御情報を記憶する。制御情報には、プロセッサが解釈できる命令および各命令のサイクル数などを示すプロセッサ情報が含まれる。制御情報記憶部１４３には、複数の種類のプロセッサについてのプロセッサ情報が記憶されてもよい。ユーザがターゲットのプロセッサの種類を指定した場合、最適化部１４０は、指定された種類に対応するプロセッサ情報を参照すればよい。また、制御情報には、分岐命令を削減する最適化において使用される変換規則が含まれる。
【００４４】
リンカ１５０は、ファイル記憶部１２０からオブジェクトファイル１２２を読み出し、オブジェクトコードを解析して、参照されている他のオブジェクトファイルやライブラリを検出する。そして、リンカ１５０は、オブジェクトファイル１２２と、検出した他のオブジェクトファイルやライブラリとをリンクし、実行ファイル１２３を生成する。なお、コンパイラ１３０にリンカ１５０の機能が統合されていてもよい。
【００４５】
図４は、プロセッサのレジスタ構成の例を示す図である。
ＣＰＵ２０は、コンパイル装置１００によって生成された実行ファイル１２３を実行可能なプロセッサの１つである。ＣＰＵ２０は、使い捨てレジスタ２１（以下ではレジスタｒ０と呼ぶことがある）、汎用レジスタ２２〜２５（以下ではレジスタｒ１，ｒ２，ｒ３，ｒ４と呼ぶことがある）およびステータスレジスタ２６を有する。
【００４６】
使い捨てレジスタ２１は、後で参照されないデータの格納先として利用されるレジスタである。使い捨てレジスタ２１がデータの格納先に指定された命令を実行することは、当該データを破棄することを意味する。ただし、使い捨てレジスタ２１は物理的なレジスタでなくてもよく、物理的に存在しない仮想的なレジスタであってもよい。その場合、ＣＰＵ２０は、使い捨てレジスタ２１がデータの格納先に指定された命令を実行すると、当該データを何れのレジスタにも格納せずに即時に破棄することになる。
【００４７】
汎用レジスタ２２〜２５は、実行ファイル１２３に含まれる命令から明示的に指定することができる、データを一時的に格納しておくレジスタである。ステータスレジスタ２６は、演算の実行状況に応じてＣＰＵ２０が自動的に更新するレジスタであり、実行ファイル１２３に含まれる命令から明示的には指定されない。ステータスレジスタ２６は、キャリーフラグ（ｃａｒｒｙ）やゼロフラグ（ｚｅｒｏ）などの制御フラグを記憶する。
【００４８】
キャリーフラグは、直前の演算によってオーバーフロー（桁上がり）またはボロー（桁借り）が発生したか否かを示す。オーバーフローまたはボローが発生したときはキャリーフラグがＯＮ（１）に設定され、それ以外のときはＯＦＦ（０）に設定される。ゼロフラグは、直前の演算の結果がゼロであるか否かを示す。演算結果がゼロのときはゼロフラグがＯＮ（１）に設定され、それ以外のときはＯＦＦ（０）に設定される。
【００４９】
図５は、プロセッサ情報の例を示す図である。
プロセッサ情報１４４は、前述の制御情報記憶部１４３に記憶される。プロセッサ情報１４４は、命令形式、サイクル数および演算内容の項目を含む。命令形式は、アセンブリ言語レベルの命令名とオペランドを示す。サイクル数は、ＣＰＵ２０が命令の実行に要する実行時間を示す。演算内容は、命令の意味を示している。第２の実施の形態では、少なくとも図５のプロセッサ情報１４４に列挙された命令を実行可能なＣＰＵ２０をターゲットとして、実行ファイル１２３を生成することを想定している。
【００５０】
ＣＰＵ２０は、ｃｍｐ命令、ｂｅｑ命令、ｂｎｅ命令、ａｄｄｘ命令、ｓｕｂｘ命令、ｓｕｂｃｃ命令、ｘｏｒ命令、ａｎｄｃｃ命令およびｏｒｃｃ命令を実行できる。ｂｅｑ命令とｂｎｅ命令のサイクル数は１０であり、他の命令のサイクル数は１である。ｃｍｐ命令は、オペランドＡ，Ｂの値が一致していればゼロフラグがＯＮになる比較命令である。ｂｅｑ命令は、ゼロフラグがＯＮのときｌａｂｅｌにジャンプする分岐命令である。ｂｎｅ命令は、ゼロフラグがＯＦＦのときｌａｂｅｌにジャンプする分岐命令である。なお、上記の分岐命令（ｂｅｑ命令とｂｎｅ命令）のサイクル数は、ＣＰＵ２０が分岐予測を行わない場合または分岐予測に失敗する場合に要するサイクル数である。
【００５１】
ａｄｄｘ命令は、ＡにＢを加え、キャリーフラグがＯＮのときは更に１を加える算術演算命令である。なお、キャリーフラグのＯＮは数値「１」に相当し、キャリーフラグのＯＦＦは数値「０」に相当する。ｓｕｂｘ命令は、ＡからＢを引き、キャリーフラグがＯＮのときは更に１を引く算術演算命令である。ｓｕｂｃｃ命令は、ＡからＢを引く算術演算命令である。ｓｕｂｃｃ命令を実行したとき、Ａ＜Ｂであればボローが発生するためキャリーフラグがＯＮになる。また、演算結果がゼロであればゼロフラグがＯＮになる。
【００５２】
ｘｏｒ命令は、オペランドＡ，Ｂの論理和を求める論理演算命令である。ａｎｄｃｃ命令は、オペランドＡ，Ｂの論理積を求める論理演算命令である。ａｎｄｃｃ命令を実行したとき、演算結果の全てのビットが０であればゼロフラグがＯＮになる。ｏｒｃｃ命令は、オペランドＡ，Ｂの論理和を求める論理演算命令である。ｏｒｃｃ命令を実行したとき、演算結果の全てのビットが０であればゼロフラグがＯＮになる。なお、ａｄｄｘ命令、ｓｕｂｘ命令、ｓｕｂｃｃ命令、ａｎｄｃｃ命令およびｏｒｃｃ命令は、ステータスレジスタを参照または更新するプロセッサアーキテクチャ依存の命令である。
【００５３】
次に、分岐命令を削減する最適化処理について説明する。
図６は、連続する分岐命令を含むコードの例を示す図である。
コンパイル装置１００は、ソースコードの解析において、コード２０１をコード２０２に変換する。また、コンパイル装置１００は、分岐命令削減の最適化において、コード２０２からコード２０３を抽出し、コード２０３からコード２０４を生成する。図６では、コード２０１をソースコード形式で記載している。また、分岐命令削減の最適化は中間コードに対して行われるが、理解を容易にするためコード２０２，２０３もソースコード形式で記載している。コード２０４は、ＣＰＵ２０がサポートする命令レベルのアセンブリコード形式または疑似アセンブリコード形式で記載している。
【００５４】
コード２０１には、引数が文字で戻り値が真偽値である関数ｆｏｏが定義されている。関数ｆｏｏは、変数ｃの値がスペース群，「”」，「’」，「／」，「；」，「｛」，「｝」の何れかと一致するとき偽を返し、何れとも一致しないとき真を返す。なお、図６に示したコード２０１では、「’」は文字定数の開始または終了を示す特殊文字であるため、エスケープシーケンスとして「￥’」と記述している。
【００５５】
コード２０２には、コード２０１と同様の関数ｆｏｏが定義されている。ただし、コード２０２では、変数ｃの値と比較される比較値が、文字コードに相当する整数に置換されている。「１０」は改行の種類の１つであるラインフィード（ＬＦ）を示し、「３２」はスペース（ＳＰ）を示し、「９」はタブ（ＨＴ）を示し、「１３」は改行の種類の１つであるキャリッジリターン（ＣＲ）を示す。これら４つの整数は、コード２０１のスペース群に対応する。「３４」は「”」を示し、「３９」は「’」を示し、「４７」は「／」を示し、「５９」は「；」を示し、「１２３」は「｛」を示し、「１２５」は「｝」を示す。コンピュータ内部では、変数ｃの値も文字コードに相当する整数として扱われるため、コード２０２は、変数ｃの値と１０個の整数との比較を表している。
【００５６】
コード２０３は、コード２０２の中から所定の条件を満たすコード部分を抽出したものである。ここでは、所定の条件を満たすコード部分は、共通の変数の値と固定の整数それぞれとを比較する複数の比較演算を含み、何れか１つの比較結果が「不一致」である（または、何れか１つの比較結果が「一致」である）ときに、共通の処理を行うものである。コード２０３では、１０個の比較演算を通じて全体の真偽値が決まる。変数ｃの値が「１０」，「３２」，「９」，「１３」，「３４」，「３９」，「４７」，「５９」，「１２３」，「１２５」の順に比較される。変数ｃの値が何れか１つの固定の整数と一致すれば、全体の真偽値が偽であると確定するため、それ以降の比較演算を省略できる。
【００５７】
コード２０４は、コード２０３の処理を、ＣＰＵ２０がサポートするｃｍｐ命令（比較命令）とｂｅｑ命令（分岐命令）を用いて表現したものである。コード２０４は、１０個のｃｍｐ命令と１０個のｂｅｑ命令を含む。まず変数ｃの値と「１０」を比較するｃｍｐ命令が実行され、その比較結果が「一致」のとき（ｚｅｒｏ＝ＯＮのとき）ｌａｂｅｌＡにジャンプするｂｅｑ命令が実行される。ｌａｂｅｌＡが示すジャンプ先は、例えば、関数ｆｏｏの戻り値を偽に設定する命令とする。ｃ＝１０でなければ、次に変数ｃの値と「３２」を比較するｃｍｐ命令が実行され、その比較結果が「一致」のときｌａｂｅｌＡにジャンプするｂｅｑ命令が実行される。以下同様に、変数ｃの値と固定の整数とを比較するｃｍｐ命令と、ｌａｂｅｌＡにジャンプするｂｅｑ命令とが交互に実行される。
【００５８】
図７は、コードのパターンと変換規則の例を示す図である。
コンパイル装置１００は、図６の変換の後、パターン１４５に該当するコードを、変換規則１４６または変換規則１４７を用いて分岐命令の数の少ないコードに変換する。変換規則１４６，１４７は、前述の制御情報記憶部１４３に記憶されている。
【００５９】
パターン１４５は、アセンブリコード形式または疑似アセンブリコード形式の４個の命令を含む。１番目は、変数ｃの値と整数Ｔ１とを比較するｃｍｐ命令である。２番目は、１番目のｃｍｐ命令の比較結果に応じてジャンプするか否か判断するｂｅｑ命令である。３番目は、変数ｃの値と整数Ｔ２とを比較するｃｍｐ命令である。４番目は、３番目のｃｍｐ命令の比較結果に応じてジャンプするか否か判断するｂｅｑ命令である。すなわち、パターン１４５は、ジャンプ先が同一であり整数の比較演算の結果に応じてジャンプするか否か判断される、比較演算２回分の連続する分岐処理を示している。
【００６０】
変換規則１４６は、アセンブリコード形式または疑似アセンブリコード形式の８個の命令を含む。この８個の命令の中には、ステータスレジスタ２６の値を利用するプロセッサアーキテクチャ依存の論理演算命令および算術演算命令が含まれる。
【００６１】
１番目は、変数ｃの値と整数Ｔ１との間の排他的論理和を計算するｘｏｒ命令である。レジスタｒ１に格納されるｘｏｒ命令の結果は、ｃ＝Ｔ１のときのみゼロになる。２番目は、変数ｃの値と整数Ｔ２との排他的論理和を求めるｘｏｒ命令である。レジスタｒ２に格納されるｘｏｒ命令の結果は、ｃ＝Ｔ２のときのみゼロになる。
【００６２】
３番目は、０−ｒ１を計算するｓｕｂｃｃ命令である。キャリーフラグは、ｒ１＝０のとき（ｃ＝Ｔ１のとき）ＯＦＦになり、それ以外のときＯＮになる。４番目は、０−（−１）を計算するｓｕｂｘ命令である。レジスタｒ３に格納されるｓｕｂｘ命令の結果は、キャリーフラグがＯＦＦのとき（ｃ＝Ｔ１のとき）１になり、キャリーフラグがＯＮのとき（ｃ＝Ｔ１でないとき）ゼロになる。５番目は、０−ｒ２を計算するｓｕｂｃｃ命令である。キャリーフラグは、ｒ２＝０のとき（ｃ＝Ｔ２のとき）ＯＦＦになり、それ以外のときＯＮになる。６番目は、０−（−１）を計算するｓｕｂｘ命令である。レジスタｒ４に格納されるｓｕｂｘ命令の結果は、キャリーフラグがＯＦＦのとき（ｃ＝Ｔ２のとき）１になり、キャリーフラグがＯＮのとき（ｃ＝Ｔ２でないとき）ゼロになる。
【００６３】
７番目は、レジスタｒ３の値とレジスタｒ４の値との間の論理和を計算するｏｒｃｃ命令である。ゼロフラグは、ｒ３＝１またはｒ４＝１のとき（ｃ＝Ｔ１またはｃ＝Ｔ２のとき）ＯＦＦになり、ｒ３＝０かつｒ４＝０のとき（ｃ＝Ｔ１でなくｃ＝Ｔ２でないとき）ＯＮになる。８番目は、ゼロフラグがＯＦＦのとき（ｃ＝Ｔ１またはｃ＝Ｔ２のとき）、パターン１４５が示すｌａｂｅｌＡにジャンプするｂｎｅ命令である。
【００６４】
パターン１４５に含まれる分岐命令は２個であるのに対し、変換規則１４６に含まれる分岐命令は１個である。変換規則１４６に基づいてコードを変換することで、分岐命令の数が２分の１に減少する。一方、パターン１４５に含まれる命令の総数は４個であるのに対し、変換規則１４６に含まれる命令の総数は８個である。変換規則１４６に基づいてコードを変換することで、命令の総数が２倍に増加する。一般に、分岐命令はその後の命令の投入待ちや分岐予測ミスのペナルティを発生させることがあり、パイプラインの利用率を低下させるため、実行時間が他の命令より長くなる傾向になる。しかし、変換後のコードの実行時間が変換前より短くなるか否かは、プロセッサアーキテクチャに依存する。
【００６５】
変換規則１４７は、アセンブリコード形式または疑似アセンブリコード形式の８個の命令を含む。１，２，３，５番目の命令は、変換規則１４６と同じである。
４番目は、０＋０を計算するａｄｄｘ命令である。レジスタｒ３に格納されるａｄｄｘ命令の結果は、キャリーフラグがＯＦＦのとき（ｃ＝Ｔ１のとき）ゼロになり、キャリーフラグがＯＮのとき（ｃ＝Ｔ１でないとき）１になる。同様に、６番目は、０＋０を計算するａｄｄｘ命令である。レジスタｒ４に格納されるａｄｄｘ命令の結果は、キャリーフラグがＯＦＦのとき（ｃ＝Ｔ２のとき）ゼロになり、キャリーフラグがＯＮのとき（ｃ＝Ｔ２でないとき）１になる。
【００６６】
７番目は、レジスタｒ３の値とレジスタｒ４の値との間の論理積を計算するａｎｄｃｃ命令である。ゼロフラグは、ｒ３＝０またはｒ４＝０のとき（ｃ＝Ｔ１またはｃ＝Ｔ２のとき）ＯＮになり、ｒ３＝１かつｒ４＝１のとき（ｃ＝Ｔ１でなくｃ＝Ｔ２でないとき）ＯＦＦになる。８番目は、ゼロフラグがＯＮのとき（ｃ＝Ｔ１またはｃ＝Ｔ２のとき）、パターン１４５が示すｌａｂｅｌＡにジャンプするｂｅｑ命令である。
【００６７】
このような変換規則１４７を用いても、変換規則１４６と同様に分岐命令を削減することができる。また、キャリーフラグなどのステータスレジスタ２６の値を参照する算術演算命令を用いることで、ステータスレジスタ２６の値を参照しない一般的な算術演算命令を用いる場合よりも、汎用レジスタの使用量を削減できる。よって、汎用レジスタが枯渇することによるメモリアクセスの増大を抑制でき、論理演算命令や算術演算命令の増加の影響を抑制できる。なお、変換規則１４６，１４７は一例であり、コンパイル装置１００は、パターン１４５よりも分岐命令が少なくなる他の変換規則を用いてもよい。
【００６８】
図８は、変換後のコードに基づく条件分岐の計算例を示す図である。
ここでは、コード２０４の先頭にある４個の命令を、変換規則１４６を用いて変換することを考える。生成されるコード２１１は、変換規則１４６のパラメータであるＴ１に「１０」を代入し、パラメータであるＴ２に「３２」を代入したものである。
【００６９】
ｃ＝１０が入力された場合、ＣＰＵ２０は、コード２１１に従って計算２１２を実行する。１番目のｘｏｒ命令では、ｃ＝１０と「１０」が一致するためｒ１＝０になる。２番目のｘｏｒ命令では、ｃ＝１０と「３２」が一致しないためｒ２＝０ｘ２Ａになる。３番目のｓｕｂｃｃ命令では、ｒ１＝０であるためキャリーフラグがＯＦＦになる。４番目のｓｕｂｘ命令では、キャリーフラグがＯＦＦであるためｒ３＝１になる。５番目のｓｕｂｃｃ命令では、ｒ２＝０ｘ２ＡであるためキャリーフラグがＯＮになる。６番目のｓｕｂｘ命令では、キャリーフラグがＯＮであるためｒ４＝０になる。７番目のｏｒｃｃ命令では、ｒ３＝１，ｒ４＝０であるためゼロフラグがＯＦＦになる。８番目のｂｎｅ命令では、ゼロフラグがＯＦＦであるため、ｌａｂｅｌＡへのジャンプが発生する。これは、２個のｃｍｐ命令と２個のｂｎｅ命令を用いた変換前のコードと同じ動作になる。
【００７０】
一方、ｃ＝２が入力された場合、ＣＰＵ２０は、コード２１１に従って計算２１３を実行する。１番目のｘｏｒ命令では、ｃ＝２と「１０」が一致しないためｒ１＝０ｘ０８になる。２番目のｘｏｒ命令では、ｃ＝２と「３２」が一致しないためｒ２＝０ｘ２２になる。３番目のｓｕｂｃｃ命令では、ｒ１＝０ｘ０８であるためキャリーフラグがＯＮになる。４番目のｓｕｂｘ命令では、キャリーフラグがＯＮであるためｒ３＝０になる。５番目のｓｕｂｃｃ命令では、ｒ２＝０ｘ２２であるためキャリーフラグがＯＮになる。６番目のｓｕｂｘ命令では、キャリーフラグがＯＮであるためｒ４＝０になる。７番目のｏｒｃｃ命令では、ｒ３＝０，ｒ４＝０であるためゼロフラグがＯＮになる。８番目のｂｎｅ命令では、ゼロフラグがＯＮであるため、ｌａｂｅｌＡへのジャンプが発生しない。これは、２個のｃｍｐ命令と２個のｂｎｅ命令を用いた変換前のコードと同じ動作になる。
【００７１】
図９は、連続する分岐命令を含むコードの変換例を示す図である。
コンパイル装置１００は、コード２０４に含まれる２個の比較命令と２個の分岐命令を一組にして変換規則１４６を適用することで、コード２０４をコード２０５に変換することができる。コード２０４の連続する４個の命令に対応して、コード２０５の連続する８個の命令が生成される。すなわち、コード２０４は１０個の分岐命令を含む２０個の命令を有するのに対し、コード２０５は５個の分岐命令を含む４０個の命令を有する。
【００７２】
コード２０４とコード２０５の何れの方が実行時間が短いかは、プロセッサアーキテクチャに依存する。そこで、コンパイル装置１００は、プロセッサ情報１４４に記載された各命令のサイクル数に基づいて、コード２０４の実行に要するサイクル数とコード２０５の実行に要するサイクル数とを見積もり、サイクル数の小さい方のコードを採用する。
【００７３】
ここでは、ｃｍｐ命令は１サイクル、ｂｅｑ命令は１０サイクルである。よって、コード２０４のサイクル数は、（１×１個＋１０×１個）×１０回＝１１０サイクルである。一方、ｘｏｒ命令が１サイクル、ｓｕｂｃｃ命令が１サイクル、ｓｕｂｘ命令が１サイクル、ｏｒｃｃ命令が１サイクル、ｂｎｅ命令が１０サイクルである。よって、コード２０５のサイクル数は、（１×２個＋１×２個＋１×２個＋１×１個＋１０×１個）×５回＝８５サイクルである。コード２０４よりコード２０５の方がサイクル数が小さいため、コンパイル装置１００は、コード２０４からコード２０５への最適化を採用する。
【００７４】
図１０は、変換前後の条件分岐の制御構造例を示す図である。
コード２０４を実行した場合、最大で分岐処理２２０〜２２９が逐次的に実行される。分岐処理２２０では、ｃ＝１０のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２１に進む。分岐処理２２１では、ｃ＝３２のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２２に進む。分岐処理２２２では、ｃ＝９のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２３に進む。分岐処理２２３では、ｃ＝１３のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２４に進む。分岐処理２２４では、ｃ＝３４のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２５に進む。
【００７５】
分岐処理２２５では、ｃ＝３９のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２６に進む。分岐処理２２６では、ｃ＝４７のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２７に進む。分岐処理２２７では、ｃ＝５９のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２８に進む。分岐処理２２８では、ｃ＝１２３のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２２９に進む。分岐処理２２９では、ｃ＝１２５のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき戻り値を真に設定する処理に進む。
【００７６】
コード２０４を実行した場合、最大で分岐処理２３０〜２３４が逐次的に実行される。分岐処理２３０では、ｃ＝１０またはｃ＝３２のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２３１に進む。分岐処理２３１では、ｃ＝９またはｃ＝１３のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２３２に進む。分岐処理２３２では、ｃ＝３４またはｃ＝３９のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２３３に進む。分岐処理２３３では、ｃ＝４７またはｃ＝５９のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき分岐処理２３４に進む。分岐処理２３４では、ｃ＝１２３またはｃ＝１２５のとき戻り値を偽に設定する処理にジャンプし、それ以外のとき戻り値を真に設定する処理に進む。
【００７７】
このように、分岐命令削減の最適化を行うと、１個の比較値に対して１回の分岐命令を実行する代わりに、連続する２個の比較値に対して１回の分岐命令が実行される。第２の実施の形態では、２個の比較値に対して１回の分岐命令を実行しているが、３個以上の比較値に対して１回の分岐命令を実行するようにすることも可能である。
【００７８】
ただし、ｎ個（ｎは２以上の整数）の比較値に対して１回の分岐命令を実行する場合、変数ｃの値が１番目の比較値と一致していても、残りのｎ−１個の比較値についての演算が省略されず実行されることになる。よって、ｎの値は、変換前のコード２０４では省略されていた比較演算の一部が省略されないことによる実行時間の増加も考慮して、適切な値に設定されることが好ましい。通常、ｎ＝２とすることで分岐処理の実行時間を良好に削減できる。コンパイル装置１００は、変数ｃの値が列挙された比較値の何れかと一致する確率を考慮して、ｎの値を動的に決定してもよい。
【００７９】
次に、コンパイル装置１００によるコンパイルの手順について説明する。
図１１は、コンパイルの手順例を示すフローチャートである。
（Ｓ１）中間コード生成部１３３は、ソースファイル１２１から読み込まれたソースコードを解析し、ソースコードを中間コードに変換して中間コード記憶部１３４に格納する。ソースコードの解析には、字句解析、構文解析、意味解析などが含まれる。
【００８０】
（Ｓ２）最適化部１４０は、中間コード記憶部１３４に記憶された中間コードに対して汎用的な最適化を実行し、中間コードを書き換える。汎用的な最適化には、使用されていない変数の削除、静的に決定できる値のみに依存する計算式の定数化、複数の計算式に共通に含まれる部分式の計算結果の再利用などが含まれる。
【００８１】
（Ｓ３）最適化部１４０は、中間コードの中から依存関係がなく並列に実行可能な命令を検出し、検出した命令が並列に実行されるように中間コードを書き換える。並列化には、ループ内の命令を展開（アンローリング）し、元のループのｉ回目の処理（ｉは１以上の整数）とｉ＋１回目の処理とを並列化することが含まれる。
【００８２】
（Ｓ４）最適化部１４０は、ターゲットのプロセッサがＳＩＭＤ（Single Instruction Multiple Data）命令をサポートしているとき、中間コードの中から依存関係がなく演算の種類が同じ２以上のスカラ命令を検出し、検出した命令をＳＩＭＤ命令に変換する。ＳＩＭＤ命令は、２以上のデータの組に対して同じ演算を並列に実行する命令である。
【００８３】
（Ｓ５）最適化部１４０は、中間コードで使用されている命令形式を、ターゲットのプロセッサがサポートする命令セットの命令形式に書き換える。すなわち、最適化部１４０は、プロセッサ非依存の中間コードをプロセッサ依存の中間コードに書き換える。なお、ターゲットのプロセッサは、コンパイル時にユーザから指定されてもよい。そのとき、最適化部１４０は、指定されたプロセッサに対応するプロセッサ情報を参照してもよい。
【００８４】
（Ｓ６）最適化部１４０は、プロセッサアーキテクチャ依存の命令を活用することで実行時間を短縮できるとき、プロセッサアーキテクチャ依存の最適化を行う。プロセッサアーキテクチャ依存の最適化には、図５の命令群を用いた分岐命令削減などが含まれる。
【００８５】
（Ｓ７）最適化部１４０は、並列性やパイプラインの利用率が向上するように、中間コードに含まれる命令の実行順序を入れ替え、中間コードを書き換える。
（Ｓ８）アセンブリコード生成部１３５は、中間コード記憶部１３４に格納された中間コードから、機械語の命令に対応するアセンブリコードを生成する。
【００８６】
（Ｓ９）ファイル出力部１３６は、ファイル記憶部１２０にオブジェクトファイル１２２を生成する。ファイル出力部１３６は、ステップＳ８で生成されたアセンブリコードを機械可読なオブジェクトコードに変換し、オブジェクトファイル１２２に書き込む。オブジェクトファイル１２２は、リンカ１５０によって他のオブジェクトファイルやライブラリとリンクされ、実行ファイル１２３に変換されることになる。
【００８７】
図１２は、分岐命令削減の手順例を示すフローチャートである。
このフローチャートが示す処理は、上記のステップＳ６の中で実行される。
（Ｓ１０）解析部１４１は、命令ｉとして中間コードの最初の命令を選択する。
【００８８】
（Ｓ１１）解析部１４１は、命令ｉがＮＵＬＬである（存在しない）か判断する。ＮＵＬＬの場合は最適化が終了し、ＮＵＬＬでない場合はステップＳ１２に処理が進む。
（Ｓ１２）解析部１４１は、命令ｊとして命令ｉの次の命令を選択する。
【００８９】
（Ｓ１３）解析部１４１は、命令ｉの種類を確認し、命令ｉがｃｍｐ命令（比較命令）であるか判断する。命令ｉがｃｍｐ命令の場合はステップＳ１４に処理が進み、ｃｍｐ命令でない場合はステップＳ１６に処理が進む。
【００９０】
（Ｓ１４）解析部１４１は、命令ｊ（ｃｍｐ命令の次の命令）の種類を確認し、命令ｊがｂｅｑ命令（分岐命令）であるか判断する。命令ｊがｂｅｑ命令の場合はステップＳ１５に処理が進み、ｂｅｑ命令でない場合はステップＳ１６に処理が進む。
【００９１】
（Ｓ１５）解析部１４１は、命令ｉ（ｃｍｐ命令）の第２オペランドとして指定された比較値が、定数かつ整数であるか判断する。比較値が定数かつ整数の場合はステップＳ１７に処理が進み、それ以外の場合はステップＳ１６に処理が進む。
【００９２】
（Ｓ１６）解析部１４１は、新たな命令ｉとして、中間コードの中から現在の命令ｉの次の命令を選択する。そして、ステップＳ１１に処理が進む。
（Ｓ１７）解析部１４１は、比較値配列Ｖｅｃの末尾に命令ｉの比較値を追加する。比較値配列Ｖｅｃは、ＲＡＭ１０２に記憶される可変長配列（ベクタ）である。
【００９３】
（Ｓ１８）解析部１４１は、命令ｉ（ｃｍｐ命令）の第１オペランドとして指定された変数をｖａｒと置き、命令ｊ（ｂｅｑ命令）のジャンプ先をｌａｂｅｌと置き、命令ｊの次の命令を命令ｎと置く。そして、ステップＳ１９に処理が進む。
【００９４】
図１３は、分岐命令削減の手順例を示すフローチャート（続き１）である。
（Ｓ１９）解析部１４１は、命令ｎがＮＵＬＬであるか判断する。ＮＵＬＬの場合はステップＳ２８に処理が進み、ＮＵＬＬでない場合はステップＳ２０に処理が進む。
【００９５】
（Ｓ２０）解析部１４１は、命令ｍとして命令ｎの次の命令を選択する。
（Ｓ２１）解析部１４１は、命令ｎの種類を確認し、命令ｎがｃｍｐ命令（比較命令）であるか判断する。命令ｎがｃｍｐ命令の場合はステップＳ２２に処理が進み、ｃｍｐ命令でない場合はステップＳ２８に処理が進む。
【００９６】
（Ｓ２２）解析部１４１は、命令ｎ（ｃｍｐ命令）の第１オペランドとして指定された変数がｖａｒ（命令ｉの変数）と同一か判断する。変数が同一の場合はステップＳ２３に処理が進み、同一でない場合はステップＳ２８に処理が進む。
【００９７】
（Ｓ２３）解析部１４１は、命令ｍ（ｃｍｐ命令の次の命令）の種類を確認し、命令ｍがｂｅｑ命令（分岐命令）であるか判断する。命令ｍがｂｅｑ命令の場合はステップＳ２４に処理が進み、ｂｅｑ命令でない場合はステップＳ２８に処理が進む。
【００９８】
（Ｓ２４）解析部１４１は、命令ｎ（ｃｍｐ命令）の第２オペランドとして指定された比較値が、定数かつ整数であるか判断する。比較値が定数かつ整数の場合はステップＳ２５に処理が進み、それ以外の場合はステップＳ２８に処理が進む。
【００９９】
（Ｓ２５）解析部１４１は、命令ｍ（ｂｅｑ命令）のオペランドとして指定されたジャンプ先がｌａｂｅｌ（命令ｊのジャンプ先）と同一か判断する。ジャンプ先が同一の場合はステップＳ２６に処理が進み、同一でない場合はステップＳ２８に処理が進む。
【０１００】
（Ｓ２６）解析部１４１は、比較値配列Ｖｅｃの末尾に命令ｎの比較値を追加する。
（Ｓ２７）解析部１４１は、新たな命令ｎとして、中間コードの中から現在の命令ｍの次の命令を選択する。そして、ステップＳ１９に処理が進む。
【０１０１】
（Ｓ２８）解析部１４１は、新たな命令ｉとして、中間コードの中から現在の命令ｍの次の命令を選択する。そして、ステップＳ２９に処理が進む。
図１４は、分岐命令削減の手順例を示すフローチャート（続き２）である。
【０１０２】
（Ｓ２９）解析部１４１は、比較値配列Ｖｅｃの要素数をｓｉｚｅと置く。
（Ｓ３０）解析部１４１は、ｓｉｚｅが奇数であるか判断する。ｓｉｚｅが奇数の場合はステップＳ３１に処理が進み、偶数の場合はステップＳ３２に処理が進む。
【０１０３】
（Ｓ３１）解析部１４１は、比較値配列Ｖｅｃから末尾の要素を削除することで、ｓｉｚｅを偶数にする。削除された比較値をもつｃｍｐ命令は最適化の対象から外される。
（Ｓ３２）解析部１４１は、制御情報記憶部１４３に記憶されたプロセッサ情報１４４を参照する。複数のプロセッサアーキテクチャに対応するプロセッサ情報が制御情報記憶部１４３に記憶されている場合、解析部１４１は、ユーザが指定したプロセッサについてのプロセッサ情報を参照する。そして、解析部１４１は、ｃｍｐ命令のサイクル数をｔａ、ｂｅｑ命令およびｂｎｅ命令のサイクル数をｔｂ、ｘｏｒ命令のサイクル数をｔｃ、ｓｕｂｃｃ命令のサイクル数をｔｄ、ｓｕｂｘ命令およびａｄｄｘ命令のサイクル数をｔｅ、ｏｒｃｃ命令およびａｎｄｃｃ命令のサイクル数をｔｆと置く。
【０１０４】
（Ｓ３３）解析部１４１は、比較値配列Ｖｅｃに格納された比較値の範囲の分岐処理について、最適化前のサイクル数ｂｅｆｏｒｅと最適化後のサイクル数ａｆｔｅｒを算出する。ｂｅｆｏｒｅは（ｔａ＋ｔｂ）×ｓｉｚｅと算出でき、ａｆｔｅｒは（ｔｂ＋２ｔｃ＋２ｔｄ＋２ｔｅ＋ｔｆ）×ｓｉｚｅ÷２と算出できる。
【０１０５】
（Ｓ３４）解析部１４１は、最適化後のサイクル数ａｆｔｅｒが最適化前のサイクル数ｂｅｆｏｒｅより小さいか、すなわち、最適化によって実行時間の短縮が期待できるか判断する。ａｆｔｅｒがｂｅｆｏｒｅより小さい場合はステップＳ３５に処理が進み、ａｆｔｅｒがｂｅｆｏｒｅ以上である場合はステップＳ３６に処理が進む。
【０１０６】
（Ｓ３５）解析部１４１は、分岐命令削減の最適化を行うことを決定する。最適化実行部１４２は、比較値配列Ｖｅｃの要素（比較値配列Ｖｅｃに格納された比較値）を先頭から順に２個ずつペアにして取り出し、制御情報記憶部１４３に記憶された変換規則１４６を適用して、最適化した中間コードを生成する。
【０１０７】
（Ｓ３６）解析部１４１は、比較値配列Ｖｅｃに格納された比較値を全て削除する（比較値配列Ｖｅｃの要素をクリアする）。そして、ステップＳ１１に処理が進む。
このように、解析部１４１は、中間コードの中から所定の条件を満たす分岐処理に関する命令群を検出する。検出する命令群は、次の条件を満たす連続した命令の集合である。（１）ｃｍｐ命令（比較命令）とｂｅｑ命令（分岐命令）とが交互に連続していること。（２）ｃｍｐ命令の第１オペランドで指定される変数が全て同一であること。（３）ｃｍｐ命令の第２のオペランドで指定される比較値が定数かつ整数であること。（４）ｂｅｑ命令のオペランドで指定されるジャンプ先が全て同一であること。最適化実行部１４２は、検出された命令群毎に、ｓｕｂｃｃ命令・ｓｕｂｘ命令・ｏｒｃｃ命令などのプロセッサアーキテクチャ依存の論理演算命令と算術演算命令を用いて、分岐命令を削減する。
【０１０８】
図１５は、比較値配列の例を示す図である。
比較値配列１４８は、分岐命令削減の最適化において解析部１４１が生成する。比較値配列１４８は、インデックスおよび比較値の項目を含む。インデックスは、比較値配列１４８の要素を識別する識別番号である。比較値は、ｃｍｐ命令の第２オペランドとして指定される整数である。解析部１４１がコード２０４を解析する場合、比較値配列１４８には、「１０」，「３２」，「９」，「１３」，「３４」，「３９」，「４７」，「５９」，「１２３」，「１２５」の順に比較値が格納される。
【０１０９】
ところで、図１０に示したように、変換前のコード２０４においても変換後のコード２０５においても、複数の比較値についての分岐処理がコンパイル時に決められる順序で連続的に実行される。この場合、変数ｃの値が早い段階で比較される比較値と一致していれば、それ以降の比較値についての分岐処理を省略することができる。例えば、図１０のフローの場合、ｃ＝３２であれば、以降の「９」，「１３」，「３４」，「３９」，「４７」，「５９」，「１２３」，「１２５」についての分岐処理を省略できる。
【０１１０】
そこで、出現確率の高い比較値についての分岐処理が先に実行されることが好ましい。これを実現する１つの方法として、最適化前のオブジェクトコードをＣＰＵ２０に仮に実行させて、各命令の実行回数などを示す実行時情報を収集し、コンパイル装置１００が実行時情報を参照して複数の比較値の順序を入れ替えることが考えられる。
【０１１１】
図１６は、実行時情報の例を示す図である。
実行時情報１４９は、コード２０４に相当するオブジェクトコードをＣＰＵ２０が実行したときに収集される情報である。実行時情報１４９は、比較値、ジャンプ回数および割合の項目を含む。比較値は、コード２０４のｃｍｐ命令（比較命令）の第２オペランドで指定される固定の整数である。ジャンプ回数は、その比較値をもつｃｍｐ命令の直後のｂｅｑ命令（分岐命令）でジャンプが発生した回数である。割合は、実行時情報１４９に列挙されたジャンプ回数の合計に対する、ある比較値のジャンプ回数が占める割合である。
【０１１２】
図１６の例では、ｃ＝１０の割合が１．５％、ｃ＝３２の割合が２．５％、ｃ＝９の割合が２１．０％、ｃ＝１３の割合が５．０％、ｃ＝３４の割合が３．０％、ｃ＝３９の割合が１９．０％、ｃ＝４７の割合が２２．０％、ｃ＝５９の割合が５．５％、ｃ＝１２３の割合が１９．５％、ｃ＝１２５の割合が１．０％である。コンパイル装置１００の最適化部１４０は、最適化処理の中で、分岐命令の実行回数の合計が少なくなるように、実行時情報１４９を参照して比較値の順序を入れ替えてもよい。
【０１１３】
図１７は、連続する分岐命令を含むコードの他の変換例を示す図である。
実行時情報１４９によれば、出現確率の高い順に比較値を並べると、「４７」，「９」，「１２３」，「３９」，「５９」，「１３」，「３４」，「３２」，「１０」，「１２５」となる。そこで、最適化部１４０は、例えば、コード２０２をコード２０６に変換する。コード２０６では、１０個の比較値が出現確率の高い順に並んでいる。これにより、実質的な分岐命令の実行回数を削減でき、実行時間を短縮できる。
【０１１４】
比較値の順序の入れ替えは、プロセッサアーキテクチャ依存の論理演算命令や算術演算命令を用いた分岐命令の削減と組み合わせて行うことができる。なお、この２つの最適化方法の一方のみを実行する場合、後者の最適化は前者の最適化と比べて次のような利点を有する。（１）複数の比較値の間で出現確率の偏りが小さい場合や、入力値が何れの比較値とも一致しない確率が高い場合でも、十分な実行時間短縮の効果が得られる。（２）実行時情報１４９を収集しなくても、分岐処理の最適化を行える。これは特に、計算量の多いプログラムを扱うときに利点が大きい。（３）２回以上コンパイルを行わなくてよい。これは、コンパイル時間が長い複雑なプログラムを扱うときに利点が大きい。
【０１１５】
第２の実施の形態のコンパイル装置１００によれば、オブジェクトコードに含まれる分岐命令が減少する。よって、パイプラインへの後続の命令の投入待ちや分岐予測ミスのペナルティの発生を抑制でき、オブジェクトコードの実行効率を向上させることができる。特に、分岐予測の精度が高くないプロセッサでは、実行効率を大きく向上できる。また、変換前のサイクル数と変換後のサイクル数とを試算して実行時間の減少が期待できるか確認することで、命令数の増加する最適化が可能となる。また、ステータスレジスタ２６の値を利用するプロセッサアーキテクチャ依存の算術演算命令を用いることで、汎用レジスタの使用量を削減でき、論理演算命令や算術演算命令の増加の影響を抑制できる。
【０１１６】
なお、前述のように、第１の実施の形態の情報処理は、コンパイル装置１０にプログラムを実行させることで実現することができる。第２の実施の形態の情報処理は、コンパイル装置１００にプログラムを実行させることで実現することができる。
【０１１７】
プログラムは、コンピュータ読み取り可能な記録媒体（例えば、記録媒体１１３）に記録しておくことができる。記録媒体としては、例えば、磁気ディスク、光ディスク、光磁気ディスク、半導体メモリなどを使用できる。磁気ディスクには、ＦＤおよびＨＤＤが含まれる。光ディスクには、ＣＤ、ＣＤ−Ｒ（Recordable）／ＲＷ（Rewritable）、ＤＶＤおよびＤＶＤ−Ｒ／ＲＷが含まれる。プログラムは、可搬型の記録媒体に記録されて配布されることがある。その場合、可搬型の記録媒体からＨＤＤなどの他の記録媒体（例えば、ＨＤＤ１０３）にプログラムをコピーして（インストールして）実行してもよい。
【符号の説明】
【０１１８】
１０  コンパイル装置
１１  記憶部
１２  変換部
１３，１４  コード
１３ａ，１３ｂ，１４ｅ  分岐命令
１４ａ，１４ｂ  論理演算命令
１４ｃ，１４ｄ  算術演算命令
【図１】
2015201119.tif 000003
【図２】
2015201119.tif 000004
【図３】
2015201119.tif 000005
【図４】
2015201119.tif 000006
【図５】
2015201119.tif 000007
【図６】
2015201119.tif 000008
【図７】
2015201119.tif 000009
【図８】
2015201119.tif 000010
【図９】
2015201119.tif 000011
【図１０】
2015201119.tif 000012
【図１１】
2015201119.tif 000013
【図１２】
2015201119.tif 000014
【図１３】
2015201119.tif 000015
【図１４】
2015201119.tif 000016
【図１５】
2015201119.tif 000017
【図１６】
2015201119.tif 000018
【図１７】
2015201119.tif 000019